On Mon, May 09, 2016 at 10:03:02PM +0200, Michael Matz wrote: > Hi, > > On Mon, 9 May 2016, Rich Felker wrote: > > > > > The *context APIs are deprecated and I'm not sure they're worth > > > > supporting with this. It would be a good excuse to get people to > > > > stop using them. > > > > > > How? POSIX decided to remove the facilities without any adequate > > > replacement (thread aren't). > > > > Threads work just as well as the ucontext api for coroutines. Due to the > > requirement to save/restore signal masks, the latter requires a syscall, > > making it no faster than a voluntary context switch via futex syscall. > > Uhm, no. If you disregard efficiency, sure, POSIX threads are sometimes a > replacement on some platforms. They still have completely different > activation models (being synchronous with *context, for which you need > even further slow synchronization in a threading model).
switch_to_next: sem_post(next->sem); while (sem_wait(self->sem)); It can actually be done more idiomatically with cond vars, but I don't see a way to make it as efficient. > > Most of the other hacks people used the ucontext API for were complete > > hacks with undefined behavior, anyway. > > Sure, that doesn't imply the facility should be removed. I can misuse all > kinds of stuff. Indeed. > > BTW it's not even possible to implement makecontext on most targets due > > to the wacky variadic calling convention it uses -- in most ABIs, > > there's simply no way to shift the variadic args into the right slots > > for calling the start function for the new context without knowing their > > types, and the implementation has no way to know the types. So it's > > really an unusably broken API. > > Of course. But _that_ implies that a workable replacement should have > been put in place, not the unrealistic stance POSIX took with the removal: > makecontext2(ucontext_t *ucp, void (*func)(void*), void* cookie); It could have been done even more simply, without a new function, by just saying the behavior is undefined unless func has type void(*)(void), argc==1, and the first variadic arg has type void*. > Done. I never understood why they left in the hugely > unuseful {sig,}{set,long}jmp() but removed the actually useful *context() > (amended somehow like above). Because those are actually part of the C language (the non-sig versions, but the sig versions are needed to work around broken unices that made the non-sig versions save/restore signal mask and thus too slow to ever use). They're also much more useful for actually reasonable code (non-local exit across functions that were badly designed with no error paths) as opposed to just nasty hacks that are mostly/entirely UB anyway (coroutines, etc.). Rich