random bug fixes & sleep call
[IRC.git] / Robust / src / Runtime / thread.c
1 #include "runtime.h"
2 #include <sys/types.h>
3 #include <unistd.h>
4 #include <errno.h>
5 #include <stdlib.h>
6 #include "thread.h"
7 #include "option.h"
8 #include <signal.h>
9
10 #include <stdio.h>
11 int threadcount;
12 pthread_mutex_t gclock;
13 pthread_mutex_t gclistlock;
14 pthread_cond_t gccond;
15 pthread_mutex_t objlock;
16 pthread_cond_t objcond;
17 pthread_key_t threadlocks;
18
19 void threadexit() {
20   struct ___Object___ *ll=pthread_getspecific(threadlocks);
21   while(ll!=NULL) {
22     struct ___Object___ *llnext=ll->___nextlockobject___;    
23     ll->___nextlockobject___=NULL;
24     ll->___prevlockobject___=NULL;
25     ll->lockcount=0;
26     ll->tid=0; //unlock it
27     ll=llnext;
28   }
29   pthread_mutex_lock(&objlock);//wake everyone up
30   pthread_cond_broadcast(&objcond);
31   pthread_mutex_unlock(&objlock);
32   pthread_mutex_lock(&gclistlock);
33   threadcount--;
34   pthread_cond_signal(&gccond);
35   pthread_mutex_unlock(&gclistlock);
36   pthread_exit(NULL);
37 }
38
39 void threadhandler(int sig, siginfo_t *info, void *uap) {
40 #ifdef DEBUG
41   printf("sig=%d\n",sig);
42   printf("signal\n");
43 #endif
44   threadexit();
45 }
46
47 void initializethreads() {
48   struct sigaction sig;
49   threadcount=1;
50   pthread_mutex_init(&gclock, NULL);
51   pthread_mutex_init(&gclistlock, NULL);
52   pthread_cond_init(&gccond, NULL);
53   pthread_mutex_init(&objlock,NULL);
54   pthread_cond_init(&objcond,NULL);
55   pthread_key_create(&threadlocks, NULL);
56   processOptions();
57
58   sig.sa_sigaction=&threadhandler;
59   sig.sa_flags=SA_SIGINFO;
60   sigemptyset(&sig.sa_mask);
61
62   /* Catch bus errors, segmentation faults, and floating point exceptions*/
63   sigaction(SIGBUS,&sig,0);
64   sigaction(SIGSEGV,&sig,0);
65   sigaction(SIGFPE,&sig,0);
66 }
67
68 void initthread(struct ___Thread___ * ___this___) {
69 #ifdef PRECISE_GC
70   struct ___Thread______staticStart____L___Thread____params p={1, NULL, ___this___};
71   ___Thread______staticStart____L___Thread___(&p);
72 #else
73   ___Thread______staticStart____L___Thread___(___this___);
74 #endif
75   pthread_mutex_lock(&gclistlock);
76   threadcount--;
77   pthread_cond_signal(&gccond);
78   pthread_mutex_unlock(&gclistlock);
79 }
80
81 void CALL11(___Thread______sleep____J, long long ___millis___, long long ___millis___) {
82 #ifdef THREADS
83 #ifdef PRECISE_GC
84   struct listitem *tmp=stopforgc((struct garbagelist *)___params___);
85 #endif
86 #endif
87   usleep(___millis___);  
88 #ifdef THREADS
89 #ifdef PRECISE_GC
90   restartaftergc(tmp);
91 #endif
92 #endif
93 }
94
95 void CALL01(___Thread______nativeCreate____, struct ___Thread___ * ___this___) {
96   pthread_t thread;
97   int retval;
98   pthread_attr_t nattr;
99
100   pthread_mutex_lock(&gclistlock);
101   threadcount++;
102   pthread_mutex_unlock(&gclistlock);
103   pthread_attr_init(&nattr);
104   pthread_attr_setdetachstate(&nattr, PTHREAD_CREATE_DETACHED);
105   
106   do {
107     retval=pthread_create(&thread, &nattr, (void * (*)(void *)) &initthread, VAR(___this___));
108     if (retval!=0)
109       usleep(1);
110   } while(retval!=0);
111
112   pthread_attr_destroy(&nattr);
113 }