wasm-micro-runtime icon indicating copy to clipboard operation
wasm-micro-runtime copied to clipboard

wasi posix semaphore issue

Open tkernelcn opened this issue 1 year ago • 5 comments
trafficstars

does it support wasi semaphore api, or how to fix, Thanks.

##running

./iwasm --map-dir="/::./" --max-threads=20 --heap-size=65535 ./test-apps.wasm
[21:31:09:159 - 7F13E76E5B80]: failed to check signature '($iii)i' and resolve pointer params for import function (env sem_open)
[21:31:09:143 - 7F13E76E5B80]: warning: failed to link import function (env, sem_open)
[21:31:09:224 - 7F13E76E5B80]: warning: failed to link import function (env, sem_open)
[21:31:09:398 - 7F13E76E5B80]: warning: failed to link import function (env, sem_open)
[21:31:09:652 - 7F13E76E5B80]: warning: failed to link import function (env, sem_open)
Exception: failed to call unlinked import function (env, sem_open)

source

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#include <pthread.h>

#define MAX_NUM_THREADS 3

sem_t *sem;

static void* routine(void* arg){
    sem_wait(sem);
    printf("Hello from thread %ld\n", (long)arg);
    sem_post(sem);
    return NULL;
}

int main(int argc, char *argv[])
{
    pthread_t threads[MAX_NUM_THREADS];
    long i;
    
    sem = sem_open("/semaphore_example", O_CREAT, 0644, 1);
    if(sem == SEM_FAILED){
        perror("sem_open");
        return TEST_FAILED;
    }

    for(i = 0; i < MAX_NUM_THREADS; i++){
        pthread_create(&threads[i], NULL, routine, (void*)i);
    }

    for(i = 0; i < MAX_NUM_THREADS; i++){
        pthread_join(threads[i], NULL);
    }

    sem_close(sem);
    sem_unlink("/semaphore_example");

    return 0;
}

tkernelcn avatar Jan 19 '24 01:01 tkernelcn

Hi, it seems that wasi-sdk doesn't support posix semaphore APIs so the compiled wasm app imports sem_xxx APIs, there may be two ways: one is to use WAMR lib-pthread instead, please refer to: https://github.com/bytecodealliance/wasm-micro-runtime/tree/main/samples/multi-thread (note that sem_open/sem_wait/sem_close are used in wasm-apps/main.c) https://github.com/bytecodealliance/wasm-micro-runtime/blob/main/doc/pthread_library.md

the other is to keep using WAMR wasi-threads, but to implement the native apis for sem_xxx, maybe you can refer to: https://github.com/bytecodealliance/wasm-micro-runtime/blob/main/core/iwasm/libraries/lib-pthread/lib_pthread_wrapper.c#L1134-L1176

wenyongh avatar Jan 19 '24 02:01 wenyongh

Hello @wenyongh, Thanks for your comments due to I will use wasi other apis like socket and file/directory, so the last approach is reasonable or implement on wasm app side like:

#include <pthread.h>
#include <stdlib.h>

typedef struct {
    pthread_mutex_t mutex;
    pthread_cond_t cond;
    int count;
} sem_t;

int sem_init(sem_t *sem, int pshared, unsigned int value){
    if(pshared > 1) {
        /* this implementation does not support
		   process-shared semaphores */
        return -1;
    }
    sem->count = value;
    pthread_mutex_init(&sem->mutex, NULL);
    pthread_cond_init(&sem->cond, NULL);
    return 0;
}

int sem_destroy(sem_t *sem){
    pthread_mutex_destroy(&sem->mutex);
    pthread_cond_destroy(&sem->cond);
    return 0;
}

int sem_wait(sem_t *sem){
    pthread_mutex_lock(&sem->mutex);
    while(sem->count == 0){
        pthread_cond_wait(&sem->cond, &sem->mutex);
    }
    sem->count--;
    pthread_mutex_unlock(&sem->mutex);
    return 0;
}

int sem_post(sem_t *sem){
    pthread_mutex_lock(&sem->mutex);
    sem->count++;
    pthread_cond_signal(&sem->cond);
    pthread_mutex_unlock(&sem->mutex);
    return 0;
}

then waiting new wasi-sdk that supporting semaphore. do you know the roadmap of wasi-sdk about IPC api, even including mqueue, rwlock ...

tkernelcn avatar Jan 19 '24 03:01 tkernelcn

Hi, I am afraid I have no idea about the roadmap of wasi-sdk, maybe you can open issue in wasi-sdk's community.

wenyongh avatar Jan 19 '24 05:01 wenyongh

is there any approach to use buildin sem_open that you list: https://github.com/bytecodealliance/wasm-micro-runtime/blob/main/core/iwasm/libraries/lib-pthread/lib_pthread_wrapper.c#L1134-L1176

and other api can also use wasi lib's like pthread/file/socket?

need a prefix like _priv_ or not? then I use sem_open after #define _priv_sem_open sem_open in wasm app

#define REG_NATIVE_FUNC(func_name, signature) \
    { _priv_#func_name, func_name##_wrapper, signature, NULL }
/* clang-format on */

static NativeSymbol native_symbols_lib_pthread_sem[] = {
#if WASM_ENABLE_LIB_PTHREAD_SEMAPHORE != 0
    REG_NATIVE_FUNC(sem_open, "($iii)i"),
    REG_NATIVE_FUNC(sem_close, "(i)i"),
    REG_NATIVE_FUNC(sem_wait, "(i)i"),
    REG_NATIVE_FUNC(sem_trywait, "(i)i"),
    REG_NATIVE_FUNC(sem_post, "(i)i"),
    REG_NATIVE_FUNC(sem_getvalue, "(i*)i"),
    REG_NATIVE_FUNC(sem_unlink, "($)i"),
#endif
};

tkernelcn avatar Jan 19 '24 07:01 tkernelcn

If to use the builtin sem_xxx apis, you should enable the lib-pthread library, but it seems that you also enable the lib-wasi-threads? I think you had better just pick one, if to use the latter, you may implement the native api for sem_xxx apis by yourself: https://github.com/bytecodealliance/wasm-micro-runtime/blob/main/doc/export_native_api.md

wenyongh avatar Jan 19 '24 10:01 wenyongh