Segfault fix in prefetch queue + additional macros for debugging
[IRC.git] / Robust / src / Runtime / DSTM / interface / queue.c
index ce82aa7ec71a578d98d25db3361fce100b9b69fd..9f2eb419b9ff96791c3e820838a70589182ce72e 100644 (file)
 #include "queue.h"
 
-primarypfq_t pqueue; //Global queue
+volatile int headoffset, tailoffset;
+char * memory;
+pthread_mutex_t qlock;
+pthread_mutexattr_t qlockattr;
+pthread_cond_t qcond;
 
-void queueInit(void) {
-       /* Intitialize primary queue */
-       pqueue.front = pqueue.rear = NULL;
-       pthread_mutex_init(&pqueue.qlock, NULL);
-       pthread_cond_init(&pqueue.qcond, NULL);
-}
 
-/* Delete the node pointed to by the front ptr of the queue */
-void delqnode() {
-       prefetchqelem_t *delnode;
-       if((pqueue.front == NULL) && (pqueue.rear == NULL)) {
-               printf("The queue is empty: UNDERFLOW %s, %d\n", __FILE__, __LINE__);
-               return;
-       } else if ((pqueue.front == pqueue.rear) && pqueue.front != NULL && pqueue.rear != NULL) {
-               printf("TEST1\n");
-               free(pqueue.front);
-               pqueue.front = pqueue.rear = NULL;
-       } else {
-               delnode = pqueue.front;
-               pqueue.front = pqueue.front->next;
-               printf("TEST2\n");
-               free(delnode);
-       }
-}
+#define QSIZE 1000000 //1 MB
 
-void queueDelete(void) {
-       /* Remove each element */
-       while(pqueue.front != NULL)
-               delqnode();
-       pqueue.front = pqueue.rear = NULL;
+void queueInit(void) {
+  /* Intitialize primary queue */
+  headoffset=0;
+  tailoffset=0;
+  memory=malloc(QSIZE+sizeof(int));//leave space for -1
+  pthread_mutexattr_init(&qlockattr);
+  pthread_mutexattr_settype(&qlockattr, PTHREAD_MUTEX_RECURSIVE_NP);
+  pthread_mutex_init(&qlock, &qlockattr);
+  pthread_cond_init(&qcond, NULL);
 }
 
-/* Inserts to the rear of primary prefetch queue */
-void enqueue(prefetchqelem_t *qnode) {
-       if(pqueue.front == NULL && pqueue.rear == NULL) {
-               pqueue.front = pqueue.rear = qnode;
-       } else {
-               qnode->next = NULL;
-               pqueue.rear->next = qnode;
-               pqueue.rear = qnode;
-       }
+void * getmemory(int size) {
+  int tmpoffset=headoffset+size+sizeof(int);
+  if (tmpoffset>QSIZE) {
+    //Wait for tail to go past end
+    tmpoffset=size+sizeof(int);
+    while(headoffset<tailoffset)
+      ;
+    //Wait for tail to go past new start
+    while(tailoffset<=tmpoffset)
+      ;
+    *((int *)(memory+headoffset))=-1;//safe because we left space
+    *((int*)memory)=size+sizeof(int);
+    return memory+sizeof(int);
+  } else {
+    while(headoffset<tailoffset&&tailoffset<=tmpoffset)
+      ;
+    *((int*)(memory+headoffset))=size+sizeof(int);
+    return memory+headoffset+sizeof(int);
+  }
 }
 
-/* Return the node pointed to by the front ptr of the queue */
-prefetchqelem_t *dequeue(void) {
-       prefetchqelem_t *retnode;
-       if (pqueue.front == NULL) {
-               printf("Queue empty: Underflow %s, %d\n", __FILE__, __LINE__);
-               return NULL;
-       }
-       retnode = pqueue.front;
-       pqueue.front = pqueue.front->next;
-
-       return retnode;
+void movehead(int size) {
+  int tmpoffset=headoffset+size+sizeof(int);
+  if (tmpoffset>QSIZE) {
+    headoffset=size+sizeof(int);
+  } else
+    headoffset=tmpoffset;
+  pthread_cond_signal(&qcond);//wake the other thread up
 }
 
-void queueDisplay() {
-       int offset = sizeof(prefetchqelem_t);
-       int *ptr;
-       int ntuples;
-       char *ptr1;
-       prefetchqelem_t *tmp = pqueue.front;
-       while(tmp != NULL) {
-               ptr1 = (char *) tmp;
-               ptr = (int *)(ptr1 + offset);
-               ntuples = *ptr;
-               printf("Number of tuples = %d\n", ntuples);
-               tmp = tmp->next;
-       }
-}
+void * gettail() {
+  while(tailoffset==headoffset) {
+    //Sleep
+    pthread_mutex_lock(&qlock);
+    if (tailoffset==headoffset)
+      pthread_cond_wait(&qcond, &qlock);
+    pthread_mutex_unlock(&qlock);
+  }
+  if (*((int *)(memory+tailoffset))==-1) {
+    tailoffset=0;//do loop
+  }
 
-void predealloc(prefetchqelem_t *node) {
-       free(node);
-       node->next = NULL;
+  return memory+tailoffset+sizeof(int);
 }
 
-
-#if 0
-main() {
-       unsigned int oids[] = {11, 13};
-       short endoffsets[] = {2, 5};
-       short arrayfields[] = {2, 2, 1, 5, 6};
-       queueInit();
-       queueDisplay();
-       prefetch(2, oids, endoffsets, arrayfields);
-       queueDisplay();
-       unsigned int oids1[] = {21, 23, 25, 27};
-       short endoffsets1[] = {1, 2, 3, 4};
-       short arrayfields1[] = {3, 2, 1, 3};
-       prefetch(4, oids1, endoffsets1, arrayfields1);
-       queueDisplay();
-       delqnode();
-       queueDisplay();
-       delqnode();
-       queueDisplay();
-       delqnode();
-       queueDisplay();
-       delqnode();
-
+void inctail() {
+  int tmpoffset=tailoffset+*((int *)(memory+tailoffset));
+  if (tmpoffset>QSIZE)
+    tailoffset=0;
+  else
+    tailoffset=tmpoffset;
 }
 
-#endif
-
+void predealloc() {
+  free(memory);
+}