more code
[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 #ifdef THREADS
21   struct ___Object___ *ll=pthread_getspecific(threadlocks);
22   while(ll!=NULL) {
23     struct ___Object___ *llnext=ll->___nextlockobject___;    
24     ll->___nextlockobject___=NULL;
25     ll->___prevlockobject___=NULL;
26     ll->lockcount=0;
27     ll->tid=0; //unlock it
28     ll=llnext;
29   }
30   pthread_mutex_lock(&objlock);//wake everyone up
31   pthread_cond_broadcast(&objcond);
32   pthread_mutex_unlock(&objlock);
33 #endif
34   pthread_mutex_lock(&gclistlock);
35   threadcount--;
36   pthread_cond_signal(&gccond);
37   pthread_mutex_unlock(&gclistlock);
38   pthread_exit(NULL);
39 }
40
41 void threadhandler(int sig, siginfo_t *info, void *uap) {
42 #ifdef DEBUG
43   printf("sig=%d\n",sig);
44   printf("signal\n");
45 #endif
46   threadexit();
47 }
48
49 void initializethreads() {
50   struct sigaction sig;
51   threadcount=1;
52   pthread_mutex_init(&gclock, NULL);
53   pthread_mutex_init(&gclistlock, NULL);
54   pthread_cond_init(&gccond, NULL);
55   pthread_mutex_init(&objlock,NULL);
56   pthread_cond_init(&objcond,NULL);
57   pthread_key_create(&threadlocks, NULL);
58   processOptions();
59   initializeexithandler();
60
61   sig.sa_sigaction=&threadhandler;
62   sig.sa_flags=SA_SIGINFO;
63   sigemptyset(&sig.sa_mask);
64
65   /* Catch bus errors, segmentation faults, and floating point exceptions*/
66   sigaction(SIGBUS,&sig,0);
67   sigaction(SIGSEGV,&sig,0);
68   sigaction(SIGFPE,&sig,0);
69   signal(SIGPIPE, SIG_IGN);
70 }
71
72 #ifdef THREADS
73 void initthread(struct ___Thread___ * ___this___) {
74 #ifdef PRECISE_GC
75   struct ___Thread______staticStart____L___Thread____params p={1, NULL, ___this___};
76   ___Thread______staticStart____L___Thread___(&p);
77 #else
78   ___Thread______staticStart____L___Thread___(___this___);
79 #endif
80   pthread_mutex_lock(&gclistlock);
81   threadcount--;
82   pthread_cond_signal(&gccond);
83   pthread_mutex_unlock(&gclistlock);
84 }
85 #endif
86
87 void CALL11(___Thread______sleep____J, long long ___millis___, long long ___millis___) {
88 #ifdef THREADS
89 #ifdef PRECISE_GC
90   struct listitem *tmp=stopforgc((struct garbagelist *)___params___);
91 #endif
92 #endif
93   usleep(___millis___);  
94 #ifdef THREADS
95 #ifdef PRECISE_GC
96   restartaftergc(tmp);
97 #endif
98 #endif
99 }
100
101 #ifdef THREADS
102 void CALL01(___Thread______nativeCreate____, struct ___Thread___ * ___this___) {
103   pthread_t thread;
104   int retval;
105   pthread_attr_t nattr;
106
107   pthread_mutex_lock(&gclistlock);
108   threadcount++;
109   pthread_mutex_unlock(&gclistlock);
110   pthread_attr_init(&nattr);
111   pthread_attr_setdetachstate(&nattr, PTHREAD_CREATE_DETACHED);
112   
113   do {
114     retval=pthread_create(&thread, &nattr, (void * (*)(void *)) &initthread, VAR(___this___));
115     if (retval!=0)
116       usleep(1);
117   } while(retval!=0);
118
119   pthread_attr_destroy(&nattr);
120 }
121 #endif
122
123 #ifdef DSTM
124 void CALL12(___Thread______start____I, int ___mid___, struct ___Thread___ * ___this___, int ___mid___) {
125   startRemoteThread((unsigned int)VAR(___this___), ___mid___);
126 }
127 #endif
128
129 #ifdef DSTM
130 void initDSMthread(int *ptr) {
131   int oid=ptr[0];
132   int type=ptr[1];
133   free(ptr);
134 #ifdef PRECISE_GC
135   int p[]={1, 0 /* NULL */, oid};
136   ((void (*)(void *))virtualtable[type*MAXCOUNT+RUNMETHOD])(p);
137 #else
138   ((void (*)(void *))virtualtable[type*MAXCOUNT+RUNMETHOD])(oid);
139 #endif
140   pthread_mutex_lock(&gclistlock);
141   threadcount--;
142   pthread_cond_signal(&gccond);
143   pthread_mutex_unlock(&gclistlock);
144 }
145
146 void startDSMthread(int oid, int objType) {
147   pthread_t thread;
148   int retval;
149   pthread_attr_t nattr;
150
151   pthread_mutex_lock(&gclistlock);
152   threadcount++;
153   pthread_mutex_unlock(&gclistlock);
154   pthread_attr_init(&nattr);
155   pthread_attr_setdetachstate(&nattr, PTHREAD_CREATE_DETACHED);
156   int * ptr=malloc(sizeof(int)*2);
157   ptr[0]=oid;
158   ptr[1]=objType;
159   do {
160     retval=pthread_create(&thread, &nattr, (void * (*)(void *)) &initDSMthread,  ptr);
161     if (retval!=0)
162       usleep(1);
163   } while(retval!=0);
164
165   pthread_attr_destroy(&nattr);
166 }
167
168 #endif