Skip to content

Recursive mutex returns ENORECOVERABLE (56) with wasi-threads #2466

Closed
WebAssembly/wasi-libc
#433
@denizsokmen

Description

@denizsokmen

I've encountered an issue where two threads locking the same recursive mutex secretly fails. Also I've noticed that the lock failure only happens from the spawned thread.

Here's a minimal reproduction case where the program will abort if lock returns non-zero:

#!/bin/bash

set -e

if [ ! -d "wasm-micro-runtime" ]; then
    git clone --depth=1 https://github.com/bytecodealliance/wasm-micro-runtime.git
    pushd wasm-micro-runtime/product-mini/platforms/linux
    cmake -DWAMR_BUILD_LIB_WASI_THREADS=1 .
    make -j 8
    popd
fi

if [ ! -d "wasi-sdk-20.0" ]; then
    wget https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20/wasi-sdk-20.0-linux.tar.gz
    tar xzf wasi-sdk-20.0-linux.tar.gz
fi

wasi-sdk-20.0/bin/clang++ --target=wasm32-wasi-threads --sysroot=wasi-sdk-20.0/share/wasi-sysroot/ -Wl,--import-memory -Wl,--export-memory -Wl,--shared-memory -Wl,--initial-memory=655360 test.cpp -o test.wasm -pthread

for i in $(seq 1 1000); do
    echo "Running $i / 1000"
    ./wasm-micro-runtime/product-mini/platforms/linux/iwasm test.wasm
done

Where test.cpp is:

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

static    pthread_mutex_t mutex;
static int cntr = 0;

int main(int argc, char **argv) {
    cntr = 0;
    pthread_mutexattr_t attr;
    pthread_mutexattr_init( &attr );
    pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE );
    pthread_mutex_init(&mutex, &attr);
    pthread_mutexattr_destroy( &attr);

    pthread_t threadID;
    pthread_create(&threadID, NULL, [](void* arg) -> void* {
        for(int i = 0; i < 10000; i++) {
            int ret = 0;
           // do {
                ret = pthread_mutex_lock(&mutex);
           // } while(ret != 0);

            cntr++;
            if (ret != 0) {
                printf("BOOM %d\n", ret);
                abort();
            }
            pthread_mutex_unlock(&mutex);
        }
        return NULL;
    }, NULL);

    for(int i = 0; i < 10000; i++) {
        int ret = 0;
        // do {
            ret = pthread_mutex_lock(&mutex);

        //} while(ret != 0);

        cntr++;
        if (ret != 0) {
            abort();
        }

        pthread_mutex_unlock(&mutex);
    }

    pthread_join(threadID, NULL);
    printf("counted: %d\n", cntr);
    return 0;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions