It is wrong to call a function with an incompatible prototype, discarding the address of the function to another prototype and calling it through the resulting pointer:
void *my_callback(void *arg) { ... } void (*broken)(void *) = (void (*)(void *)) my_callback; broken(some_arg);
What you can do is pass makecontext your own callback, which will call thread_func and ignore its return value. A small function that only serves to call another function is sometimes called trampoline .
static void trampoline(int cb, int arg) { void *(*real_cb)(void *) = (void *(*)(void *)) cb; void *real_arg = arg; real_cb(real_arg); } int my_pthread_create(void *(*cb)(void *), void *arg) { ucontext_t *ucp; ... makecontext(ucp, trampoline, 2, (int) cb, (int) arg); ... }
For bonus points, you can change the trampoline to save the void * value returned by the callback function on the stack and get its equivalent pthread_join() .
source share