Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there something to replace the <ucontext.h> functions?

Tags:

The user thread functions in <ucontext.h> are deprecated because they use a deprecated C feature (they use a function declaration with empty parentheses for an argument).

Is there a standard replacement for them? I don't feel full-fledged threads are good at implementing cooperative threading.

like image 246
zneak Avatar asked Nov 28 '10 20:11

zneak


People also ask

What is Uc_link?

The uc_link member is used to determine the context that shall be resumed when the context being modified by makecontext() returns. The application shall ensure that the uc_link member is initialized prior to the call to makecontext().

What does swapcontext do?

The swapcontext() function saves the current user context in the context structure pointed to by oucp and restores the user context structure pointed to by ucp. swapcontext() is equivalent to getcontext() with the oucp argument followed by setcontext() with the ucp argument.

What does makecontext do in C?

makecontext writes the function info into a context, and it will remain there until it is overwritten by something else. getcontext overwites the entire context, so would overwrite any function written there by a previous call to makecontext .

What is Ucontext_t?

DESCRIPTION. The ucontext_t type is a structure type suitable for holding the context for a user thread of execution. A thread's context includes its stack, saved registers, and list of blocked signals. The ucontext_t structure contains at least these fields: ucontext_t *uc_link.


1 Answers

If you really want to do something like what the ucontext.h functions allow, I would keep using them. Anything else will be less portable. Marking them obsolescent in POSIX seems to have been a horrible mistake of pedantry by someone on the committee. POSIX itself requires function pointers and data pointers to be the same size and for function pointers to be representable cast to void *, and C itself requires a cast between function pointer types and back to be round-trip safe, so there are many ways this issue could have been solved.

There is one real problem, that converting the int argc, ... passed into makecontext into a form to pass to the function cannot be done without major assistance from the compiler unless the calling convention for variadic and non-variadic functions happens to be the same (and even then it's rather questionable whether it can be done robustly). This problem however could have been solved simply by deprecating the use of makecontext in any form other than makecontext(ucp, func, 1, (void *)arg);.

Perhaps a better question though is why you think ucontext.h functions are the best way to handle threading. If you do want to go with them, I might suggest writing a wrapper interface that you can implement either with ucontext.h or with pthreads, then comparing the performance and bloat. This will also have the advantage that, should future systems drop support for ucontext.h, you can simply switch to compiling with the pthread-based implementation and everything will simply work. (By then, the bloat might be less important, the benefit of multi-core/SMP will probably be huge, and hopefully pthread implementations will be less bloated.)

Edit (based on OP's request): To implement "cooperative threading" with pthreads, you need condition variables. Here's a decent pthreads tutorial with information on using them:

https://computing.llnl.gov/tutorials/pthreads/#ConditionVariables

Your cooperative multitasking primitive of "hand off execution to thread X" would go something like:

self->flag = 0; other_thread->flag = 1; pthread_mutex_lock(other_thread->mutex); pthread_cond_signal(other_thread->cond); pthread_mutex_unlock(other_thread->mutex); pthread_mutex_lock(self->mutex); while (!self->flag)     pthread_cond_wait(self->cond, self->mutex); pthread_mutex_unlock(self->mutex); 

Hope I got that all right; at least the general idea is correct. If anyone sees mistakes please comment so I can fix it. Half of the locking (other_thread's mutex) is probably entirely unnecessary with this sort of usage, so you could perhaps make the mutex a local variable in the task_switch function. All you'd really be doing is using pthread_cond_wait and pthread_cond_signal as "go to sleep" and "wake up other thread" primitives.

like image 158
R.. GitHub STOP HELPING ICE Avatar answered Sep 30 '22 00:09

R.. GitHub STOP HELPING ICE