00001 #include <stdlib.h> 00002 #include "converse.h" 00003 #include "fifo.h" 00004 00005 00006 FIFO_QUEUE *FIFO_Create(void) 00007 { 00008 FIFO_QUEUE *queue; 00009 queue = (FIFO_QUEUE *)malloc(sizeof(FIFO_QUEUE)); 00010 _MEMCHECK(queue); 00011 queue->block = (void **) malloc(_FIFO_BLK_LEN * sizeof(void *)); 00012 _MEMCHECK(queue->block); 00013 queue->size = _FIFO_BLK_LEN; 00014 queue->push = queue->pull = 0; 00015 queue->fill = 0; 00016 return queue; 00017 } 00018 00019 int FIFO_Fill(FIFO_QUEUE *queue) 00020 { 00021 return queue->fill; 00022 } 00023 00024 int FIFO_Empty(FIFO_QUEUE *queue) 00025 { 00026 return !(queue->fill); 00027 } 00028 00029 static void FIFO_Expand(FIFO_QUEUE *queue) 00030 { 00031 int newsize; void **newblock; int rest; 00032 int pull = queue->pull; 00033 int size = queue->size; 00034 void **block = queue->block; 00035 newsize = size * 3; 00036 newblock = (void**)malloc(newsize * sizeof(void *)); 00037 _MEMCHECK(newblock); 00038 rest = size - pull; 00039 memcpy(newblock, block + pull, rest * sizeof(void *)); 00040 memcpy(newblock + rest, block, pull * sizeof(void *)); 00041 free(block); 00042 queue->block = newblock; 00043 queue->size = newsize; 00044 queue->pull = 0; 00045 queue->push = size; 00046 queue->fill = size; 00047 } 00048 00049 void FIFO_EnQueue(FIFO_QUEUE *queue, void *elt) 00050 { 00051 if (queue->fill == queue->size) FIFO_Expand(queue); 00052 queue->block[queue->push] = elt; 00053 queue->push = ((queue->push + 1) % queue->size); 00054 queue->fill++; 00055 } 00056 00057 void FIFO_EnQueue_Front(FIFO_QUEUE *queue, void *elt) 00058 { 00059 if (queue->fill == queue->size) FIFO_Expand(queue); 00060 queue->pull = ((queue->pull + queue->size - 1) % queue->size); 00061 queue->block[queue->pull] = elt; 00062 queue->fill++; 00063 } 00064 00065 void *FIFO_Peek(FIFO_QUEUE *queue) 00066 { 00067 if (queue->fill == 0) return 0; 00068 return queue->block[queue->pull]; 00069 } 00070 00071 void FIFO_Pop(FIFO_QUEUE *queue) 00072 { 00073 if (queue->fill) { 00074 queue->pull = (queue->pull+1) % queue->size; 00075 queue->fill--; 00076 } 00077 } 00078 00079 void FIFO_DeQueue(FIFO_QUEUE *queue, void **element) 00080 { 00081 *element = 0; 00082 if (queue->fill) { 00083 *element = queue->block[queue->pull]; 00084 queue->pull = (queue->pull+1) % queue->size; 00085 queue->fill--; 00086 } 00087 } 00088 00089 00090 /* This assumes the the caller has not allocated 00091 memory for element 00092 */ 00093 void FIFO_Enumerate(FIFO_QUEUE *queue, void ***element) 00094 { 00095 int i = 0; 00096 int num = queue->fill; 00097 int pull = queue->pull; 00098 *element = 0; 00099 if(num == 0) 00100 return; 00101 *element = (void **)malloc(num * sizeof(void *)); 00102 _MEMCHECK(*element); 00103 while(num > 0){ 00104 (*element)[i++] = queue->block[pull]; 00105 pull = (pull + 1) % queue->size; 00106 num--; 00107 } 00108 } 00109 00110 void FIFO_Destroy(FIFO_QUEUE *queue) 00111 { 00112 if (!FIFO_Empty(queue)) { 00113 CmiError("Tried to FIFO_Destroy a non-empty queue.\n"); 00114 exit(1); 00115 } 00116 free(queue->block); 00117 free(queue); 00118 }