- 
          
 - 
                Notifications
    
You must be signed in to change notification settings  - Fork 247
 
Open
Description
It looks like Blink's system call emulation for futex(2) doesn't support the FUTEX_REQUEUE flag. This flag is sometimes used by musl libc (specifically here: https://git.musl-libc.org/cgit/musl/tree/src/thread/pthread_cond_timedwait.c#n48). This can cause multithreaded programs built with musl to misbehave when run inside of Blink.
Here's a simple example that makes direct use of FUTEX_REQUEUE as a test:
#include <stdio.h>
#include <stdlib.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <pthread.h>
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
#define FUTEX_REQUEUE 3
int futex1 = 0;  // Initial futex
int futex2 = 0;  // Destination futex for requeued threads
static int futex_wait(int *addr, int val) {
    return syscall(SYS_futex, addr, FUTEX_WAIT, val, NULL, NULL, 0);
}
static int futex_wake(int *addr, int num) {
    return syscall(SYS_futex, addr, FUTEX_WAKE, num, NULL, NULL, 0);
}
static int futex_requeue(int *futex1, int *futex2, int wake_count, int requeue_count) {
    return syscall(SYS_futex, futex1, FUTEX_REQUEUE, wake_count, requeue_count, futex2, 0);
}
void *worker_thread(void *arg) {
    int id = *(int *)arg;
    printf("Thread %d waiting on futex1\n", id);
    futex_wait(&futex1, 0);
    return NULL;
}
int main() {
    pthread_t thread1, thread2;
    int id1 = 1, id2 = 2;
    // Start two worker threads
    pthread_create(&thread1, NULL, worker_thread, &id1);
    pthread_create(&thread2, NULL, worker_thread, &id2);
    sleep(1); // Ensure both threads are waiting
    // Wake one thread and requeue the other to futex2
    printf("Main thread: Waking 1 thread and requeuing 1 thread\n");
    futex_requeue(&futex1, &futex2, 1, 1);
    sleep(1); // Give time for one thread to wake up
    // Wake the remaining thread from futex2
    printf("Main thread: Waking the remaining thread from futex2\n");
    futex_wake(&futex2, 1);
    // Join threads
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);
    printf("All threads completed.\n");
    return 0;
}$ musl-clang -O2 -static main.c
Thanks!
senyai
Metadata
Metadata
Assignees
Labels
No labels