86
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1 #include <stdio.h>
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
2 #include <unistd.h>
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
3
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
4 #include "context.h"
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
5 #include "origin_cs.h"
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
6
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
7 extern __code initContext(struct Context* context);
|
90
|
8 extern void allocator(struct Context* context);
|
86
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
9
|
90
|
10 int length;
|
|
11 int* array_ptr;
|
|
12
|
|
13 void print_queue(struct Element* element) {
|
|
14 while (element) {
|
|
15 printf("%d\n", element->task->key);
|
|
16 element = element->next;
|
|
17 }
|
|
18 }
|
|
19
|
|
20 void print_tree(struct Node* node) {
|
|
21 if (node != 0) {
|
|
22 printf("%d\n", node->value->array.index);
|
|
23 print_tree(node->left);
|
|
24 print_tree(node->right);
|
|
25 }
|
|
26 }
|
86
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
27
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
28 __code code1(struct Context* context) {
|
91
|
29 puts("queue");
|
|
30 print_queue(context->data[ActiveQueue]->queue.first);
|
|
31 puts("tree");
|
|
32 print_tree(context->data[Tree]->tree.root);
|
92
|
33 puts("result");
|
90
|
34
|
92
|
35 goto meta(context, CreateWorker);
|
86
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
36 }
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
37
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
38 __code code1_stub(struct Context* context) {
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
39 goto code1(context);
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
40 }
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
41
|
92
|
42 __code code2(struct Context* context, struct Array* array, struct LoopCounter* loopCounter) {
|
|
43 int i = loopCounter->i;
|
|
44
|
|
45 if (i < length) {
|
|
46 printf("%d\n", array->array[i]);
|
|
47 loopCounter->i++;
|
|
48
|
|
49 goto meta(context, Code2);
|
|
50 }
|
|
51
|
|
52 goto meta(context, Exit);
|
|
53 }
|
|
54
|
|
55 __code code2_stub(struct Context* context) {
|
|
56 goto code2(context, &context->data[Node]->node.value->array, &context->data[LoopCounter]->loopCounter);
|
|
57 }
|
|
58
|
90
|
59 __code createData1(struct Context* context, struct Allocate* allocate, struct LoopCounter* loopCounter) {
|
|
60 int i = loopCounter->i;
|
|
61
|
|
62 if (i < length) {
|
|
63 allocate->size = sizeof(struct Array);
|
|
64 allocator(context);
|
|
65
|
|
66 goto meta(context, CreateData2);
|
|
67 }
|
|
68
|
92
|
69 loopCounter->i = 0;
|
90
|
70 goto meta(context, Code1);
|
|
71 }
|
|
72
|
|
73 __code createData1_stub(struct Context* context) {
|
|
74 goto createData1(context, &context->data[Allocate]->allocate, &context->data[LoopCounter]->loopCounter);
|
|
75 }
|
|
76
|
|
77 __code createData2(struct Context* context, struct LoopCounter* loopCounter, struct Array* array, struct Node* node) {
|
|
78 int i = loopCounter->i;
|
|
79
|
|
80 array->index = i;
|
|
81 array->array = array_ptr;
|
|
82
|
|
83 node->key = i;
|
|
84 node->value = (union Data*)array;
|
|
85
|
|
86 context->next = CreateTask1;
|
|
87
|
|
88 goto meta(context, PutTree);
|
|
89 }
|
|
90
|
|
91 __code createData2_stub(struct Context* context) {
|
|
92 goto createData2(context,
|
|
93 &context->data[LoopCounter]->loopCounter,
|
|
94 &context->data[context->dataNum]->array,
|
|
95 &context->data[Node]->node);
|
|
96 }
|
|
97
|
|
98 __code createTask1(struct Context* context, struct Allocate* allocate) {
|
|
99 allocate->size = sizeof(struct Task);
|
|
100 allocator(context);
|
|
101
|
|
102 goto meta(context, CreateTask2);
|
|
103 }
|
|
104
|
|
105 __code createTask1_stub(struct Context* context) {
|
|
106 goto createTask1(context, &context->data[Allocate]->allocate);
|
|
107 }
|
|
108
|
|
109 __code createTask2(struct Context* context, struct LoopCounter* loopCounter, struct Task* task, struct Element* element) {
|
|
110 int i = loopCounter->i;
|
|
111
|
92
|
112 task->code = Twice;
|
90
|
113 task->key = i;
|
|
114
|
|
115 element->task = task;
|
|
116
|
|
117 context->next = CreateData1;
|
|
118 loopCounter->i++;
|
|
119
|
|
120 goto meta(context, PutQueue1);
|
|
121 }
|
|
122
|
|
123 __code createTask2_stub(struct Context* context) {
|
|
124 goto createTask2(context,
|
|
125 &context->data[LoopCounter]->loopCounter,
|
|
126 &context->data[context->dataNum]->task,
|
|
127 &context->data[Element]->element);
|
|
128 }
|
|
129
|
|
130 __code putQueue1(struct Context* context, struct Allocate* allocate) {
|
|
131 allocate->size = sizeof(struct Element);
|
|
132 allocator(context);
|
|
133
|
|
134 goto meta(context, PutQueue2);
|
|
135 }
|
|
136
|
|
137 __code putQueue1_stub(struct Context* context) {
|
|
138 goto putQueue1(context, &context->data[Allocate]->allocate);
|
|
139 }
|
|
140
|
|
141 __code putQueue2(struct Context* context, struct Element* new_element, struct Element* element, struct Queue* queue) {
|
|
142 new_element->task = element->task;
|
|
143
|
|
144 if (queue->first)
|
|
145 goto meta(context, PutQueue3);
|
|
146 else
|
|
147 goto meta(context, PutQueue4);
|
|
148 }
|
|
149
|
|
150 __code putQueue2_stub(struct Context* context) {
|
|
151 goto putQueue2(context,
|
|
152 &context->data[context->dataNum]->element,
|
|
153 &context->data[Element]->element,
|
|
154 &context->data[ActiveQueue]->queue);
|
|
155 }
|
|
156
|
|
157 __code putQueue3(struct Context* context, struct Queue* queue, struct Element* new_element) {
|
|
158 struct Element* last = queue->last;
|
|
159
|
|
160 if (__sync_bool_compare_and_swap(&queue->last, last, new_element)) {
|
|
161 last->next = new_element;
|
|
162 queue->count++;
|
|
163
|
|
164 goto meta(context, context->next);
|
|
165 } else {
|
|
166 goto meta(context, PutQueue3);
|
|
167 }
|
|
168 }
|
|
169
|
|
170 __code putQueue3_stub(struct Context* context) {
|
|
171 goto putQueue3(context, &context->data[ActiveQueue]->queue, &context->data[context->dataNum]->element);
|
|
172 }
|
|
173
|
|
174 __code putQueue4(struct Context* context, struct Queue* queue, struct Element* new_element) {
|
|
175 if (__sync_bool_compare_and_swap(&queue->first, 0, new_element)) {
|
|
176 queue->last = new_element;
|
|
177 queue->count++;
|
|
178
|
|
179 goto meta(context, context->next);
|
|
180 } else {
|
|
181 goto meta(context, PutQueue3);
|
|
182 }
|
|
183 }
|
|
184
|
|
185 __code putQueue4_stub(struct Context* context) {
|
|
186 goto putQueue4(context, &context->data[ActiveQueue]->queue, &context->data[context->dataNum]->element);
|
|
187 }
|
|
188
|
92
|
189 __code getQueue(struct Context* context, struct Queue* queue, struct Node* node) {
|
91
|
190 if (queue->count == 0)
|
|
191 return;
|
|
192
|
|
193 struct Element* first = queue->first;
|
|
194 if (__sync_bool_compare_and_swap(&queue->first, first, first->next)) {
|
|
195 queue->count--;
|
|
196
|
|
197 context->next = GetQueue;
|
|
198 stack_push(context->code_stack, &context->next);
|
|
199
|
|
200 context->next = first->task->code;
|
92
|
201 node->key = first->task->key;
|
91
|
202
|
92
|
203 goto meta(context, Get);
|
91
|
204 } else {
|
|
205 goto meta(context, GetQueue);
|
|
206 }
|
|
207 }
|
|
208
|
|
209 __code getQueue_stub(struct Context* context) {
|
92
|
210 goto getQueue(context, &context->data[ActiveQueue]->queue, &context->data[Node]->node);
|
91
|
211 }
|
|
212
|
86
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
213 __code createWorker(struct Context* context, struct LoopCounter* loopCounter, struct Worker* worker) {
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
214 int i = loopCounter->i;
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
215
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
216 if (i < worker->num) {
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
217 struct Context* worker_context = &worker->contexts[i];
|
91
|
218 worker_context->next = GetQueue;
|
|
219 worker_context->data[Tree] = context->data[Tree];
|
|
220 worker_context->data[ActiveQueue] = context->data[ActiveQueue];
|
86
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
221 pthread_create(&worker_context->thread, NULL, (void*)&start_code, worker_context);
|
92
|
222 worker_context->thread_num = i;
|
86
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
223 loopCounter->i++;
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
224
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
225 goto meta(context, CreateWorker);
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
226 }
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
227
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
228 loopCounter->i = 0;
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
229 goto meta(context, TaskManager);
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
230 }
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
231
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
232 __code createWorker_stub(struct Context* context) {
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
233 goto createWorker(context, &context->data[LoopCounter]->loopCounter, &context->data[Worker]->worker);
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
234 }
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
235
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
236 __code taskManager(struct Context* context, struct LoopCounter* loopCounter, struct Worker* worker) {
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
237 int i = loopCounter->i;
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
238
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
239 if (i < worker->num) {
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
240 pthread_join(worker->contexts[i].thread, NULL);
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
241 loopCounter->i++;
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
242
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
243 goto meta(context, TaskManager);
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
244 }
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
245
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
246 loopCounter->i = 0;
|
92
|
247 goto meta(context, Code2);
|
86
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
248 }
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
249
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
250 __code taskManager_stub(struct Context* context) {
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
251 goto taskManager(context, &context->data[LoopCounter]->loopCounter, &context->data[Worker]->worker);
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
252 }
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
253
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
254 int main(int argc, char** argv) {
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
255 int cpu_num = (int)atoi(argv[1]);
|
90
|
256 length = (int)atoi(argv[2]);
|
|
257
|
|
258 array_ptr = (int*)malloc(sizeof(int)*length);
|
|
259
|
|
260 for(int i=0; i<length; i++)
|
|
261 array_ptr[i]=i;
|
86
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
262
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
263 struct Context* main_context = (struct Context*)malloc(sizeof(struct Context));
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
264 initContext(main_context);
|
90
|
265 //main_context->next = CreateWorker;
|
|
266 main_context->next = CreateData1;
|
86
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
267
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
268 struct Context* worker_contexts = (struct Context*)malloc(sizeof(struct Context)*cpu_num);
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
269
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
270 struct Worker* worker = &main_context->data[Worker]->worker;
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
271 worker->num = cpu_num;
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
272 worker->contexts = worker_contexts;
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
273
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
274 for (int i = 0;i<cpu_num;i++)
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
275 initContext(&worker_contexts[i]);
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
276
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
277 goto start_code(main_context);
|
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
278 }
|