This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

EGCS-1.1.1 PATCH: hooks in libgcc(eh.o) [thread safety]


( now with a better subject line )

There are many cases where we want to use hand-made cooperative threads
- when the system does not provide threads, 
- when we run in a .so file loaded by a non-threaded program 
  shared object (netscape plugins)

EGCS exceptions will not work in portable mode (-fsjlj-exceptions) with
cooperative threads because the exception handler chain gets mixed.
This is the only problem since there is no real need to lock data structures 
with cooperative threads.

Here is a patch on libgcc2.c (release_1_1_1 branch) which exposes
the function __new_eh_context() and the pointer __get_eh_context_ptr.
A user program can now redirect __get_eh_context_ptr to a custom
function which will properly create a __new_eh_context() per cooperative
thread and return the right eh context pointer.  There is no need
to write a custom gthr-my-own-threads.h or to recompile libgcc.a.

The changes consist of:
- removing a two "static" keywords
- renaming the corresponding function/pointer with a double underscore prefix.
- propagating the new names where needed.
 
Is this patch acceptable ?

- Leon Bottou.
Index: libgcc2.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/libgcc2.c,v
retrieving revision 1.46.2.1
diff -c -r1.46.2.1 libgcc2.c
*** libgcc2.c	1998/11/23 20:37:20	1.46.2.1
--- libgcc2.c	1998/11/25 21:32:34
***************
*** 3063,3071 ****
  
  extern void __throw ();
  
! static void *
! new_eh_context ()
  {
    struct eh_full_context {
      struct eh_context c;
      void *top_elt[2];
--- 3063,3073 ----
  
  extern void __throw ();
  
! void *
! __new_eh_context ()
  {
+   /* This function is externally visible so that user programs may call it.
+      This is useful when a program uses non-system cooperative threads. */
    struct eh_full_context {
      struct eh_context c;
      void *top_elt[2];
***************
*** 3101,3107 ****
  }
  #endif
  
! /* Pointer to function to return EH context. */
  
  static struct eh_context *eh_context_initialize ();
  static struct eh_context *eh_context_static ();
--- 3103,3111 ----
  }
  #endif
  
! /* Pointer to function to return EH context. 
!    This pointer is external so that user programs can modify
!    it in order to adapt to any hand-made cooperative threads. */
  
  static struct eh_context *eh_context_initialize ();
  static struct eh_context *eh_context_static ();
***************
*** 3109,3115 ****
  static struct eh_context *eh_context_specific ();
  #endif
  
! static struct eh_context *(*get_eh_context) () = &eh_context_initialize;
  
  /* Routine to get EH context.
     This one will simply call the function pointer. */
--- 3113,3119 ----
  static struct eh_context *eh_context_specific ();
  #endif
  
! struct eh_context *(*__get_eh_context_ptr) () = &eh_context_initialize;
  
  /* Routine to get EH context.
     This one will simply call the function pointer. */
***************
*** 3117,3123 ****
  void *
  __get_eh_context ()
  {
!   return (void *) (*get_eh_context) ();
  }
  
  /* Get and set the language specific info pointer. */
--- 3121,3127 ----
  void *
  __get_eh_context ()
  {
!   return (void *) (*__get_eh_context_ptr) ();
  }
  
  /* Get and set the language specific info pointer. */
***************
*** 3125,3131 ****
  void **
  __get_eh_info ()
  {
!   struct eh_context *eh = (*get_eh_context) ();
    return &eh->info;
  }
  
--- 3129,3135 ----
  void **
  __get_eh_info ()
  {
!   struct eh_context *eh = (*__get_eh_context_ptr) ();
    return &eh->info;
  }
  
***************
*** 3136,3149 ****
    /* Try to create the key.  If it fails, revert to static method,
       otherwise start using thread specific EH contexts. */
    if (__gthread_key_create (&eh_context_key, &eh_context_free) == 0)
!     get_eh_context = &eh_context_specific;
    else
!     get_eh_context = &eh_context_static;
  }
  #endif /* no __GTHREADS */
  
  /* Initialize EH context.
!    This will be called only once, since we change GET_EH_CONTEXT
     pointer to another routine. */
  
  static struct eh_context *
--- 3140,3153 ----
    /* Try to create the key.  If it fails, revert to static method,
       otherwise start using thread specific EH contexts. */
    if (__gthread_key_create (&eh_context_key, &eh_context_free) == 0)
!     __get_eh_context_ptr = &eh_context_specific;
    else
!     __get_eh_context_ptr = &eh_context_static;
  }
  #endif /* no __GTHREADS */
  
  /* Initialize EH context.
!    This will be called only once, since we change __GET_EH_CONTEXT_PTR
     pointer to another routine. */
  
  static struct eh_context *
