/[guile]/guile/guile-core/libguile/pthread-threads.c
ViewVC logotype

Diff of /guile/guile-core/libguile/pthread-threads.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.5 by mdj, Wed Dec 18 10:53:23 2002 UTC revision 1.6 by mdj, Wed Dec 18 13:42:58 2002 UTC
# Line 44  Line 44 
44    
45  #include "libguile/scmconfig.h"  #include "libguile/scmconfig.h"
46    
47    /* Should go to threads-plugin */
48  scm_t_mutexattr scm_i_plugin_mutex;  scm_t_mutexattr scm_i_plugin_mutex;
49    
50  scm_t_mutexattr scm_i_plugin_rec_mutex;  scm_t_mutexattr scm_i_plugin_rec_mutex;
51    
 #if !defined (SCM_MUTEX_RECURSIVE) || defined (SCM_DEBUG_THREADS)  
   
 typedef struct rec_mutex {  
 #ifdef SCM_DEBUG_THREADS  
   int kind;  
 #endif  
   scm_t_mutex mutex;  
   scm_thread *owner;  
   int count;  
 } rec_mutex;  
   
 /* Mutex for recursive mutex administration */  
 static scm_t_mutex rec_mutex_mutex;  
   
 #ifdef SCM_DEBUG_THREADS  
   
 #define FAST_MUTEX 1  
 #define REC_MUTEX 2  
   
 typedef struct mutex {  
   int kind;  
   pthread_mutex_t mutex;  
   scm_thread *owner;  
   int count;  
 } mutex;  
   
 static pthread_mutex_t mutex_mutex;  
   
 int  
 scm_i_plugin_mutex_init (scm_t_mutex *mx, const scm_t_mutexattr *a)  
 {  
   mutex *m = (mutex *) mx;  
   pthread_mutex_init (&m->mutex, &scm_i_plugin_mutex);  
   m->owner = 0;  
   m->count = 0;  
   m->kind = FAST_MUTEX;  
   return 0;  
 }  
   
 int  
 scm_i_plugin_mutex_lock (scm_t_mutex *mx)  
 {  
   mutex *m = (mutex *) mx;  
   scm_thread *t = SCM_CURRENT_THREAD;  
   pthread_mutex_lock (&mutex_mutex);  
   if (m->kind != FAST_MUTEX)  
     {  
       fprintf (stderr,  
                m->kind == REC_MUTEX  
                ? "locking wrong mutex type\n"  
                : "locking uninitialized mutex\n");  
       abort ();  
     }  
   if (m->owner == t)  
     {  
       fprintf (stderr, "locking mutex already locked by self\n");  
       abort ();  
     }  
   pthread_mutex_unlock (&mutex_mutex);  
   pthread_mutex_lock (&m->mutex);  
   m->count = 1;  
   m->owner = t;  
   return 0;  
 }  
   
 int  
 scm_i_plugin_mutex_unlock (scm_t_mutex *mx)  
 {  
   mutex *m = (mutex *) mx;  
   pthread_mutex_lock (&mutex_mutex);  
   if (m->kind != FAST_MUTEX)  
     {  
       fprintf (stderr,  
                m->kind == REC_MUTEX  
                ? "locking wrong mutex type\n"  
                : "locking uninitialized mutex\n");  
       abort ();  
     }  
   if (m->count != 1)  
     {  
       fprintf (stderr,  
                m->count == 0  
                ? "unlocking unlocked mutex\n"  
                : "bogus internal state");  
       abort ();  
     }  
   m->owner = 0;  
   m->count = 0;  
   pthread_mutex_unlock (&m->mutex);  
   pthread_mutex_unlock (&mutex_mutex);  
   return 0;  
 }  
   
 int  
 scm_i_plugin_cond_wait (scm_t_cond *c, scm_t_mutex *mx)  
 {  
   mutex *m = (mutex *) mx;  
   int res;  
   if (m->owner != SCM_CURRENT_THREAD || m->count != 1)  
     {  
       fprintf (stderr, "mutex not locked by self\n");  
       abort ();  
     }  
   res = pthread_cond_wait ((pthread_cond_t *) c, &m->mutex);  
   if (m->owner != 0 || m->count != 0)  
     {  
       fprintf (stderr, "strange internal state\n");  
       abort ();  
     }  
   m->owner = SCM_CURRENT_THREAD;  
   m->count = 1;  
   return res;  
 }  
   
 int  
 scm_i_plugin_cond_timedwait (scm_t_cond *c,  
                         scm_t_mutex *mx,  
                         const struct timespec *t)  
 {  
   mutex *m = (mutex *) mx;  
   return pthread_cond_timedwait ((pthread_cond_t *) c, &m->mutex, t);  
 }  
   
 void  
 scm_i_assert_heap_locked ()  
 {  
   mutex *m = (mutex *) &SCM_CURRENT_THREAD->heap_mutex;  
   pthread_mutex_lock (&mutex_mutex);  
   if (gc_running)  
     {  
       fprintf (stderr, "thread running during gc\n");  
       abort ();  
     }  
   if (m->count != 1)  
     {  
       fprintf (stderr, "mutex not locked\n");  
       abort ();  
     }  
   pthread_mutex_unlock (&mutex_mutex);  
 }  
   
 #endif  
   
 /* The following section belongs in threads.c, or rather  
    thread-plugin.c.  It is generic and not tied to any particular  
    thread library. */  
   
 int  
 scm_i_plugin_rec_mutex_init (scm_t_rec_mutex *mx, const scm_t_mutexattr *a)  
 {  
   rec_mutex *m = (rec_mutex *) mx;  
   scm_i_plugin_mutex_init (&m->mutex, &scm_i_plugin_mutex);  
   m->owner = 0;  
   m->count = 0;  
 #ifdef SCM_DEBUG_THREADS  
   m->kind = REC_MUTEX;  
 #endif  
   return 0;  
 }  
   
 int  
 scm_i_plugin_rec_mutex_lock (scm_t_rec_mutex *mx)  
 {  
   rec_mutex *m = (rec_mutex *) mx;  
   scm_thread *t = SCM_CURRENT_THREAD;  
   scm_i_plugin_mutex_lock (&rec_mutex_mutex);  
 #ifdef SCM_DEBUG_THREADS  
   if (m->kind != REC_MUTEX)  
     {  
       fprintf (stderr,  
                m->kind == FAST_MUTEX  
                ? "locking wrong mutex type\n"  
                : "locking uninitialized mutex\n");  
       abort ();  
     }  
 #endif  
   if (m->count && m->owner == t)  
     {  
       ++m->count;  
       scm_i_plugin_mutex_unlock (&rec_mutex_mutex);  
     }  
   else  
     {  
       scm_i_plugin_mutex_unlock (&rec_mutex_mutex);  
       scm_i_plugin_mutex_lock (&m->mutex);  
       m->count = 1;  
       m->owner = t;  
     }  
   return 0;  
 }  
   
 int  
 scm_i_plugin_rec_mutex_trylock (scm_t_rec_mutex *mx)  
 {  
   rec_mutex *m = (rec_mutex *) mx;  
   scm_thread *t = SCM_CURRENT_THREAD;  
   scm_i_plugin_mutex_lock (&rec_mutex_mutex);  
   if (m->owner != 0 && m->owner != t)  
     return EBUSY;  
   else if (m->count)  
     {  
       ++m->count;  
       scm_i_plugin_mutex_unlock (&rec_mutex_mutex);  
     }  
   else  
     {  
       scm_i_plugin_mutex_unlock (&rec_mutex_mutex);  
       scm_i_plugin_mutex_lock (&m->mutex);  
       m->count = 1;  
       m->owner = t;  
     }  
   return 0;  
 }  
   
 int  
 scm_i_plugin_rec_mutex_unlock (scm_t_rec_mutex *mx)  
 {  
   rec_mutex *m = (rec_mutex *) mx;  
   scm_i_plugin_mutex_lock (&rec_mutex_mutex);  
 #ifdef SCM_DEBUG_THREADS  
   if (m->kind != REC_MUTEX)  
     {  
       fprintf (stderr,  
                m->kind == FAST_MUTEX  
                ? "locking wrong mutex type\n"  
                : "locking uninitialized mutex\n");  
       abort ();  
     }  
   if (m->count == 0)  
     {  
       fprintf (stderr, "unlocking unlocked mutex\n");  
       abort ();  
     }  
 #endif  
   if (!--m->count)  
     {  
       m->owner = 0;  
       scm_i_plugin_mutex_unlock (&m->mutex);  
     }  
   scm_i_plugin_mutex_unlock (&rec_mutex_mutex);  
   return 0;  
 }  
   
 #endif /* !PTHREAD_MUTEX_RECURSIVE */  
   
