pike.git / src / threads.h

version» Context lines:

pike.git/src/threads.h:1:   /* -  * $Id: threads.h,v 1.118 2003/03/31 18:20:14 grubba Exp $ +  * $Id: threads.h,v 1.119 2003/05/07 21:01:03 mast Exp $    */   #ifndef THREADS_H   #define THREADS_H      #include "machine.h"   #include "object.h"   #include "pike_error.h"   #include "interpret.h" -  + #include "main.h"      /* Needed for the sigset_t typedef, which is needed for    * the pthread_sigsetmask() prototype on Solaris 2.x.    */   #include <signal.h>      #ifdef HAVE_SYS_TYPES_H   /* Needed for pthread_t on OSF/1 */   #include <sys/types.h>   #endif /* HAVE_SYS_TYPES_H */
pike.git/src/threads.h:67:   #define fp Pike_fp   #undef FRAMEPOINTER_WAS_DEFINED   #endif /* FRAMEPOINTER_WAS_DEFINED */         extern int num_threads;   PMOD_EXPORT extern int live_threads;   struct object;   PMOD_EXPORT extern size_t thread_stack_size;    + PMOD_EXPORT void thread_low_error (int errcode); +  + #define LOW_THREAD_CHECK_NONZERO_ERROR(CALL) do { \ +  int thread_errcode_ = (CALL); \ +  if (thread_errcode_) thread_low_error (thread_errcode_); \ +  } while (0) +    #define DEFINE_MUTEX(X) PIKE_MUTEX_T X         #ifdef POSIX_THREADS      #ifdef HAVE_PTHREAD_ATFORK   #define th_atfork(X,Y,Z) pthread_atfork((X),(Y),(Z))   #define th_atfork_prepare()   #define th_atfork_parent()   #define th_atfork_child()   #else   int th_atfork(void (*)(void),void (*)(void),void (*)(void));   void th_atfork_prepare(void);   void th_atfork_parent(void);   void th_atfork_child(void);   #endif      #define THREAD_T pthread_t   #define PIKE_MUTEX_T pthread_mutex_t -  +  + #if !defined(HAVE_PTHREAD_MUTEX_ERRORCHECK_NP) && defined(HAVE_PTHREAD_MUTEX_ERRORCHECK) + #define PTHREAD_MUTEX_ERRORCHECK_NP PTHREAD_MUTEX_ERRORCHECK + #define HAVE_PTHREAD_MUTEX_ERRORCHECK_NP + #endif +  + #ifdef HAVE_PTHREAD_MUTEX_ERRORCHECK_NP + #define mt_init(X) do { \ +  if (debug_options & ERRORCHECK_MUTEXES) { \ +  pthread_mutexattr_t attr; \ +  pthread_mutexattr_init(&attr); \ +  pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK_NP); \ +  pthread_mutex_init((X), &attr); \ +  } \ +  else \ +  pthread_mutex_init((X),0); \ +  } while (0) + #define DO_IF_PIKE_MUTEX_ERRORCHECK(X) X + #else   #define mt_init(X) pthread_mutex_init((X),0) -  + #define DO_IF_PIKE_MUTEX_ERRORCHECK(X) + #endif      #if !defined(HAVE_PTHREAD_MUTEX_RECURSIVE_NP) && defined(HAVE_PTHREAD_MUTEX_RECURSIVE)   #define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE   #define HAVE_PTHREAD_MUTEX_RECURSIVE_NP   #endif      #ifdef HAVE_PTHREAD_MUTEX_RECURSIVE_NP   #define mt_init_recursive(X) \    do{ \    pthread_mutexattr_t attr; \    pthread_mutexattr_init(&attr); \ -  pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP); \ +  pthread_mutexattr_settype( \ +  &attr, \ +  PTHREAD_MUTEX_RECURSIVE_NP \ +  DO_IF_PIKE_MUTEX_ERRORCHECK (| PTHREAD_MUTEX_ERRORCHECK_NP)); \    pthread_mutex_init((X), &attr); \    }while(0)   #endif    - #define mt_lock(X) pthread_mutex_lock(X) + #define mt_lock(X) LOW_THREAD_CHECK_NONZERO_ERROR (pthread_mutex_lock(X))   #define mt_trylock(X) pthread_mutex_trylock(X) - #define mt_unlock(X) pthread_mutex_unlock(X) + #define mt_unlock(X) LOW_THREAD_CHECK_NONZERO_ERROR (pthread_mutex_unlock(X))   #define mt_destroy(X) pthread_mutex_destroy(X)      /* SIGH! No setconcurrency in posix threads. This is more or less    * needed to make usable multi-threaded programs on solaris machines    * with only one CPU. Otherwise, only systemcalls are actually    * threaded.    */   #define th_setconcurrency(X)   #ifdef HAVE_PTHREAD_YIELD   #define th_yield() pthread_yield()
pike.git/src/threads.h:171:   #endif /* POSIX_THREADS */               #ifdef UNIX_THREADS   #define THREAD_T thread_t   #define PTHREAD_MUTEX_INITIALIZER DEFAULTMUTEX   #define PIKE_MUTEX_T mutex_t   #define mt_init(X) mutex_init((X),USYNC_THREAD,0) - #define mt_lock(X) mutex_lock(X) + #define mt_lock(X) LOW_THREAD_CHECK_NONZERO_ERROR (mutex_lock(X))   #define mt_trylock(X) mutex_trylock(X) - #define mt_unlock(X) mutex_unlock(X) + #define mt_unlock(X) LOW_THREAD_CHECK_NONZERO_ERROR (mutex_unlock(X))   #define mt_destroy(X) mutex_destroy(X)      #define th_setconcurrency(X) thr_setconcurrency(X)      #define th_create(ID,fun,arg) thr_create(NULL,thread_stack_size,fun,arg,THR_DAEMON|THR_DETACHED,ID)   #define th_create_small(ID,fun,arg) thr_create(NULL,8192*sizeof(char *),fun,arg,THR_DAEMON|THR_DETACHED,ID)   #define th_exit(foo) thr_exit(foo)   #define th_self() thr_self()   #define th_kill(ID,sig) thr_kill((ID),(sig))   #define th_yield() thr_yield()
pike.git/src/threads.h:232:    * No cond_vars yet    */      #endif /* SGI_SPROC_THREADS */         #ifdef NT_THREADS   #include <process.h>   #include <windows.h>    + #define LOW_THREAD_CHECK_ZERO_ERROR(CALL) do { \ +  if (!(CALL)) thread_low_error (GetLastError()); \ +  } while (0) +    #define THREAD_T unsigned   #define th_setconcurrency(X)   #define th_create(ID,fun,arg) low_nt_create_thread(2*1024*1024,fun, arg,ID)   #define th_create_small(ID,fun,arg) low_nt_create_thread(8192*sizeof(char *), fun,arg,ID)   #define TH_RETURN_TYPE unsigned __stdcall   #define TH_STDCALL __stdcall   #define th_exit(foo) _endthreadex(foo)   #define th_join(ID,res) /******************* FIXME! ****************/   #define th_self() GetCurrentThreadId()   #define th_destroy(X)   #define th_yield() Sleep(0)   #define th_equal(X,Y) ((X)==(Y))   #define th_hash(X) (X)      #define PIKE_MUTEX_T HANDLE   #define mt_init(X) CheckValidHandle((*(X)=CreateMutex(NULL, 0, NULL))) - #define mt_lock(X) WaitForSingleObject(CheckValidHandle(*(X)), INFINITE) - #define mt_trylock(X) WaitForSingleObject(CheckValidHandle(*(X)), 0) - #define mt_unlock(X) ReleaseMutex(CheckValidHandle(*(X))) + #define mt_lock(X) \ +  LOW_THREAD_CHECK_ZERO_ERROR ( \ +  WaitForSingleObject(CheckValidHandle(*(X)), INFINITE) == WAIT_OBJECT_0) + #define mt_trylock(X) \ +  LOW_THREAD_CHECK_ZERO_ERROR ( \ +  WaitForSingleObject(CheckValidHandle(*(X)), 0) != WAIT_FAILED) + #define mt_unlock(X) LOW_THREAD_CHECK_ZERO_ERROR (ReleaseMutex(CheckValidHandle(*(X))))   #define mt_destroy(X) CloseHandle(CheckValidHandle(*(X)))      #define EVENT_T HANDLE   #define event_init(X) CheckValidHandle(*(X)=CreateEvent(NULL, 1, 0, NULL)) - #define event_signal(X) SetEvent(CheckValidHandle(*(X))) + #define event_signal(X) LOW_THREAD_CHECK_ZERO_ERROR (SetEvent(CheckValidHandle(*(X))))   #define event_destroy(X) CloseHandle(CheckValidHandle(*(X))) - #define event_wait(X) WaitForSingleObject(CheckValidHandle(*(X)), INFINITE) + #define event_wait(X) \ +  LOW_THREAD_CHECK_ZERO_ERROR ( \ +  WaitForSingleObject(CheckValidHandle(*(X)), INFINITE) == WAIT_OBJECT_0)      #endif         #if !defined(COND_T) && defined(EVENT_T) && defined(PIKE_MUTEX_T)      #define SIMULATE_COND_WITH_EVENT      struct cond_t_queue   {
pike.git/src/threads.h:280:   };      typedef struct cond_t_s   {    PIKE_MUTEX_T lock;    struct cond_t_queue *head, *tail;   } COND_T;      #define COND_T struct cond_t_s    - #define co_init(X) do { mt_init(& (X)->lock), (X)->head=(X)->tail=0; }while(0) + #define co_init(X) do { mt_init(& (X)->lock); (X)->head=(X)->tail=0; }while(0)      PMOD_EXPORT int co_wait(COND_T *c, PIKE_MUTEX_T *m);   PMOD_EXPORT int co_signal(COND_T *c);   PMOD_EXPORT int co_broadcast(COND_T *c);   PMOD_EXPORT int co_destroy(COND_T *c);      #endif      extern int th_running;      PMOD_EXPORT extern PIKE_MUTEX_T interpreter_lock;      #if defined(PIKE_DEBUG) && !defined(__NT__)      /* This is a debug wrapper to enable checks that the interpreter lock    * is hold by the current thread. */      extern THREAD_T debug_locking_thread;   #define SET_LOCKING_THREAD (debug_locking_thread = th_self(), 0)    - #define mt_lock_interpreter() (mt_lock(&interpreter_lock) || SET_LOCKING_THREAD) + #define mt_lock_interpreter() \ +  do {mt_lock(&interpreter_lock); SET_LOCKING_THREAD;} while (0)   #define mt_trylock_interpreter() (mt_trylock(&interpreter_lock) || SET_LOCKING_THREAD) - #define mt_unlock_interpreter() (mt_unlock(&interpreter_lock)) + #define mt_unlock_interpreter() do {mt_unlock(&interpreter_lock);} while (0)   #define co_wait_interpreter(COND) \    do {co_wait((COND), &interpreter_lock); SET_LOCKING_THREAD;} while (0)      #define CHECK_INTERPRETER_LOCK() do { \    if (th_running) { \    THREAD_T self; \    if (!mt_trylock(&interpreter_lock)) \    fatal("Interpreter is not locked.\n"); \    self = th_self(); \    if (!th_equal(debug_locking_thread, self)) \    fatal("Interpreter is not locked by this thread.\n"); \    } \   } while (0)      #else    - #define mt_lock_interpreter() (mt_lock(&interpreter_lock)) + #define mt_lock_interpreter() do {mt_lock(&interpreter_lock);} while (0)   #define mt_trylock_interpreter() (mt_trylock(&interpreter_lock)) - #define mt_unlock_interpreter() (mt_unlock(&interpreter_lock)) + #define mt_unlock_interpreter() do {mt_unlock(&interpreter_lock);} while (0)   #define co_wait_interpreter(COND) do {co_wait((COND), &interpreter_lock);} while (0)      #endif      PMOD_EXPORT extern COND_T live_threads_change; /* Used by _disable_threads */   PMOD_EXPORT extern COND_T threads_disabled_change; /* Used by _disable_threads */      struct svalue;   struct pike_frame;