forked from idris-lang/Idris-dev
-
Notifications
You must be signed in to change notification settings - Fork 0
/
threads.c
116 lines (95 loc) · 2.35 KB
/
threads.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include <closure.h>
#include "threads.h"
// Threads and locks
typedef struct {
pthread_mutex_t m_id;
} IdrisMutex;
typedef struct {
pthread_t t_id;
} IdrisThread;
IdrisMutex** idris_ms = NULL;
int idris_mutexes = 0;
int idris_newLock()
{
pthread_mutex_t m;
pthread_mutex_init(&m, NULL);
IdrisMutex* newm = EMALLOC(sizeof(IdrisMutex));
newm->m_id = m;
// Increase space for the mutexes
if (idris_ms==NULL) {
idris_ms = (IdrisMutex**)EMALLOC(sizeof(IdrisMutex*));
idris_mutexes=1;
} else {
idris_ms = (IdrisMutex**)(EREALLOC(idris_ms, sizeof(IdrisMutex*)*(idris_mutexes+1)));
idris_mutexes++;
}
idris_ms[idris_mutexes-1] = newm;
return idris_mutexes-1;
}
void idris_doLock(int lock)
{
pthread_mutex_lock(&(idris_ms[lock]->m_id));
}
void idris_doUnlock(int lock)
{
pthread_mutex_unlock(&(idris_ms[lock]->m_id));
}
struct idris_threadinfo {
void* proc;
void* result;
};
void* idris_runThread(void* th_in) {
printf("IN THREAD\n");
struct idris_threadinfo* th = (struct idris_threadinfo*)th_in;
printf("using %d\n", th_in);
void* v = DO_EVAL(th_in, 1);
th->result = v;
return v;
}
void idris_doFork(void* proc)
{
printf("FORKING!\n");
pthread_t* t = malloc(sizeof(pthread_t));
struct idris_threadinfo th;
printf("in %d\n", proc);
th.proc = proc;
th.result = NULL;
pthread_create(t, NULL, idris_runThread, proc);
printf("FORKED!\n");
}
void* idris_doWithin(int limit, void* proc, void* doOnFail)
{
pthread_t* t = EMALLOC(sizeof(pthread_t));
// printf("CREATING THREAD %d\n", t);
struct idris_threadinfo th;
th.proc = proc;
th.result = NULL;
struct timeval tv;
gettimeofday(&tv, NULL);
int tnow, tthen = do_utime();
pthread_create(t, NULL, idris_runThread, &th);
// printf("tthen %d\n", tthen);
void* ans;
do
{
// If the answer has been updated, we're done.
if (th.result!=NULL) {
pthread_join(*t, &ans);
return ans;
}
gettimeofday(&tv, NULL);
tnow = idris_utime();
usleep(100);
// printf("tnow %d\n", tnow);
}
while(tnow<(tthen+(limit*1000)));
pthread_cancel(*t);
return DO_EVAL(doOnFail,1);
}
int idris_utime() {
struct timeval tv;
gettimeofday(&tv, NULL);
static int start=0;
if (start==0) { start = tv.tv_sec; }
return 1000000*(tv.tv_sec - start)+tv.tv_usec;
}