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