a setjmp implementation of single-threaded mlp API
authorjjenista <jjenista>
Thu, 2 Apr 2009 20:53:54 +0000 (20:53 +0000)
committerjjenista <jjenista>
Thu, 2 Apr 2009 20:53:54 +0000 (20:53 +0000)
Robust/src/Tests/setjmpTest/Queue.c [new file with mode: 0644]
Robust/src/Tests/setjmpTest/Queue.h [new file with mode: 0644]
Robust/src/Tests/setjmpTest/makefile [new file with mode: 0644]
Robust/src/Tests/setjmpTest/sj.c [new file with mode: 0644]

diff --git a/Robust/src/Tests/setjmpTest/Queue.c b/Robust/src/Tests/setjmpTest/Queue.c
new file mode 100644 (file)
index 0000000..0b99404
--- /dev/null
@@ -0,0 +1,85 @@
+#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;
+}
diff --git a/Robust/src/Tests/setjmpTest/Queue.h b/Robust/src/Tests/setjmpTest/Queue.h
new file mode 100644 (file)
index 0000000..d3a9362
--- /dev/null
@@ -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 (file)
index 0000000..78ec48a
--- /dev/null
@@ -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 (file)
index 0000000..bc9dd57
--- /dev/null
@@ -0,0 +1,119 @@
+#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;
+}