-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtinycsp.h
161 lines (131 loc) · 3.61 KB
/
tinycsp.h
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#ifndef __TINYCSPH
#define __TINYCSPH
// #define DEBUG_FLAG
/* ***************************************************************** */
/* CONSTANTS */
#include "list.h"
#define true 1
#define false 0
#ifdef DEBUG_FLAG
#define DEBUG(exp) exp
#else
#define DEBUG(exp)
#endif
/* ***************************************************************** */
/* TYPES */
typedef struct channel_record {
int value;
unsigned int read_ok : 1;
} channel;
typedef struct process_record {
struct list_elem e;
char name;
unsigned int running : 1;
void *label;
} process;
// Matt's cheap O(1) deadlock detection
// We just have to go through the list once.
int deadlocked;
/* ***************************************************************** */
/* CHANNEL HELPERS */
#define PASTE0(x, y) x ## y
#define PASTE(x, y) PASTE0(x,y)
#define CHAN_INIT(ch) \
do { \
ch.value = -1; \
ch.read_ok = 0; \
} while (0);
#define CURRENT_LABEL(tag) \
current_process->label = &&tag; \
DEBUG(fprintf(stdout, " - " #tag "\n");) \
#define SET_LABEL(lab) lab.label = &&LABEL_##lab;
#define ADD_PROCESS(structure, tag, state) \
structure.label = &&LABEL_##structure; \
structure.name = tag; \
structure.running = state; \
add_to_back(&structure);
#define WRITE(ch, v) \
do { \
PASTE(WRITE_, __LINE__): \
CURRENT_LABEL(PASTE(WRITE_, __LINE__)); \
DEBUG(fprintf (stdout, "\nW " #ch ".read_ok: %d\n", ch.read_ok);) \
if (!ch.read_ok) { \
ch.value = v; \
ch.read_ok = 1; \
DEBUG(fprintf(stdout, "\t" #ch " <- %d\n", v);) \
deadlocked = false; \
CURRENT_LABEL(PASTE(DONE_WRITE_, __LINE__)); \
} \
SCHEDULE_NEXT(); \
} while (0); \
PASTE(DONE_WRITE_, __LINE__):
#define NAMED_WRITE(label, ch, v) \
do { \
label: \
CURRENT_LABEL(label); \
DEBUG(fprintf (stdout, "\nW " #ch ".read_ok: %d\n", ch.read_ok);) \
if (!ch.read_ok) { \
ch.value = v; \
ch.read_ok = 1; \
DEBUG(fprintf(stdout, "\t" #ch " <- %d\n", v);) \
deadlocked = false; \
CURRENT_LABEL(PASTE(DONE_WRITE_, label)); \
} \
SCHEDULE_NEXT(); \
} while (0); \
PASTE(DONE_WRITE_, label):
#define READ(ch, v) \
do { \
PASTE(READ_, __LINE__): \
CURRENT_LABEL(PASTE(READ_, __LINE__)); \
DEBUG(fprintf (stdout, "\nR " #ch ".read_ok: %d\n", ch.read_ok);) \
if (ch.read_ok) { \
ch.read_ok = 0; \
v = ch.value; \
DEBUG(fprintf(stdout, "\t" #ch " -> " #v "\n");) \
deadlocked = false; \
} else { \
SCHEDULE_NEXT(); \
} \
} while (0);
#define GET_PARAM(type, loc) (type (current_process->params[loc]))
#define SCHEDULE_NEXT() \
do { \
current_process = get_next_process(current_process); \
DEBUG(show_queue(current_process);); \
DEBUG(sleep(1);); \
goto *(current_process->label); \
} while (0);
#define SCHEDULE(proc) \
do { \
DEBUG(retain(stdout, "SCHEDULING " #proc "\n");) \
goto *(proc.label); \
} while (0);
#define PROC(label)\
LABEL_##label: \
current_process = &label; \
DEBUG(printf ("Starting " #label "\n");) \
do {
#define PROCEND(lab) \
remove_from_queue(&lab); \
SCHEDULE_NEXT(); \
} while (0);
#define FOREVER() \
while (true) {
// PASTE(WHILE, __LINE__): \
// CURRENT_LABEL(PASTE(WHILE, __LINE__));
#define ENDFOREVER() }
// deadlocked = false; \
// SCHEDULE_NEXT(); \
// }
/* ***************************************************************** */
/* QUEUE HLPERS */
void remove_from_queue (process *p);
void add_to_front (process *p);
void add_to_back (process *p);
void show_queue (process *p);
process * get_next_process (process *p);
process * first (void);
// Dirty tricks on the AVR
// http://tinyurl.com/olmtvyo
#endif /* __TINYCSPH */