From: jjenista Date: Thu, 2 Apr 2009 20:53:54 +0000 (+0000) Subject: a setjmp implementation of single-threaded mlp API X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=cc02b8efac41d7f259e2db1a7f15f81a43c7f6eb;p=IRC.git a setjmp implementation of single-threaded mlp API --- diff --git a/Robust/src/Tests/setjmpTest/Queue.c b/Robust/src/Tests/setjmpTest/Queue.c new file mode 100644 index 00000000..0b994048 --- /dev/null +++ b/Robust/src/Tests/setjmpTest/Queue.c @@ -0,0 +1,85 @@ +#include +#include "Queue.h" + +struct Queue * createQueue() { + struct Queue * queue = (struct Queue *)malloc(sizeof(struct Queue)); + queue->head = NULL; + queue->tail = NULL; + return queue; +} + +void freeQueue(struct Queue * q) { + free(q); +} + +struct QueueItem * addNewItem(struct Queue * queue, void * ptr) { + struct QueueItem * item=malloc(sizeof(struct QueueItem)); + item->objectptr=ptr; + item->queue=queue; + if (queue->head==NULL) { + queue->head=item; + queue->tail=item; + } else { + item->next=queue->head; + queue->head->prev=item; + queue->head=item; + } + return item; +} + +#ifdef RAW +struct QueueItem * addNewItem_I(struct Queue * queue, void * ptr) { + struct QueueItem * item=malloc_I(sizeof(struct QueueItem)); + item->objectptr=ptr; + item->queue=queue; + if (queue->head==NULL) { + queue->head=item; + queue->tail=item; + } else { + item->next=queue->head; + queue->head->prev=item; + queue->head=item; + } + return item; +} +#endif + +struct QueueItem * findItem(struct Queue * queue, void *ptr) { + struct QueueItem * item=queue->head; + while(item!=NULL) { + if (item->objectptr==ptr) + return item; + item=item->next; + } + return NULL; +} + +void removeItem(struct Queue * queue, struct QueueItem * item) { + struct QueueItem * prev=item->prev; + struct QueueItem * next=item->next; + if (queue->head==item) + queue->head=next; + else + prev->next=next; + if (queue->tail==item) + queue->tail=prev; + else + next->prev=prev; + free(item); +} + +struct QueueItem * getTail(struct Queue * queue) { + return queue->tail; +} + +struct QueueItem * getNextQueueItem(struct QueueItem * qi) { + return qi->next; +} + +void * getItem(struct Queue * queue) { + struct QueueItem * q=queue->head; + void * ptr=q->objectptr; + queue->head=q->next; + free(q); + return ptr; +} diff --git a/Robust/src/Tests/setjmpTest/Queue.h b/Robust/src/Tests/setjmpTest/Queue.h new file mode 100644 index 00000000..d3a93624 --- /dev/null +++ b/Robust/src/Tests/setjmpTest/Queue.h @@ -0,0 +1,32 @@ +#ifndef QUEUE_H +#define QUEUE_H + +struct Queue { + struct QueueItem * head; + struct QueueItem * tail; +}; + +typedef struct Queue Q; + +struct QueueItem { + void * objectptr; + struct Queue * queue; + struct QueueItem * next; + struct QueueItem * prev; +}; + +#define isEmpty(x) ((x)->head==NULL) + +void * getItem(struct Queue * queue); +void freeQueue(struct Queue * q); +struct Queue * createQueue(); +struct QueueItem * addNewItem(struct Queue * queue, void * ptr); +#ifdef RAW +struct QueueItem * addNewItem_I(struct Queue * queue, void * ptr); +#endif +struct QueueItem * findItem(struct Queue * queue, void * ptr); +void removeItem(struct Queue * queue, struct QueueItem * item); +struct QueueItem * getTail(struct Queue * queue); +struct QueueItem * getNextQueueItem(struct QueueItem * qi); + +#endif diff --git a/Robust/src/Tests/setjmpTest/makefile b/Robust/src/Tests/setjmpTest/makefile new file mode 100644 index 00000000..78ec48a6 --- /dev/null +++ b/Robust/src/Tests/setjmpTest/makefile @@ -0,0 +1,15 @@ +all: sj + +sj: sj.o Queue.o + gcc -g sj.o Queue.o -o sj + +Queue.o: Queue.c Queue.h + gcc -g -c Queue.c -o Queue.o + +sj.o: sj.c Queue.h + gcc -g -c sj.c -o sj.o + +clean: + rm -f sj + rm -f *.o + rm -f *~ diff --git a/Robust/src/Tests/setjmpTest/sj.c b/Robust/src/Tests/setjmpTest/sj.c new file mode 100644 index 00000000..bc9dd573 --- /dev/null +++ b/Robust/src/Tests/setjmpTest/sj.c @@ -0,0 +1,119 @@ +#include +#include +#include +#include + +#include "Queue.h" + +struct SESEstruct { + int id; + jmp_buf buf; + void* parent; + Q* childQ; + + // "local" variables for use in macros + void* child; +}; +typedef struct SESEstruct SESE; + + +SESE* createSESE( SESE* parent, int id ) { + SESE* sese = (SESE*) malloc( sizeof( SESE ) ); + sese->id = id; + sese->parent = (void*) parent; + sese->childQ = createQueue(); +} + +void freeSESE( SESE* sese ) { + freeQueue( sese->childQ ); + free( sese ); + sese = NULL; +} + +// macros set this return value for inspection +int mlpRet; + +// currently running SESE +SESE* current; + + +int mlpTime = 0; +void mlpLog( char* point ) { + printf( " time = %d, id = %d, point = %s\n", mlpTime, current->id, point ); + mlpTime++; +} + + +#define mlpInit( id ) \ + current = createSESE( NULL, id ); + + +void mlpBlock( int id ) { +} + + +#define mlpEnqueue( childid ) \ + current->child = (void*) createSESE( current, childid ); \ + addNewItem( current->childQ, current->child ); \ + if( setjmp( ((SESE*)current->child)->buf ) ) { \ + mlpRet = 1; \ + } else { \ + mlpRet = 0; \ + } + + +#define mlpNotifyExit( id ) \ + while( !isEmpty( current->childQ ) ) { \ + current->child = getItem( current->childQ ); \ + current = (SESE*) current->child; \ + if( setjmp( ((SESE*)current->parent)->buf ) ) { \ + } else { \ + longjmp( current->buf, 1 ); \ + } \ + } \ + if( current->parent != NULL ) { \ + current = (SESE*) current->parent; \ + longjmp( current->buf, 1 ); \ + } + + +int main() { + int i; + char lname[10]; + + printf( "Beginning setjump/longjump test.\n" ); + + mlpInit( 0 ); + mlpLog( "a" ); + + mlpEnqueue( 1 ); + if( mlpRet ) { + + mlpLog( "w" ); + + for( i = 0; i < 2; ++i ) { + + mlpEnqueue( 10 + i ); + if( mlpRet ) { + + sprintf( lname, "Ls%d", 10 + i ); + mlpLog( lname ); + mlpNotifyExit( 10 + i ); + + } else { + mlpLog( "i" ); + } + } + + mlpLog( "x" ); + mlpNotifyExit( 1 ); + + } else { + mlpLog( "W" ); + mlpNotifyExit( 0 ); + } + + printf( "End test.\n" ); + + return 0; +}