***************
*** 3152,3175 ****
  #if __GTHREADS
  
    static __gthread_once_t once = __GTHREAD_ONCE_INIT;
!   /* Make sure that get_eh_context does not point to us anymore.
       Some systems have dummy thread routines in their libc that
       return a success (Solaris 2.6 for example). */
    if (__gthread_once (&once, eh_threads_initialize) != 0
!       || get_eh_context == &eh_context_initialize)
      {
        /* Use static version of EH context. */
!       get_eh_context = &eh_context_static;
      }
  
  #else /* no __GTHREADS */
  
    /* Use static version of EH context. */
!   get_eh_context = &eh_context_static;
  
  #endif /* no __GTHREADS */
  
!   return (*get_eh_context) ();
  }
  
  /* Return a static EH context. */
--- 3156,3179 ----
  #if __GTHREADS
  
    static __gthread_once_t once = __GTHREAD_ONCE_INIT;
!   /* Make sure that __get_eh_context_ptr does not point to us anymore.
       Some systems have dummy thread routines in their libc that
       return a success (Solaris 2.6 for example). */
    if (__gthread_once (&once, eh_threads_initialize) != 0
!       || __get_eh_context_ptr == &eh_context_initialize)
      {
        /* Use static version of EH context. */
!       __get_eh_context_ptr = &eh_context_static;
      }
  
  #else /* no __GTHREADS */
  
    /* Use static version of EH context. */
!   __get_eh_context_ptr = &eh_context_static;
  
  #endif /* no __GTHREADS */
  
!   return (*__get_eh_context_ptr) ();
  }
  
  /* Return a static EH context. */
***************
*** 3179,3185 ****
  {
    static struct eh_context *eh;
    if (! eh)
!     eh = new_eh_context ();
    return eh;
  }
  
--- 3183,3189 ----
  {
    static struct eh_context *eh;
    if (! eh)
!     eh = __new_eh_context ();
    return eh;
  }
  
***************
*** 3193,3199 ****
    eh = (struct eh_context *) __gthread_getspecific (eh_context_key);
    if (! eh)
      {
!       eh = new_eh_context ();
        if (__gthread_setspecific (eh_context_key, (void *) eh) != 0)
  	__terminate ();
      }
--- 3197,3203 ----
    eh = (struct eh_context *) __gthread_getspecific (eh_context_key);
    if (! eh)
      {
!       eh = __new_eh_context ();
        if (__gthread_setspecific (eh_context_key, (void *) eh) != 0)
  	__terminate ();
      }
***************
*** 3218,3224 ****
  void ***
  __get_dynamic_handler_chain ()
  {
!   struct eh_context *eh = (*get_eh_context) ();
    return &eh->dynamic_handler_chain;
  }
  
--- 3222,3228 ----
  void ***
  __get_dynamic_handler_chain ()
  {
!   struct eh_context *eh = (*__get_eh_context_ptr) ();
    return &eh->dynamic_handler_chain;
  }
  
***************
*** 3233,3239 ****
  void
  __sjthrow ()
  {
!   struct eh_context *eh = (*get_eh_context) ();
    void ***dhc = &eh->dynamic_handler_chain;
    void *jmpbuf;
    void (*func)(void *, int);
--- 3237,3243 ----
  void
  __sjthrow ()
  {
!   struct eh_context *eh = (*__get_eh_context_ptr) ();
    void ***dhc = &eh->dynamic_handler_chain;
    void *jmpbuf;
    void (*func)(void *, int);
***************
*** 3309,3315 ****
  void
  __sjpopnthrow ()
  {
!   struct eh_context *eh = (*get_eh_context) ();
    void ***dhc = &eh->dynamic_handler_chain;
    void (*func)(void *, int);
    void *arg;
--- 3313,3319 ----
  void
  __sjpopnthrow ()
  {
!   struct eh_context *eh = (*__get_eh_context_ptr) ();
    void ***dhc = &eh->dynamic_handler_chain;
    void (*func)(void *, int);
    void *arg;
***************
*** 3597,3603 ****
  void
  __throw ()
  {
!   struct eh_context *eh = (*get_eh_context) ();
    void *saved_pc, *pc, *handler, *retaddr;
    frame_state ustruct, ustruct2;
    frame_state *udata = &ustruct;
--- 3601,3607 ----
  void
  __throw ()
  {
!   struct eh_context *eh = (*__get_eh_context_ptr) ();
    void *saved_pc, *pc, *handler, *retaddr;
    frame_state ustruct, ustruct2;
    frame_state *udata = &ustruct;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]