Interpreter - Incremental API changes
[rune.git] / libi / thread.c
1 /*
2  * THREAD.C
3  *
4  * (c)Copyright 1993-2014, Matthew Dillon, All Rights Reserved.  See the  
5  *    COPYRIGHT file at the base of the distribution.
6  */
7
8 #include "defs.h"
9
10 typedef struct ThreadClass {
11         int32_t tc_Wid;
12 } ThreadClass;
13
14 typedef struct ThreadWait {
15         List    tw_List;
16 } ThreadWait;
17
18 void *
19 isys_waitThreads(runctx_p ct __unused, Exp *exp __unused,
20                  RefStor **prs __unused)
21 {
22         IFrame frame;
23
24         saveIFrame(&frame);
25         threadWaitTerminate();
26         restoreIFrame(&frame);
27         return(NULL);
28 }
29
30 void *
31 isys_wakeup(runctx_p ct, Exp *exp, RefStor **prs __unused)
32 {
33         RefStor *rs = NULL;
34         struct {
35                 LValueStor s;
36         } *rhs;
37         ThreadClass *tc;
38         ThreadWait *tw;
39
40         rhs = exp->ex_Rhs->ex_Func(ct, exp->ex_Rhs, &rs);
41         tc = rhs->s.s_Addr;
42         if ((tw = hashLookup(tc->tc_Wid, HASH_THREADWAIT)) == NULL) {
43                 fprintf(stderr,
44                         "unable to locate thread rendezvous %d\n",
45                         tc->tc_Wid);
46                 dassert_exp(exp, 0);
47         }
48         threadWakeupAll(&tw->tw_List);
49         relsRefStor(rs);
50         return(NULL);
51 }
52
53 void *
54 isys_sleep(runctx_p ct, Exp *exp, RefStor **prs __unused)
55 {
56         RefStor *rs = NULL;
57         struct {
58                 LValueStor s;
59                 int32_t    ms;
60         } *rhs;
61         ThreadClass *tc;
62         ThreadWait *tw;
63         IFrame frame;
64
65         rhs = exp->ex_Rhs->ex_Func(ct, exp->ex_Rhs, &rs);
66         tc = rhs->s.s_Addr;
67         if ((tw = hashLookup(tc->tc_Wid, HASH_THREADWAIT)) == NULL) {
68                 fprintf(stderr,
69                         "unable to locate thread rendezvous %d\n",
70                         tc->tc_Wid);
71                 dassert_exp(exp, 0);
72         }
73         saveIFrame(&frame);
74         if (rhs->ms > 0)
75                 threadSleep(&tw->tw_List, rhs->ms);
76         else
77                 threadStop(&tw->tw_List, 0);
78         restoreIFrame(&frame);
79         relsRefStor(rs);
80         return(NULL);
81 }
82
83 void
84 ic_thread_construct(Declaration *d, LValueStor *lvs)
85 {
86         ThreadClass *tc;
87         ThreadWait *tw;
88
89         tc = lvs->s_Addr;
90         if ((tw = hashLookup(tc->tc_Wid, HASH_THREADWAIT)) != NULL) {
91                 fprintf(stderr,
92                         "thread rendezvous %d already constructed!\n",
93                         tc->tc_Wid);
94                 dassert_decl(d, 0);
95         }
96         tw = zalloc(sizeof(ThreadWait));
97         initList(&tw->tw_List);
98         tc->tc_Wid = hashEnter(tw, HASH_THREADWAIT, -1);
99 }
100
101 void
102 ic_thread_destruct(Declaration *d, LValueStor *lvs)
103 {
104         ThreadClass *tc;
105         ThreadWait *tw;
106
107         tc = lvs->s_Addr;
108         if ((tw = hashLookup(tc->tc_Wid, HASH_THREADWAIT)) == NULL) {
109                 fprintf(stderr,
110                         "Unable to locate thread rendezvous to destruct: %d\n",
111                         tc->tc_Wid);
112                 dassert_decl(d, 0);
113         }
114         tc->tc_Wid = 0;
115         threadWakeupAll(&tw->tw_List);
116         zfree(tw, sizeof(ThreadWait));
117 }