# HG changeset patch # User Tatsuki IHA # Date 1444809638 -32400 # Node ID 9653f09ea8eb0a0138ccb83dee14a518f1976d81 # Parent a870c84acd0ec162d219d7655b7b21fb8c2a2162 Add synchronizedQueueIdeal diff -r a870c84acd0e -r 9653f09ea8eb src/synchronizedQueue/synchronizedQueueIdeal.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/synchronizedQueue/synchronizedQueueIdeal.c Wed Oct 14 17:00:38 2015 +0900 @@ -0,0 +1,182 @@ +#include +#include + +#include "synchronizedQueueContext.h" + +#include "allocate.h" +#include "origin_cs.h" + +#ifdef CLANG +#define _CbC_retrun __return +#define _CbC_environment __environment +#endif + +#define NUM 100 + +extern __code initSynchronizedQueueContext(struct Context* context); +extern void allocator(struct Context* context); + +__code meta(struct Context* context, enum Code next) { + goto (context->code[next])(context); +} + +//__code code1(struct Context* context) { +// context->data[Allocate]->allocate.size = sizeof(struct Element); +// goto code2(context); +//} + +__code code1(struct Context* context, struct Allocate* allocate) { + allocate->size = sizeof(long); + allocator(context); + long* count = &context->data[Counter]->count + goto code2(count) +} + +__code code2(struct Context* context, long* count) { + *count = 0; + struct Allocate* allocate = &context->data[Allocate]->allocate; + goto code3(count, allocate); +} + +__code code3(struct Context* context, long* count, struct Allocate* allocate) { + long loop = *count; + if(loop == NUM) { + goto thread_exit(); + } + allocate->size = sizeof(struct Element); + allocator(context); + struct Element* element = &context->data[context->dataNum]->element) + got code4(count, allocate, element); +} + +__code code4(struct Context* context, long* count, struct Allocate* allocate, struct Element* element) { + allocate->after_put = Code3; + element->value = (*count)++; + struct Queue* queue = &context->data[Queue]->queue; + goto sender(queue); +} + +__code meta_sender(struct Context* context, struct Queue* queue, enum Code next) { + // lock + pthread_mutex_lock(&queue->mutex); + goto (context->code[next])(context); +} + +__code sender(struct Context* context, struct Queue* queue) { + goto meta_sender(context, queue, Put); +} + +__code meta_put(struct Context* context, struct Queue* queue, enum Code next) { + // signal + pthread_cond_signal(&queue->cond); + // unlock + pthread_mutex_unlock(&queue->mutex); + goto (context->code[next])(context); +} + +__code put(struct Context* context, struct Allocate* allocate, struct Queue* queue, struct Element* element) { + if(queue->first) { + queue->last->next = element; + } else { + queue->first = element; + } + queue->last = element; + element->next = 0; + queue->count++; + printf("Put %d\n\n", element->value); + goto meta_put(context, queue, allocate->after_put); +} + +__code code5(struct Context* context, struct Allocate* allocate) { + allocate->size = sizeof(long); + allocator(context); + long* count = &context->data[Counter]->count + goto code6(count); +} + +__code code5_stub(struct Context* context) { + goto code5(context, &context->data[Allocate]->allocate); +} + +__code code6(struct Context* context, long* count) { + *count = 0; + struct Allocate* allocate = &context->data[Allocate]->allocate; + goto code7(count, allocate); +} + +__code code7(struct Context* context, long* count, struct Allocate* allocate) { + long loop = *count; + if(loop == NUM) { + goto meta(context, ThreadExit); + } + (*count)++; + allocate->after_get = Code7; + struct Queue* queue = &context->data[Queue]->queue; + goto receiver(queue); +} + +__code meta_receiver(struct Context* context, struct Queue* queue, enum Code next) { + // lock + pthread_mutex_lock(&queue->mutex); + goto (context->code[next])(context); +} + +__code receiver(struct Context* context, struct Queue* queue) { + goto meta_receiver(context, queue, Get); +} + +__code meta_get(struct Context* context, enum Code next) { + pthread_mutex_unlock(&context->data[Queue]->queue.mutex); + goto (context->code[next])(context); +} + +__code get(struct Context* context, struct Allocate* allocate, struct Queue* queue, struct Element* element) { + // thread wait if queue is empty + while (queue->count == 0) { + pthread_cond_wait(&queue->cond, &queue->mutex); + } + printf(" Get %d\n\n", queue->first->value); + queue->first = (queue->first->next) ? queue->first->next : 0; + queue->count--; + goto meta_get(context, allocate->after_get); +} + +__code thread_exit(struct Context* context) { + free(context->code); + free(context->data); + free(context->heapStart); + pthread_exit(0); +} + +void* thread_func(void* context) { + goto start_code((struct Context*)context, Code1); + return 0; +} + +void* thread_func2(void* context) { + goto start_code((struct Context*)context, Code5); + return 0; +} + +int main() { + struct Context* context1 = (struct Context*)malloc(sizeof(struct Context)); + initSynchronizedQueueContext(context1); + struct Context* context2 = (struct Context*)malloc(sizeof(struct Context)); + initSynchronizedQueueContext(context2); + struct Context* context3 = (struct Context*)malloc(sizeof(struct Context)); + initSynchronizedQueueContext(context3); + struct Context* context4 = (struct Context*)malloc(sizeof(struct Context)); + initSynchronizedQueueContext(context4); + context2->data[Queue] = context1->data[Queue]; + context3->data[Queue] = context1->data[Queue]; + context4->data[Queue] = context1->data[Queue]; + pthread_t thread1, thread2, thread3, thread4; + pthread_create(&thread1, NULL, thread_func, (void *)context1); + pthread_create(&thread2, NULL, thread_func, (void *)context2); + pthread_create(&thread3, NULL, thread_func2, (void *)context3); + pthread_create(&thread4, NULL, thread_func2, (void *)context4); + pthread_join(thread1, NULL); + pthread_join(thread2, NULL); + pthread_join(thread3, NULL); + pthread_join(thread4, NULL); +}