on ace080c help sign in
Idris-dev/support/threads.c
116 lines 2.4 kB history raw
1#include <closure.h>
2#include "threads.h"
4// Threads and locks
6typedef struct {
7 pthread_mutex_t m_id;
8} IdrisMutex;
10typedef struct {
11 pthread_t t_id;
12} IdrisThread;
14IdrisMutex** idris_ms = NULL;
15int idris_mutexes = 0;
17int idris_newLock()
19 pthread_mutex_t m;
21 pthread_mutex_init(&m, NULL);
22 IdrisMutex* newm = EMALLOC(sizeof(IdrisMutex));
23 newm->m_id = m;
25 // Increase space for the mutexes
26 if (idris_ms==NULL) {
27 idris_ms = (IdrisMutex**)EMALLOC(sizeof(IdrisMutex*));
28 idris_mutexes=1;
29 } else {
30 idris_ms = (IdrisMutex**)(EREALLOC(idris_ms, sizeof(IdrisMutex*)*(idris_mutexes+1)));
31 idris_mutexes++;
32 }
34 idris_ms[idris_mutexes-1] = newm;
35 return idris_mutexes-1;
38void idris_doLock(int lock)
40 pthread_mutex_lock(&(idris_ms[lock]->m_id));
43void idris_doUnlock(int lock)
45 pthread_mutex_unlock(&(idris_ms[lock]->m_id));
48struct idris_threadinfo {
49 void* proc;
50 void* result;
51};
53void* idris_runThread(void* th_in) {
54 printf("IN THREAD\n");
55 struct idris_threadinfo* th = (struct idris_threadinfo*)th_in;
56 printf("using %d\n", th_in);
57 void* v = DO_EVAL(th_in, 1);
58 th->result = v;
59 return v;
62void idris_doFork(void* proc)
64 printf("FORKING!\n");
65 pthread_t* t = malloc(sizeof(pthread_t));
66 struct idris_threadinfo th;
67 printf("in %d\n", proc);
68 th.proc = proc;
69 th.result = NULL;
70 pthread_create(t, NULL, idris_runThread, proc);
71 printf("FORKED!\n");
74void* idris_doWithin(int limit, void* proc, void* doOnFail)
76 pthread_t* t = EMALLOC(sizeof(pthread_t));
77// printf("CREATING THREAD %d\n", t);
78 struct idris_threadinfo th;
79 th.proc = proc;
80 th.result = NULL;
82 struct timeval tv;
83 gettimeofday(&tv, NULL);
84 int tnow, tthen = do_utime();
86 pthread_create(t, NULL, idris_runThread, &th);
87// printf("tthen %d\n", tthen);
89 void* ans;
91 do
92 {
93 // If the answer has been updated, we're done.
94 if (th.result!=NULL) {
95 pthread_join(*t, &ans);
96 return ans;
97 }
98 gettimeofday(&tv, NULL);
99 tnow = idris_utime();
100 usleep(100);
101// printf("tnow %d\n", tnow);
102 }
103 while(tnow<(tthen+(limit*1000)));
104 pthread_cancel(*t);
105 return DO_EVAL(doOnFail,1);
108int idris_utime() {
109 struct timeval tv;
110 gettimeofday(&tv, NULL);
112 static int start=0;
113 if (start==0) { start = tv.tv_sec; }
115 return 1000000*(tv.tv_sec - start)+tv.tv_usec;