From gcc Fri May 18 15:30:23 2001 From: Leon Bottou Date: Fri, 18 May 2001 15:30:23 +0000 To: gcc Subject: Re: exceptions in a coroutine enviroment X-MARC-Message: https://marc.info/?l=gcc&m=99020006420446 de@lmnet.de wrote: > Hello, > I use a C++ coroutine system which switches between the coroutines > by setjmp/longjmp. It is non-pre-emptive (resume(), call(), detach()) > The problem in using C++ exceptions is that the exception stack is used for > all the coroutines. That is true for the ``sjlj'' exception model that relies on setjmp/longjmp. Many gcc binaries use the ``eh-region'' model that bypasses the problem. I believe that gcc is migrating towards using the ``eh-region'' model for all platforms, but have no idea of when this will happen. > I found a posting from you: > "Thread safe exception with custom cooperative threads" > 25 Nov 1998 gcc-patches > Has the new gcc the eh_ functions? I never received any feedback on this patch proposal. It is not in gcc-2.95.2. > Do you have an description how this works? A simple example? The full source code is in the file GThreads.cpp of the DjVu reference library (http://www.djvuzone.org/open/) that has now be released under the GPL. The file provides a unified interface for three thread implementations (win32, mac, posix) and for a home-grown non-preemptive threading code named ``cothreads''. The libgcc patch exposes two symbols that were already present but private to libgcc: extern void* __new_eh_context(void); Allocates an exception context chain This is called whenever a new cothread is created an the returned pointer is saved into the cothread structure. extern void* (*__get_eh_context_ptr)(void); This is a pointer to function variable. Libgcc calls the function pointed by this variable whenever it needs a pointer to the current exception context chain. The thread constructor contains the followin code: GThread::GThread(int stacksize) ... { ... if (! maintask} { // first time : create maintask ... maintask->ehctx = (*__get_eh_context_ptr)(); __get_eh_context_ptr = cotask_get_eh_context } ... // allocate eh ctx for newly created thread/task. // this must be released with free() when the thread terminates. task->ehctx = __new_eh_context(); ... } Function cotask_get_eh_context() is as follows: static void * cotask_get_eh_context() { if (curtask) return curtask->ehctx; else if (maintask) return maintask->ehctx; else abort(); } This function will be called whenever libgcc needs a eh context via the pointer __get_eh_context_ptr.