--- /dev/null
+#include <stdlib.h>
+#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;
+}
--- /dev/null
+#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
--- /dev/null
+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 *~
--- /dev/null
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <setjmp.h>
+
+#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;
+}