[prev in list] [next in list] [prev in thread] [next in thread] 

List:       gcc
Subject:    Re: exceptions in a coroutine enviroment
From:       Leon Bottou <leonb () research ! att ! com>
Date:       2001-05-18 15:30:23
[Download RAW message or body]


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"
  <http://gcc.gnu.org/ml/gcc-patches/1998-11/msg00435.html>
> 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.

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic