Changeset 1098 for sfio/trunk
- Timestamp:
- 08/26/06 08:18:07 (2 years ago)
- Location:
- sfio/trunk/src/lockfree
- Files:
-
- 3 modified
- 2 moved
-
BcbTestProject.bpr (modified) (1 diff)
-
BcbTestProject.cpp (modified) (2 diffs)
-
MessageQueue.cpp (modified) (7 diffs)
-
grame02_lifo.c (moved) (moved from sfio/trunk/src/lockfree/grame02_stack.c) (6 diffs)
-
grame02_lifo.h (moved) (moved from sfio/trunk/src/lockfree/grame02_stack.h) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
sfio/trunk/src/lockfree/BcbTestProject.bpr
r1094 r1098 15 15 # --------------------------------------------------------------------------- 16 16 PROJECT = BcbTestProject.exe 17 OBJFILES = BcbTestProject.obj ms96_queue.obj grame02_stack.obj MessageQueue.obj17 OBJFILES = BcbTestProject.obj ms96_queue.obj MessageQueue.obj grame02_lifo.obj 18 18 RESFILES = 19 19 RESDEPEN = $(RESFILES) -
sfio/trunk/src/lockfree/BcbTestProject.cpp
r1094 r1098 6 6 7 7 #include "ms96_queue.h" 8 #include "grame02_ stack.h"8 #include "grame02_lifo.h" 9 9 #include "MessageQueue.h" 10 10 11 11 //--------------------------------------------------------------------------- 12 12 USEUNIT("ms96_queue.c"); 13 USEUNIT("grame02_stack.c");14 13 USEUNIT("MessageQueue.cpp"); 14 USEUNIT("grame02_lifo.c"); 15 15 //--------------------------------------------------------------------------- 16 16 #pragma argsused … … 19 19 20 20 ms96_queue_test(); 21 grame02_ stack_test();21 grame02_lifo_test(); 22 22 23 23 MessageQueue::Test(); -
sfio/trunk/src/lockfree/MessageQueue.cpp
r1094 r1098 5 5 6 6 #include "ms96_queue.h" 7 #include "grame02_ stack.h"7 #include "grame02_lifo.h" 8 8 9 9 10 10 static size_t nodeSize_; 11 static grame02_ stack_t nodeFreeList_;12 static grame02_ stack_t messageFreeList_;11 static grame02_lifo_t nodeFreeList_; 12 static grame02_lifo_t messageFreeList_; 13 13 14 14 // for now we limit the message size to 64 bytes, all messages occupy the same space. … … 23 23 void Message::InitializeAllocator() 24 24 { 25 nodeSize_ = std::max( sizeof(ms96_queue_node_t), sizeof(grame02_ stack_node_t) );25 nodeSize_ = std::max( sizeof(ms96_queue_node_t), sizeof(grame02_lifo_node_t) ); 26 26 27 27 28 grame02_ stack_initialize( &nodeFreeList_ );29 grame02_ stack_initialize( &messageFreeList_ );28 grame02_lifo_initialize( &nodeFreeList_ ); 29 grame02_lifo_initialize( &messageFreeList_ ); 30 30 } 31 31 … … 33 33 void* AllocateNode() 34 34 { 35 grame02_ stack_node_t *node = grame02_stack_pop( &nodeFreeList_ );35 grame02_lifo_node_t *node = grame02_lifo_pop( &nodeFreeList_ ); 36 36 if( !node ) 37 node = reinterpret_cast<grame02_ stack_node_t*>( ::operator new( nodeSize_ ) );37 node = reinterpret_cast<grame02_lifo_node_t*>( ::operator new( nodeSize_ ) ); 38 38 39 39 return node; … … 43 43 void FreeNode( void * node ) 44 44 { 45 grame02_ stack_push( &nodeFreeList_, reinterpret_cast<grame02_stack_node_t*>(node) );45 grame02_lifo_push( &nodeFreeList_, reinterpret_cast<grame02_lifo_node_t*>(node) ); 46 46 } 47 47 … … 59 59 assert( size <= MAX_MESSAGE_SIZE ); // if you exceed this value you should retune the system... 60 60 61 grame02_ stack_node_t *node = grame02_stack_pop( &messageFreeList_ );61 grame02_lifo_node_t *node = grame02_lifo_pop( &messageFreeList_ ); 62 62 if( node ){ 63 63 Message *message = reinterpret_cast<Message*>( node->value ); // pretend we already have a message so we can set the lf node … … 65 65 return message; 66 66 }else{ 67 node = reinterpret_cast<grame02_ stack_node_t*>( AllocateNode() );67 node = reinterpret_cast<grame02_lifo_node_t*>( AllocateNode() ); 68 68 Message *message = reinterpret_cast<Message*>( ::operator new( MAX_MESSAGE_SIZE ) ); 69 69 message->SetLFNode( node ); … … 76 76 { 77 77 Message *message = reinterpret_cast<Message*>( p ); // pretend we already have a message so we can set the lf node 78 grame02_ stack_node_t *node = reinterpret_cast<grame02_stack_node_t*>( message->GetLFNode() );78 grame02_lifo_node_t *node = reinterpret_cast<grame02_lifo_node_t*>( message->GetLFNode() ); 79 79 assert( node ); 80 80 81 81 node->value = message; 82 grame02_ stack_push( &messageFreeList_, node );82 grame02_lifo_push( &messageFreeList_, node ); 83 83 } 84 84 -
sfio/trunk/src/lockfree/grame02_lifo.c
r1095 r1098 1 #include "grame02_ stack.h"1 #include "grame02_lifo.h" 2 2 3 3 #include <stdio.h> 4 4 #include <stdlib.h> 5 5 6 /* 7 fixme: could rename lifo 8 */ 6 9 7 static int CAS( volatile void *p, volatile void *oldValue, volatile void *newValue ) 10 11 static int CAS32( volatile void *p32, volatile void *oldValue, volatile void *newValue ) 8 12 { 9 13 unsigned char resultFlags; … … 13 17 mov ebx, newValue 14 18 15 mov esi, p 19 mov esi, p32 16 20 17 21 lock cmpxchg [esi], ebx … … 26 30 27 31 28 static int CAS 2( volatile grame02_stack_t *p, volatile void *oldPtr, volatile unsigned long oldCount,32 static int CAS64( volatile void *p64, volatile void *oldPtr, volatile unsigned long oldCount, 29 33 void *newPtr, unsigned long newCount ) 30 34 { … … 38 42 mov ecx, newCount 39 43 40 mov esi, p 44 mov esi, p64 41 45 42 46 lock cmpxchg8b [esi] … … 51 55 52 56 53 LIBLFDS_CALLING_CONVENTION(void) grame02_ stack_initialize( grame02_stack_t* stack )57 LIBLFDS_CALLING_CONVENTION(void) grame02_lifo_initialize( grame02_lifo_t* stack ) 54 58 { 55 stack->top = 0;59 stack->top = NULL; 56 60 } 57 61 58 62 59 LIBLFDS_CALLING_CONVENTION(void) grame02_ stack_push( grame02_stack_t* stack, grame02_stack_node_t *node )63 LIBLFDS_CALLING_CONVENTION(void) grame02_lifo_push( grame02_lifo_t* stack, grame02_lifo_node_t *node ) 60 64 { 61 / / B1: loop65 /* B1: loop */ 62 66 for(;;){ 63 // B2: cl->next = lf->top # set the cell next pointer to top of the lifo 67 /* B2: cl->next = lf->top # set the cell next pointer to top of the lifo */ 68 69 /* On IA32 the CAS32 below ensures the visibility of stack->top to all 70 * other threads. Otherwise we may need a read barrier here to ensure 71 * that the current value of stack->top is being fetched. 72 * ==> actually not 100% this is true if CAS32 fails, should check 73 */ 74 64 75 node->next = stack->top; 65 // B3: if CAS (&lf->top, cl->next, cl) # try to set the top of the lifo to cell 66 // B4: break 67 // B5: endif 76 77 /* B3: if CAS (&lf->top, cl->next, cl) # try to set the top of 78 # the lifo to cell */ 79 /* B4: break */ 80 /* B5: endif */ 68 81 69 // on IA32 CAS has full fence semantics, otherwise we would need a write barrier 70 // here to ensure that node->next and node->value were stored before the CAS is executed 71 72 if( CAS( &stack->top, node->next, node ) ) 82 /* On IA32 CAS has full fence semantics, otherwise we may need a write 83 * barrier here to ensure that node->next and node->value are stored 84 * before the CAS is executed. 85 */ 86 87 if( CAS32( &stack->top, node->next, node ) ) 73 88 break; 74 / / B6: endloop89 /* B6: endloop */ 75 90 } 76 91 } 77 92 78 93 79 LIBLFDS_CALLING_CONVENTION(grame02_ stack_node_t*) grame02_stack_pop( grame02_stack_t* stack )94 LIBLFDS_CALLING_CONVENTION(grame02_lifo_node_t*) grame02_lifo_pop( grame02_lifo_t* stack ) 80 95 { 81 grame02_ stack_node_t *top, *next;96 grame02_lifo_node_t *top, *next; 82 97 unsigned long pop_count; 83 / / SC1: loop98 /* SC1: loop */ 84 99 for(;;){ 85 // SC2: head = lf->top # get the top cell of the lifo 86 // SC2: oc = lf->ocount # get the pop operations count 87 top = (grame02_stack_node_t*)stack->top; 100 101 /* On some architectures a read barrier may be necessary here to ensure 102 * that fresh values are being read for stack->top and stack->pop_count 103 * and also for top->value (because we return top below and value needs 104 * to be present for the client to use it). 105 */ 106 107 /* SC2: head = lf->top # get the top cell of the lifo */ 108 /* SC2: oc = lf->ocount # get the pop operations count */ 109 top = (grame02_lifo_node_t*)stack->top; 88 110 pop_count = stack->pop_count; 89 111 90 / / SC3: if head == NULL91 / / SC4: return NULL # LIFO is empty92 / / SC5: endif112 /* SC3: if head == NULL */ 113 /* SC4: return NULL # LIFO is empty */ 114 /* SC5: endif */ 93 115 if( !top ) 94 return 0;116 return NULL; 95 117 96 // SC6: next = head->next # get the next cell of cell 97 next = (grame02_stack_node_t*)top->next; 98 99 // SC7: if CAS2 (&lf->top, head, oc, next, oc + 1) # try to change both the top of the lifo and pop count 100 // SC8: break 101 // SC9: endif 102 if( CAS2( stack, top, pop_count, next, pop_count + 1 ) ) 118 /* If a read barrier is needed at all, one above should ensure that 119 * top->next is also up to date when we read it. 120 */ 121 122 /* SC6: next = head->next # get the next cell of cell */ 123 next = (grame02_lifo_node_t*)top->next; 124 125 /* SC7: if CAS2 (&lf->top, head, oc, next, oc + 1) # try to change both 126 # the top of the lifo 127 # and pop count */ 128 /* SC8: break */ 129 /* SC9: endif 130 */ 131 if( CAS64( stack, top, pop_count, next, pop_count + 1 ) ) 103 132 break; 104 133 105 / / SC10: endloop134 /* SC10: endloop */ 106 135 } 107 / / SC11: return head136 /* SC11: return head */ 108 137 return top; 109 138 } 110 139 111 140 112 LIBLFDS_CALLING_CONVENTION(void) grame02_ stack_test(void)141 LIBLFDS_CALLING_CONVENTION(void) grame02_lifo_test(void) 113 142 { 114 143 const char *s = "\n!dlrow olleh"; 115 grame02_ stack_t stack;144 grame02_lifo_t stack; 116 145 const char *p; 117 grame02_ stack_node_t *node;146 grame02_lifo_node_t *node; 118 147 119 grame02_ stack_initialize( &stack );148 grame02_lifo_initialize( &stack ); 120 149 121 150 p = s; … … 123 152 char *p2 = (char*)malloc( 1 ); 124 153 *p2 = *p++; 125 node = (grame02_ stack_node_t*)malloc( sizeof(grame02_stack_node_t) );154 node = (grame02_lifo_node_t*)malloc( sizeof(grame02_lifo_node_t) ); 126 155 node->value = p2; 127 grame02_ stack_push( &stack, node );156 grame02_lifo_push( &stack, node ); 128 157 } 129 158 130 node = grame02_ stack_pop( &stack );159 node = grame02_lifo_pop( &stack ); 131 160 while( node ){ 132 161 //free( node ); // actually it isn't safe to free node here, this is just a test so we leak it 133 162 printf( "%c", * ((char*)(node->value)) ); 134 163 free( node->value ); 135 node = grame02_ stack_pop( &stack );164 node = grame02_lifo_pop( &stack ); 136 165 } 137 166 } -
sfio/trunk/src/lockfree/grame02_lifo.h
r1095 r1098 1 #ifndef INCLUDED_GRAME02_ STACK_H2 #define INCLUDED_GRAME02_ STACK_H1 #ifndef INCLUDED_GRAME02_LIFO_H 2 #define INCLUDED_GRAME02_LIFO_H 3 3 4 4 /* … … 22 22 23 23 24 typedef void* grame02_ value_t; /* this is the "payload" data type which is stored in the stack node */24 typedef void* grame02_lifo_value_t; /* this is the "payload" data type which is stored in the stack node */ 25 25 26 struct grame02_ stack_node_t;27 typedef struct grame02_ stack_node_t grame02_stack_node_t;26 struct grame02_lifo_node_t; 27 typedef struct grame02_lifo_node_t grame02_lifo_node_t; 28 28 29 29 #pragma pack( push, 4 ) 30 30 31 31 32 typedef struct grame02_ stack_node_t{33 grame02_ value_t value;34 volatile grame02_ stack_node_t *next;35 } grame02_ stack_node_t;32 typedef struct grame02_lifo_node_t{ 33 grame02_lifo_value_t value; 34 volatile grame02_lifo_node_t *next; 35 } grame02_lifo_node_t; 36 36 37 37 38 typedef struct grame02_ stack_t{39 volatile grame02_ stack_node_t *top;38 typedef struct grame02_lifo_t{ 39 volatile grame02_lifo_node_t *top; 40 40 volatile unsigned long pop_count; 41 }grame02_ stack_t;41 }grame02_lifo_t; 42 42 43 43 … … 45 45 46 46 47 LIBLFDS_CALLING_CONVENTION(void) grame02_ stack_initialize( grame02_stack_t* stack );47 LIBLFDS_CALLING_CONVENTION(void) grame02_lifo_initialize( grame02_lifo_t* stack ); 48 48 49 LIBLFDS_CALLING_CONVENTION(void) grame02_ stack_push( grame02_stack_t* stack, grame02_stack_node_t *node );49 LIBLFDS_CALLING_CONVENTION(void) grame02_lifo_push( grame02_lifo_t* stack, grame02_lifo_node_t *node ); 50 50 51 LIBLFDS_CALLING_CONVENTION(grame02_ stack_node_t*) grame02_stack_pop( grame02_stack_t* stack );51 LIBLFDS_CALLING_CONVENTION(grame02_lifo_node_t*) grame02_lifo_pop( grame02_lifo_t* stack ); 52 52 53 LIBLFDS_CALLING_CONVENTION(void) grame02_ stack_test(void);53 LIBLFDS_CALLING_CONVENTION(void) grame02_lifo_test(void); 54 54 55 55 #ifdef __cplusplus … … 57 57 #endif /* __cplusplus */ 58 58 59 #endif /* INCLUDED_GRAME02_ STACK_H */59 #endif /* INCLUDED_GRAME02_LIFO_H */ 60 60