52  #ifndef SCM_MUTEXATTR_SETTYPE_DECLARED  #ifndef SCM_MUTEXATTR_SETTYPE_DECLARED
53  int pthread_mutexattr_settype (pthread_mutexattr_t *, int);  int pthread_mutexattr_settype (pthread_mutexattr_t *, int);
54  #endif  #endif
# Line 300  int pthread_mutexattr_settype (pthread_m Line 56  int pthread_mutexattr_settype (pthread_m
56  void  void
57  scm_init_pthread_threads ()  scm_init_pthread_threads ()
58  {  {
   size_t mutex_size, rec_mutex_size;  
59    pthread_mutexattr_init (&scm_i_plugin_mutex);    pthread_mutexattr_init (&scm_i_plugin_mutex);
60  #ifdef SCM_MUTEX_FAST  #ifdef SCM_MUTEX_FAST
61    pthread_mutexattr_settype (&scm_i_plugin_mutex, SCM_MUTEX_FAST);    pthread_mutexattr_settype (&scm_i_plugin_mutex, SCM_MUTEX_FAST);
62  #endif  #endif
63      /* These values should be passed in a structure. */
64      scm_i_plugin_mutex_size = sizeof (pthread_mutex_t);
65      scm_i_plugin_mutex_init = (scm_t_mutex_init) pthread_mutex_init;
66      scm_i_plugin_mutex_lock = (scm_t_mutex_lock) pthread_mutex_lock;
67      scm_i_plugin_mutex_unlock = (scm_t_mutex_unlock) pthread_mutex_unlock;
68    
69  #if defined (SCM_MUTEX_RECURSIVE) && !defined (SCM_DEBUG_THREADS)  #if defined (SCM_MUTEX_RECURSIVE) && !defined (SCM_DEBUG_THREADS)
   rec_mutex_size = sizeof (pthread_mutex_t);  
70    pthread_mutexattr_init (&scm_i_plugin_rec_mutex);    pthread_mutexattr_init (&scm_i_plugin_rec_mutex);
71    pthread_mutexattr_settype (&scm_i_plugin_rec_mutex, SCM_MUTEX_RECURSIVE);    pthread_mutexattr_settype (&scm_i_plugin_rec_mutex, SCM_MUTEX_RECURSIVE);
72  #else    scm_i_plugin_rec_mutex_size = sizeof (pthread_mutex_t);
73    /* If PTHREAD_MUTEX_RECURSIVE is not defined,    scm_i_plugin_rec_mutex_init = (scm_t_rec_mutex_init) pthread_mutex_init;
74       scm_i_plugin_rec_mutex_init won't pay attention to it anyway    scm_i_plugin_rec_mutex_destroy = (scm_t_rec_mutex_destroy) pthread_mutex_destroy;
75    */    scm_i_plugin_rec_mutex_lock = (scm_t_rec_mutex_lock) pthread_mutex_lock;
76    rec_mutex_size = sizeof (rec_mutex);    scm_i_plugin_rec_mutex_trylock = (scm_t_rec_mutex_trylock) pthread_mutex_trylock;
77    scm_i_plugin_mutex_init (&rec_mutex_mutex, &scm_i_plugin_mutex);    scm_i_plugin_rec_mutex_unlock = (scm_t_rec_mutex_unlock) pthread_mutex_unlock;
 #endif  
 #ifdef SCM_DEBUG_THREADS  
   mutex_size = sizeof (mutex);  
   pthread_mutex_init (&mutex_mutex, &scm_i_plugin_mutex);  
 #else  
   mutex_size = sizeof (pthread_mutex_t);  
78  #endif  #endif
79    if (mutex_size > SCM_MUTEX_MAXSIZE || rec_mutex_size > SCM_REC_MUTEX_MAXSIZE)  
80      {    scm_init_threads_plugin ();
       fprintf (stderr, "Internal error: Need to upgrade mutex size\n");  
       abort ();  
     }  
81  }  }
82    
83  /*  /*

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.6

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26