Mercurial > cgi-bin > hgwebdir.cgi > VMS > C_Libraries > Queue_impl
comparison PrivateQueue.c @ 4:8abcca1590b8
Tested and working on full VMS test
| author | Me |
|---|---|
| date | Wed, 30 Jun 2010 14:34:56 -0700 |
| parents | 85af604dee9b |
| children | 174a7c2ca340 |
comparison
equal
deleted
inserted
replaced
| 0:7202babe6f9e | 1:d17692922bff |
|---|---|
| 35 retQ->endOfData = &(retQ->startOfData[1023]); | 35 retQ->endOfData = &(retQ->startOfData[1023]); |
| 36 | 36 |
| 37 return retQ; | 37 return retQ; |
| 38 } | 38 } |
| 39 | 39 |
| 40 PrivQueueStruc* make_larger_PrivQ( PrivQueueStruc *Q ) | 40 |
| 41 void | |
| 42 enlargePrivQ( PrivQueueStruc *Q ) | |
| 41 { int oldSize, newSize; | 43 { int oldSize, newSize; |
| 42 void **oldStartOfData; | 44 void **oldStartOfData; |
| 43 | 45 |
| 44 oldSize = Q->endOfData - Q->startOfData; | 46 oldSize = Q->endOfData - Q->startOfData; |
| 45 newSize = 2 * oldSize; | 47 newSize = 2 * oldSize; |
| 48 free(oldStartOfData); | 50 free(oldStartOfData); |
| 49 | 51 |
| 50 Q->extractPos = &(Q->startOfData[0]); //side by side == empty | 52 Q->extractPos = &(Q->startOfData[0]); //side by side == empty |
| 51 Q->insertPos = &(Q->startOfData[1]); // so start pos's have to be | 53 Q->insertPos = &(Q->startOfData[1]); // so start pos's have to be |
| 52 Q->endOfData = &(Q->startOfData[newSize - 1]); | 54 Q->endOfData = &(Q->startOfData[newSize - 1]); |
| 53 | |
| 54 return Q; | |
| 55 } | 55 } |
| 56 | 56 |
| 57 | 57 |
| 58 /*Returns NULL when queue is empty | 58 /*Returns NULL when queue is empty |
| 59 */ | 59 */ |
| 60 void* readPrivQ( PrivQueueStruc* Q ) | 60 void* readPrivQ( PrivQueueStruc* Q ) |
| 61 { void *out = 0; | 61 { void *out = 0; |
| 62 int startOfData = Q->startOfData; | 62 void **startOfData = Q->startOfData; |
| 63 int endOfData = Q->endOfData; | 63 void **endOfData = Q->endOfData; |
| 64 | 64 |
| 65 volatile int insertPos = Q->insertPos; | 65 void **insertPos = Q->insertPos; |
| 66 volatile int extractPos = Q->extractPos; | 66 void **extractPos = Q->extractPos; |
| 67 | 67 |
| 68 //if not empty -- extract just below insert when empty | 68 //if not empty -- extract just below insert when empty |
| 69 if( insertPos - extractPos != 1 && | 69 if( insertPos - extractPos != 1 && |
| 70 !(extractPos == endOfData && insertPos == startOfData)) | 70 !(extractPos == endOfData && insertPos == startOfData)) |
| 71 { //move before read | 71 { //move before read |
| 80 } | 80 } |
| 81 //Q is empty | 81 //Q is empty |
| 82 return NULL; | 82 return NULL; |
| 83 } | 83 } |
| 84 | 84 |
| 85 | |
| 86 /*Expands the queue size automatically when it's full | |
| 87 */ | |
| 88 void | |
| 89 writeAndEnlargePrivQ( void * in, PrivQueueStruc* Q ) | |
| 90 { | |
| 91 void **startOfData = Q->startOfData; | |
| 92 void **endOfData = Q->endOfData; | |
| 93 | |
| 94 void **insertPos = Q->insertPos; | |
| 95 void **extractPos = Q->extractPos; | |
| 96 | |
| 97 tryAgain: | |
| 98 if( extractPos - insertPos != 1 && | |
| 99 !(insertPos == endOfData && extractPos == startOfData)) | |
| 100 { *(Q->insertPos) = in; //insert before move | |
| 101 if( insertPos == endOfData ) //write new pos exactly once, correctly | |
| 102 { Q->insertPos = startOfData; | |
| 103 } | |
| 104 else | |
| 105 { Q->insertPos++; | |
| 106 } | |
| 107 return; | |
| 108 } | |
| 109 //Q is full | |
| 110 enlargePrivQ( Q ); | |
| 111 goto tryAgain; | |
| 112 } | |
| 113 | |
| 114 | |
| 85 /*Returns false when the queue was full. | 115 /*Returns false when the queue was full. |
| 86 * have option of calling make_larger_PrivQ to make more room, then try again | 116 * have option of calling make_larger_PrivQ to make more room, then try again |
| 87 */ | 117 */ |
| 88 bool8 writePrivQ( void * in, PrivQueueStruc* Q ) | 118 int writeAndFailPrivQ( void * in, PrivQueueStruc* Q ) |
| 89 { | 119 { |
| 90 int startOfData = Q->startOfData; | 120 void **startOfData = Q->startOfData; |
| 91 int endOfData = Q->endOfData; | 121 void **endOfData = Q->endOfData; |
| 92 | 122 |
| 93 volatile int insertPos = Q->insertPos; | 123 void **insertPos = Q->insertPos; |
| 94 volatile int extractPos = Q->extractPos; | 124 void **extractPos = Q->extractPos; |
| 95 | 125 |
| 96 if( extractPos - insertPos != 1 && | 126 if( extractPos - insertPos != 1 && |
| 97 !(insertPos == endOfData && extractPos == startOfData)) | 127 !(insertPos == endOfData && extractPos == startOfData)) |
| 98 { *(insertPos) = in; //insert before move | 128 { *(Q->insertPos) = in; //insert before move |
| 99 if( insertPos == endOfData ) //write new pos exactly once, correctly | 129 if( insertPos == endOfData ) //write new pos exactly once, correctly |
| 100 { Q->insertPos = startOfData; | 130 { Q->insertPos = startOfData; |
| 101 } | 131 } |
| 102 else | 132 else |
| 103 { Q->insertPos++; | 133 { Q->insertPos++; |
| 105 return TRUE; | 135 return TRUE; |
| 106 } | 136 } |
| 107 //Q is full | 137 //Q is full |
| 108 return FALSE; | 138 return FALSE; |
| 109 } | 139 } |
| 110 |
