24ddc71998-03-28Henrik Grubbström (Grubba) /*
a91ca01998-07-10Henrik Grubbström (Grubba)  * $Id: threads.h,v 1.45 1998/07/10 15:52:08 grubba Exp $
24ddc71998-03-28Henrik Grubbström (Grubba)  */
07513e1996-10-04Fredrik Hübinette (Hubbe) #ifndef THREADS_H #define THREADS_H #include "machine.h" #include "interpret.h"
a7fef41997-09-03Per Hedbor #include "object.h"
07513e1996-10-04Fredrik Hübinette (Hubbe) #include "error.h"
be478c1997-08-30Henrik Grubbström (Grubba) #ifdef HAVE_SYS_TYPES_H /* Needed for pthread_t on OSF/1 */ #include <sys/types.h> #endif /* HAVE_SYS_TYPES_H */
07513e1996-10-04Fredrik Hübinette (Hubbe) #ifdef _REENTRANT
b2a0fb1997-02-06Henrik Grubbström (Grubba) /* * Decide which type of threads to use *
0409001998-02-10Per Hedbor  * UNIX_THREADS : Unix international threads * POSIX_THREADS : POSIX standard threads
b2a0fb1997-02-06Henrik Grubbström (Grubba)  * SGI_SPROC_THREADS : SGI sproc() based threads
0409001998-02-10Per Hedbor  * NT_THREADS : NT threads
b2a0fb1997-02-06Henrik Grubbström (Grubba)  */ #ifdef _UNIX_THREADS
97ffe41997-01-26Per Hedbor #ifdef HAVE_THREAD_H #define UNIX_THREADS #include <thread.h> #undef HAVE_PTHREAD_H #undef HAVE_THREAD_H #endif
b2a0fb1997-02-06Henrik Grubbström (Grubba) #endif /* _UNIX_THREADS */
97ffe41997-01-26Per Hedbor 
b2a0fb1997-02-06Henrik Grubbström (Grubba) #ifdef _MIT_POSIX_THREADS
07513e1996-10-04Fredrik Hübinette (Hubbe) #ifdef HAVE_PTHREAD_H
97ffe41997-01-26Per Hedbor #define POSIX_THREADS
07513e1996-10-04Fredrik Hübinette (Hubbe) #include <pthread.h> #undef HAVE_PTHREAD_H #endif
b2a0fb1997-02-06Henrik Grubbström (Grubba) #endif /* _MIT_POSIX_THREADS */
07513e1996-10-04Fredrik Hübinette (Hubbe) 
b2a0fb1997-02-06Henrik Grubbström (Grubba) #ifdef _SGI_SPROC_THREADS
5377b91997-02-01Henrik Grubbström (Grubba) /* Not supported yet */
b2a0fb1997-02-06Henrik Grubbström (Grubba) #undef SGI_SPROC_THREADS
5377b91997-02-01Henrik Grubbström (Grubba) #undef HAVE_SPROC
b2a0fb1997-02-06Henrik Grubbström (Grubba) #endif /* _SGI_SPROC_THREADS */
97ffe41997-01-26Per Hedbor 
07513e1996-10-04Fredrik Hübinette (Hubbe) extern int num_threads;
ef1e931998-03-26Henrik Grubbström (Grubba) extern int live_threads;
6d1a5e1996-10-07Fredrik Hübinette (Hubbe) struct object; extern struct object *thread_id;
07513e1996-10-04Fredrik Hübinette (Hubbe) 
97ffe41997-01-26Per Hedbor #define DEFINE_MUTEX(X) MUTEX_T X #ifdef POSIX_THREADS #define THREAD_T pthread_t
07513e1996-10-04Fredrik Hübinette (Hubbe) #define MUTEX_T pthread_mutex_t #define mt_init(X) pthread_mutex_init((X),0) #define mt_lock(X) pthread_mutex_lock(X) #define mt_trylock(X) pthread_mutex_trylock(X) #define mt_unlock(X) pthread_mutex_unlock(X) #define mt_destroy(X) pthread_mutex_destroy(X)
97ffe41997-01-26Per Hedbor /* 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)
5377b91997-02-01Henrik Grubbström (Grubba) #ifdef HAVE_PTHREAD_YIELD #define th_yield() pthread_yield() #else
97ffe41997-01-26Per Hedbor #define th_yield()
5377b91997-02-01Henrik Grubbström (Grubba) #endif /* HAVE_PTHREAD_YIELD */
864d3c1998-01-29Fredrik Hübinette (Hubbe) extern pthread_attr_t pattr; extern pthread_attr_t small_pattr;
07513e1996-10-04Fredrik Hübinette (Hubbe)  #define th_create(ID,fun,arg) pthread_create(ID,&pattr,fun,arg)
864d3c1998-01-29Fredrik Hübinette (Hubbe) #define th_create_small(ID,fun,arg) pthread_create(ID,&small_pattr,fun,arg)
07513e1996-10-04Fredrik Hübinette (Hubbe) #define th_exit(foo) pthread_exit(foo)
a70bd01996-12-15Niels Möller #define th_self() pthread_self()
07513e1996-10-04Fredrik Hübinette (Hubbe) 
5377b91997-02-01Henrik Grubbström (Grubba) #ifdef HAVE_PTHREAD_COND_INIT
07513e1996-10-04Fredrik Hübinette (Hubbe) #define COND_T pthread_cond_t
5377b91997-02-01Henrik Grubbström (Grubba)  #ifdef HAVE_PTHREAD_CONDATTR_DEFAULT #define co_init(X) pthread_cond_init((X), pthread_condattr_default) #else
07513e1996-10-04Fredrik Hübinette (Hubbe) #define co_init(X) pthread_cond_init((X), 0)
5377b91997-02-01Henrik Grubbström (Grubba) #endif /* HAVE_PTHREAD_CONDATTR_DEFAULT */
07513e1996-10-04Fredrik Hübinette (Hubbe) #define co_wait(COND, MUTEX) pthread_cond_wait((COND), (MUTEX)) #define co_signal(X) pthread_cond_signal(X) #define co_broadcast(X) pthread_cond_broadcast(X) #define co_destroy(X) pthread_cond_destroy(X)
5377b91997-02-01Henrik Grubbström (Grubba) #else #error No way to make cond-vars #endif /* HAVE_PTHREAD_COND_INIT */ #endif /* POSIX_THREADS */
97ffe41997-01-26Per Hedbor  #ifdef UNIX_THREADS #define THREAD_T thread_t #define PTHREAD_MUTEX_INITIALIZER DEFAULTMUTEX #define MUTEX_T mutex_t #define mt_init(X) mutex_init((X),USYNC_THREAD,0) #define mt_lock(X) mutex_lock(X) #define mt_trylock(X) mutex_trylock(X) #define mt_unlock(X) mutex_unlock(X) #define mt_destroy(X) mutex_destroy(X) #define th_setconcurrency(X) thr_setconcurrency(X)
1b91341998-02-13Per Hedbor #define th_create(ID,fun,arg) thr_create(NULL,0,fun,arg,THR_DAEMON|THR_DETACHED,ID)
0409001998-02-10Per Hedbor #define th_create_small(ID,fun,arg) thr_create(NULL,32768,fun,arg,THR_DAEMON|THR_DETACHED,ID)
97ffe41997-01-26Per Hedbor #define th_exit(foo) thr_exit(foo) #define th_self() thr_self() #define th_yield() thr_yield() #define COND_T cond_t #define co_init(X) cond_init((X),USYNC_THREAD,0) #define co_wait(COND, MUTEX) cond_wait((COND), (MUTEX)) #define co_signal(X) cond_signal(X) #define co_broadcast(X) cond_broadcast(X) #define co_destroy(X) cond_destroy(X)
5377b91997-02-01Henrik Grubbström (Grubba)  #endif /* UNIX_THREADS */
b2a0fb1997-02-06Henrik Grubbström (Grubba) #ifdef SGI_SPROC_THREADS
5377b91997-02-01Henrik Grubbström (Grubba)  /* * Not fully supported yet */ #define THREAD_T int #define MUTEX_T ulock_t #define mt_init(X) (usinitlock(((*X) = usnewlock(/*********/)))) #define mt_lock(X) ussetlock(*X) #define mt_unlock(X) usunsetlock(*X) #define mt_destroy(X) usfreelock((*X), /*******/) #define th_setconcurrency(X) /*******/ #define PIKE_SPROC_FLAGS (PR_SADDR|PR_SFDS|PR_SDIR|PS_SETEXITSIG) #define th_create(ID, fun, arg) (((*(ID)) = sproc(fun, PIKE_SPROC_FLAGS, arg)) == -1)
864d3c1998-01-29Fredrik Hübinette (Hubbe) #define th_create_small(ID, fun, arg) (((*(ID)) = sproc(fun, PIKE_SPROC_FLAGS, arg)) == -1)
5377b91997-02-01Henrik Grubbström (Grubba) #define th_exit(X) exit(X) #define th_self() getpid() #define th_yield() sginap(0)
d213271998-02-28Fredrik Hübinette (Hubbe) #define th_equal(X,Y) ((X)==(Y)) #define th_hash(X) ((unsigned INT32)(X))
5377b91997-02-01Henrik Grubbström (Grubba)  /* * No cond_vars yet */
b2a0fb1997-02-06Henrik Grubbström (Grubba) #endif /* SGI_SPROC_THREADS */
97ffe41997-01-26Per Hedbor 
a2db6b1998-01-02Fredrik Hübinette (Hubbe)  #ifdef NT_THREADS #include <process.h>
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #include <windows.h>
a2db6b1998-01-02Fredrik Hübinette (Hubbe)  #define THREAD_T HANDLE #define th_setconcurrency(X)
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #define th_create(ID,fun,arg) (!(*(ID)=_beginthread(fun, 2*1024*1024, arg)))
864d3c1998-01-29Fredrik Hübinette (Hubbe) #define th_create_small(ID,fun,arg) (!(*(ID)=_beginthread(fun, 32768, arg)))
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #define th_exit(foo) _endthread(foo)
e42eaf1998-01-02Fredrik Hübinette (Hubbe) #define th_self() GetCurrentThread()
dc7cc91998-01-14Fredrik Hübinette (Hubbe) #define th_destroy(X)
e42eaf1998-01-02Fredrik Hübinette (Hubbe) #define th_yield() Sleep(0)
d213271998-02-28Fredrik Hübinette (Hubbe) #define th_equal(X,Y) ((X)==(Y)) #define th_hash(X) ((unsigned INT32)(X))
e42eaf1998-01-02Fredrik Hübinette (Hubbe)  #define MUTEX_T HANDLE
dc7cc91998-01-14Fredrik Hübinette (Hubbe) #define mt_init(X) CheckValidHandle((*(X)=CreateMutex(NULL, 0, NULL))) #define mt_lock(X) (CheckValidHandle(*(X)),WaitForSingleObject(*(X), INFINITE)) #define mt_trylock(X) (CheckValidHandle(*(X)),WaitForSingleObject(*(X), 0)) #define mt_unlock(X) (CheckValidHandle(*(X)),ReleaseMutex(*(X))) #define mt_destroy(X) (CheckValidHandle(*(X)),CloseHandle(*(X)))
e42eaf1998-01-02Fredrik Hübinette (Hubbe)  #define EVENT_T HANDLE
dc7cc91998-01-14Fredrik Hübinette (Hubbe) #define event_init(X) CheckValidHandle(*(X)=CreateEvent(NULL, 1, 0, NULL)) #define event_signal(X) (CheckValidHandle(*(X)),SetEvent(*(X))) #define event_destroy(X) (CheckValidHandle(*(X)),CloseHandle(*(X))) #define event_wait(X) (CheckValidHandle(*(X)),WaitForSingleObject(*(X), INFINITE))
a2db6b1998-01-02Fredrik Hübinette (Hubbe)  #endif
e42eaf1998-01-02Fredrik Hübinette (Hubbe)  #if !defined(COND_T) && defined(EVENT_T) && defined(MUTEX_T) #define SIMULATE_COND_WITH_EVENT struct cond_t_queue { struct cond_t_queue *next; EVENT_T event; };
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) typedef struct cond_t_s
e42eaf1998-01-02Fredrik Hübinette (Hubbe) { MUTEX_T lock;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  struct cond_t_queue *head, *tail;
e42eaf1998-01-02Fredrik Hübinette (Hubbe) } COND_T; #define COND_T struct cond_t_s
dc7cc91998-01-14Fredrik Hübinette (Hubbe) #define co_init(X) do { mt_init(& (X)->lock), (X)->head=(X)->tail=0; }while(0)
e42eaf1998-01-02Fredrik Hübinette (Hubbe)  int co_wait(COND_T *c, MUTEX_T *m); int co_signal(COND_T *c); int co_broadcast(COND_T *c); int co_destroy(COND_T *c); #endif
97ffe41997-01-26Per Hedbor extern MUTEX_T interpreter_lock;
ef1e931998-03-26Henrik Grubbström (Grubba) extern COND_T live_threads_change; /* Used by _disable_threads */ extern COND_T threads_disabled_change; /* Used by _disable_threads */
07513e1996-10-04Fredrik Hübinette (Hubbe)  struct svalue; struct frame;
a91ca01998-07-10Henrik Grubbström (Grubba) extern MUTEX_T interleave_lock; struct interleave_mutex { struct interleave_mutex *next; struct interleave_mutex *prev; MUTEX_T lock; }; #define IMUTEX_T struct interleave_mutex #define DEFINE_IMUTEX(name) IMUTEX_T name /* If threads are disabled, we already hold the lock. */ #define LOCK_IMUTEX(im) do { \ if (!threads_disabled) { \ THREADS_FPRINTF(0, (stderr, "Locking IMutex 0x%08p...\n", (im))); \ THREADS_ALLOW(); \ mt_lock(&((im)->lock)); \ THREADS_DISALLOW(); \ } \ } while(0) /* If threads are disabled, the lock will be released later. */ #define UNLOCK_IMUTEX(im) do { \ if (!threads_disabled) { \ THREADS_FPRINTF(0, (stderr, "Unlocking IMutex 0x%08p...\n", (im))); \ mt_unlock(&((im)->lock)); \ } \ } while(0)
5740881998-01-01Fredrik Hübinette (Hubbe) #define THREAD_NOT_STARTED -1 #define THREAD_RUNNING 0 #define THREAD_EXITED 1
07513e1996-10-04Fredrik Hübinette (Hubbe) struct thread_state {
5740881998-01-01Fredrik Hübinette (Hubbe)  char swapped; char status; COND_T status_change;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  THREAD_T id;
eac2091998-02-27Marcus Comstedt  struct thread_state *hashlink, **backlink;
5740881998-01-01Fredrik Hübinette (Hubbe)  /* Swapped variables */
07513e1996-10-04Fredrik Hübinette (Hubbe)  struct svalue *sp,*evaluator_stack; struct svalue **mark_sp,**mark_stack; struct frame *fp; int evaluator_stack_malloced; int mark_stack_malloced; JMP_BUF *recoveries;
6d1a5e1996-10-07Fredrik Hübinette (Hubbe)  struct object * thread_id;
78112c1998-04-13Henrik Grubbström (Grubba) #ifdef THREAD_TRACE int t_flag; #endif /* THREAD_TRACE */
07513e1996-10-04Fredrik Hübinette (Hubbe) };
e42eaf1998-01-02Fredrik Hübinette (Hubbe) #ifndef th_destroy #define th_destroy(X) #endif #ifndef th_yield #define th_yield() #endif
d213271998-02-28Fredrik Hübinette (Hubbe) #ifndef th_equal
ce31941998-03-10Marcus Comstedt #define th_equal(X,Y) (!MEMCMP(&(X),&(Y),sizeof(THREAD_T)))
d213271998-02-28Fredrik Hübinette (Hubbe) #endif #ifndef th_hash
9f2dc01998-03-12Henrik Grubbström (Grubba) #define th_hash(X) hashmem((unsigned char *)&(X),sizeof(THREAD_T), 16)
d213271998-02-28Fredrik Hübinette (Hubbe) #endif
60e6a61997-09-03Henrik Grubbström (Grubba) /* Define to get a debug-trace of some of the threads operations. */
a91ca01998-07-10Henrik Grubbström (Grubba) /* #define VERBOSE_THREADS_DEBUG 0 */ /* Some debug */ /* #define VERBOSE_THREADS_DEBUG 1 */ /* Lots of debug */
60e6a61997-09-03Henrik Grubbström (Grubba)  #ifndef VERBOSE_THREADS_DEBUG
a91ca01998-07-10Henrik Grubbström (Grubba) #define THREADS_FPRINTF(L,X)
60e6a61997-09-03Henrik Grubbström (Grubba) #else
a91ca01998-07-10Henrik Grubbström (Grubba) #define THREADS_FPRINTF(L,X) do { \ if ((VERBOSE_THREADS_DEBUG + 0) >= (L)) fprintf X; \ } while(0)
60e6a61997-09-03Henrik Grubbström (Grubba) #endif /* VERBOSE_THREADS_DEBUG */
78112c1998-04-13Henrik Grubbström (Grubba) #ifdef THREAD_TRACE #define SWAP_OUT_TRACE(_tmp) do { extern int t_flag; (_tmp)->t_flag = t_flag; } while(0) #define SWAP_IN_TRACE(_tmp) do { extern int t_flag; t_flag = (_tmp)->t_flag; } while(0) #else /* !THREAD_TRACE */ #define SWAP_OUT_TRACE(_tmp) #define SWAP_IN_TRACE(_tmp) #endif /* THREAD_TRACE */
a7fef41997-09-03Per Hedbor #define SWAP_OUT_THREAD(_tmp) do { \ (_tmp)->swapped=1; \ (_tmp)->evaluator_stack=evaluator_stack;\ (_tmp)->evaluator_stack_malloced=evaluator_stack_malloced;\ (_tmp)->fp=fp;\ (_tmp)->mark_sp=mark_sp;\ (_tmp)->mark_stack=mark_stack;\ (_tmp)->mark_stack_malloced=mark_stack_malloced;\ (_tmp)->recoveries=recoveries;\ (_tmp)->sp=sp; \ (_tmp)->thread_id=thread_id;\
78112c1998-04-13Henrik Grubbström (Grubba)  SWAP_OUT_TRACE(_tmp); \
a7fef41997-09-03Per Hedbor  } while(0) #define SWAP_IN_THREAD(_tmp) do {\ (_tmp)->swapped=0; \ evaluator_stack=(_tmp)->evaluator_stack;\ evaluator_stack_malloced=(_tmp)->evaluator_stack_malloced;\ fp=(_tmp)->fp;\ mark_sp=(_tmp)->mark_sp;\ mark_stack=(_tmp)->mark_stack;\ mark_stack_malloced=(_tmp)->mark_stack_malloced;\ recoveries=(_tmp)->recoveries;\ sp=(_tmp)->sp;\ thread_id=(_tmp)->thread_id;\
78112c1998-04-13Henrik Grubbström (Grubba)  SWAP_IN_TRACE(_tmp); \
a7fef41997-09-03Per Hedbor  } while(0)
2d9cbe1997-09-08Fredrik Hübinette (Hubbe) #define SWAP_OUT_CURRENT_THREAD() \ do {\ struct thread_state *_tmp=(struct thread_state *)thread_id->storage; \ SWAP_OUT_THREAD(_tmp); \
a91ca01998-07-10Henrik Grubbström (Grubba)  THREADS_FPRINTF(1, (stderr, "SWAP_OUT_CURRENT_THREAD() %s:%d t:%08x\n", \ __FILE__, __LINE__, (unsigned int)_tmp->thread_id)) \
2d9cbe1997-09-08Fredrik Hübinette (Hubbe)  #define SWAP_IN_CURRENT_THREAD() \
a91ca01998-07-10Henrik Grubbström (Grubba)  THREADS_FPRINTF(1, (stderr, "SWAP_IN_CURRENT_THREAD() %s:%d ... t:%08x\n", \ __FILE__, __LINE__, (unsigned int)_tmp->thread_id)); \
2d9cbe1997-09-08Fredrik Hübinette (Hubbe)  SWAP_IN_THREAD(_tmp);\ } while(0)
e09b891998-01-06Mirar (Pontus Hagland) #if defined(DEBUG) && ! defined(DONT_HIDE_GLOBALS)
d818601997-10-21Henrik Grubbström (Grubba) /* Note that scalar types are used in place of pointers and vice versa * below. This is intended to cause compiler warnings/errors if * there is an attempt to use the global variables in an unsafe * environment. */ #define HIDE_GLOBAL_VARIABLES() do { \ int sp = 0, evaluator_stack = 0, mark_sp = 0, mark_stack = 0, fp = 0; \ void *evaluator_stack_malloced = NULL, *mark_stack_malloced = NULL; \
a35bbd1997-10-21Henrik Grubbström (Grubba)  int recoveries = 0, thread_id = 0; \ int error = 0, xalloc = 0, low_my_putchar = 0, low_my_binary_strcat = 0; \ int low_make_buf_space = 0, pop_n_elems = 0; \
a91ca01998-07-10Henrik Grubbström (Grubba)  int push_sp_mark = 0, pop_sp_mark = 0, threads_disabled = 1
d818601997-10-21Henrik Grubbström (Grubba) 
602f691997-10-25Henrik Grubbström (Grubba) /* Note that the semi-colon below is needed to add an empty statement * in case there is a label before the macro. */ #define REVEAL_GLOBAL_VARIABLES() ; } while(0)
d818601997-10-21Henrik Grubbström (Grubba) #else /* DEBUG */ #define HIDE_GLOBAL_VARIABLES() #define REVEAL_GLOBAL_VARIABLES() #endif /* DEBUG */
2d9cbe1997-09-08Fredrik Hübinette (Hubbe) 
602f691997-10-25Henrik Grubbström (Grubba) #define THREADS_ALLOW() do { \
a7fef41997-09-03Per Hedbor  struct thread_state *_tmp=(struct thread_state *)thread_id->storage; \
07513e1996-10-04Fredrik Hübinette (Hubbe)  if(num_threads > 1 && !threads_disabled) { \
a7fef41997-09-03Per Hedbor  SWAP_OUT_THREAD(_tmp); \
a91ca01998-07-10Henrik Grubbström (Grubba)  THREADS_FPRINTF(1, (stderr, "THREADS_ALLOW() %s:%d t:%08x(#%d)\n", \ __FILE__, __LINE__, \ (unsigned int)_tmp->thread_id, live_threads)); \
07513e1996-10-04Fredrik Hübinette (Hubbe)  mt_unlock(& interpreter_lock); \
602f691997-10-25Henrik Grubbström (Grubba)  } else {} \ HIDE_GLOBAL_VARIABLES()
07513e1996-10-04Fredrik Hübinette (Hubbe)  #define THREADS_DISALLOW() \
d818601997-10-21Henrik Grubbström (Grubba)  REVEAL_GLOBAL_VARIABLES(); \
a7fef41997-09-03Per Hedbor  if(_tmp->swapped) { \
07513e1996-10-04Fredrik Hübinette (Hubbe)  mt_lock(& interpreter_lock); \
a91ca01998-07-10Henrik Grubbström (Grubba)  THREADS_FPRINTF(1, (stderr, "THREADS_DISALLOW() %s:%d t:%08x(#%d)\n", \ __FILE__, __LINE__, \ (unsigned int)_tmp->thread_id, live_threads)); \
ef1e931998-03-26Henrik Grubbström (Grubba)  while (threads_disabled) { \
a91ca01998-07-10Henrik Grubbström (Grubba)  THREADS_FPRINTF(1, (stderr, \ "THREADS_DISALLOW(): Threads disabled\n")); \
72fdae1998-07-05Henrik Grubbström (Grubba)  co_wait(&threads_disabled_change, &interpreter_lock); \
ef1e931998-03-26Henrik Grubbström (Grubba)  } \
a7fef41997-09-03Per Hedbor  SWAP_IN_THREAD(_tmp);\
07513e1996-10-04Fredrik Hübinette (Hubbe)  } \ } while(0)
ef1e931998-03-26Henrik Grubbström (Grubba) #define THREADS_ALLOW_UID() do { \ struct thread_state *_tmp_uid=(struct thread_state *)thread_id->storage; \ if(num_threads > 1 && !threads_disabled) { \ SWAP_OUT_THREAD(_tmp_uid); \ live_threads++; \
a91ca01998-07-10Henrik Grubbström (Grubba)  THREADS_FPRINTF(1, (stderr, "THREADS_ALLOW_UID() %s:%d t:%08x(#%d)\n", \ __FILE__, __LINE__, \ (unsigned int)_tmp_uid->thread_id, live_threads)); \
ef1e931998-03-26Henrik Grubbström (Grubba)  mt_unlock(& interpreter_lock); \ } else {} \ HIDE_GLOBAL_VARIABLES() #define THREADS_DISALLOW_UID() \ REVEAL_GLOBAL_VARIABLES(); \ if(_tmp_uid->swapped) { \ mt_lock(& interpreter_lock); \ live_threads--; \
a91ca01998-07-10Henrik Grubbström (Grubba)  THREADS_FPRINTF(1, (stderr, \ "THREADS_DISALLOW_UID() %s:%d t:%08x(#%d)\n", \ __FILE__, __LINE__, \ (unsigned int)_tmp_uid->thread_id, live_threads)); \
72fdae1998-07-05Henrik Grubbström (Grubba)  co_broadcast(&live_threads_change); \
ef1e931998-03-26Henrik Grubbström (Grubba)  while (threads_disabled) { \
a91ca01998-07-10Henrik Grubbström (Grubba)  THREADS_FPRINTF(1, (stderr, "THREADS_DISALLOW_UID(): Wait...\n")); \
ef1e931998-03-26Henrik Grubbström (Grubba)  co_wait(&threads_disabled_change, &interpreter_lock); \ } \ SWAP_IN_THREAD(_tmp_uid);\ } \ } while(0)
07513e1996-10-04Fredrik Hübinette (Hubbe) /* Prototypes begin here */
6d1a5e1996-10-07Fredrik Hübinette (Hubbe) struct thread_starter;
07513e1996-10-04Fredrik Hübinette (Hubbe) void *new_thread_func(void * data); void f_thread_create(INT32 args);
dc7cc91998-01-14Fredrik Hübinette (Hubbe) void f_thread_set_concurrency(INT32 args);
a29e021996-10-15Fredrik Hübinette (Hubbe) void f_this_thread(INT32 args);
6d1a5e1996-10-07Fredrik Hübinette (Hubbe) struct mutex_storage; struct key_storage;
07513e1996-10-04Fredrik Hübinette (Hubbe) void f_mutex_lock(INT32 args); void f_mutex_trylock(INT32 args); void init_mutex_obj(struct object *o); void exit_mutex_obj(struct object *o); void init_mutex_key_obj(struct object *o); void exit_mutex_key_obj(struct object *o); void f_cond_wait(INT32 args); void f_cond_signal(INT32 args); void f_cond_broadcast(INT32 args); void init_cond_obj(struct object *o); void exit_cond_obj(struct object *o);
dc7cc91998-01-14Fredrik Hübinette (Hubbe) void f_thread_backtrace(INT32 args); void f_thread_id_status(INT32 args); void init_thread_obj(struct object *o); void exit_thread_obj(struct object *o);
865bd01998-03-08Per Hedbor void th_farm(void (*fun)(void *), void *);
dc7cc91998-01-14Fredrik Hübinette (Hubbe) void th_init(void);
a91ca01998-07-10Henrik Grubbström (Grubba) void low_th_init(void);
be478c1997-08-30Henrik Grubbström (Grubba) void th_cleanup(void);
4e799e1998-02-27Marcus Comstedt void thread_table_insert(struct object *o); void thread_table_delete(struct object *o); struct thread_state *thread_state_for_id(THREAD_T tid); struct object *thread_for_id(THREAD_T tid); void f_all_threads(INT32 args);
98759d1998-06-25Henrik Grubbström (Grubba) void init_threads_disable(struct object *o); void exit_threads_disable(struct object *o);
a91ca01998-07-10Henrik Grubbström (Grubba) void init_interleave_mutex(IMUTEX_T *im); void exit_interleave_mutex(IMUTEX_T *im);
07513e1996-10-04Fredrik Hübinette (Hubbe) /* Prototypes end here */ #else
97ffe41997-01-26Per Hedbor #define th_setconcurrency(X)
419ede1996-11-13Fredrik Hübinette (Hubbe) #define DEFINE_MUTEX(X)
a91ca01998-07-10Henrik Grubbström (Grubba) #define DEFINE_IMUTEX(X) #define init_interleave_mutex(X) #define LOCK_IMUTEX(X) #define UNLOCK_IMUTEX(X)
0516881996-10-04David Hedbor #define mt_init(X) #define mt_lock(X) #define mt_unlock(X)
419ede1996-11-13Fredrik Hübinette (Hubbe) #define mt_destroy(X)
07513e1996-10-04Fredrik Hübinette (Hubbe) #define THREADS_ALLOW() #define THREADS_DISALLOW()
a1ad421998-03-27Fredrik Hübinette (Hubbe) #define THREADS_ALLOW_UID() #define THREADS_DISALLOW_UID()
43306a1997-10-21Henrik Grubbström (Grubba) #define HIDE_GLOBAL_VARIABLES() #define REVEAL_GLOBAL_VARIABLES()
07513e1996-10-04Fredrik Hübinette (Hubbe) #define th_init()
a91ca01998-07-10Henrik Grubbström (Grubba) #define low_th_init()
6d1a5e1996-10-07Fredrik Hübinette (Hubbe) #define th_cleanup()
07513e1996-10-04Fredrik Hübinette (Hubbe) #define th_init_programs()
fc33451997-10-02Fredrik Hübinette (Hubbe) #define th_self() ((void*)0)
2bfcfe1998-03-27Fredrik Hübinette (Hubbe) #define co_signal(X)
a872b21998-04-30Fredrik Hübinette (Hubbe) #define co_broadcast(X)
98759d1998-06-25Henrik Grubbström (Grubba)  #define init_threads_disable(X) #define exit_threads_disable(X)
5377b91997-02-01Henrik Grubbström (Grubba) #endif /* _REENTRANT */
07513e1996-10-04Fredrik Hübinette (Hubbe) 
dc7cc91998-01-14Fredrik Hübinette (Hubbe) #ifdef __NT__ #ifndef DEBUG #define CheckValidHandle(X) 0 #else void CheckValidHandle(HANDLE h); #endif #endif
0516881996-10-04David Hedbor 
07513e1996-10-04Fredrik Hübinette (Hubbe) extern int threads_disabled;
5377b91997-02-01Henrik Grubbström (Grubba)  #endif /* THREADS_H */