INLINE #endif /* PTW32_BUILD_INLINED */ void ptw32_mcs_lock_release (ptw32_mcs_local_node_t * node) { ptw32_mcs_lock_t *lock = node->lock; ptw32_mcs_local_node_t *next = (ptw32_mcs_local_node_t *) PTW32_INTERLOCKED_EXCHANGE_ADD_SIZE((PTW32_INTERLOCKED_SIZEPTR)&node->next, (PTW32_INTERLOCKED_SIZE)0); /* MBR fence */ if (0 == next) { /* no known successor */ if (node == (ptw32_mcs_local_node_t *) PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR((PTW32_INTERLOCKED_PVOID_PTR)lock, (PTW32_INTERLOCKED_PVOID)0, (PTW32_INTERLOCKED_PVOID)node)) { /* no successor, lock is free now */ return; } /* wait for successor */ ptw32_mcs_flag_wait(&node->nextFlag); next = (ptw32_mcs_local_node_t *) PTW32_INTERLOCKED_EXCHANGE_ADD_SIZE((PTW32_INTERLOCKED_SIZEPTR)&node->next, (PTW32_INTERLOCKED_SIZE)0); /* MBR fence */ } /* pass the lock */ ptw32_mcs_flag_set(&next->readyFlag); }
/* * ptw32_mcs_lock_release -- release an MCS lock. * * See: * J. M. Mellor-Crummey and M. L. Scott. * Algorithms for Scalable Synchronization on Shared-Memory Multiprocessors. * ACM Transactions on Computer Systems, 9(1):21-65, Feb. 1991. */ INLINE void ptw32_mcs_lock_release (ptw32_mcs_local_node_t * node) { ptw32_mcs_lock_t *lock = node->lock; ptw32_mcs_local_node_t *next = (ptw32_mcs_local_node_t *) InterlockedExchangeAdd((LPLONG)&node->next, 0); /* MBR fence */ if (0 == next) { /* no known successor */ if (node == (ptw32_mcs_local_node_t *) PTW32_INTERLOCKED_COMPARE_EXCHANGE((PTW32_INTERLOCKED_LPLONG)lock, (PTW32_INTERLOCKED_LONG)0, (PTW32_INTERLOCKED_LONG)node)) { /* no successor, lock is free now */ return; } /* wait for successor */ ptw32_mcs_flag_wait(&node->nextFlag); next = (ptw32_mcs_local_node_t *) InterlockedExchangeAdd((LPLONG)&node->next, 0); /* MBR fence */ } /* pass the lock */ ptw32_mcs_flag_set(&next->readyFlag); }
INLINE #endif void ptw32_mcs_lock_release (ptw32_mcs_local_node_t * node) { ptw32_mcs_lock_t *lock = node->lock; ptw32_mcs_local_node_t *next = (ptw32_mcs_local_node_t *) PTW32_INTERLOCKED_EXCHANGE_ADD_SIZE((PTW32_INTERLOCKED_SIZEPTR)&node->next, (PTW32_INTERLOCKED_SIZE)0); if (0 == next) { if (node == (ptw32_mcs_local_node_t *) PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR((PTW32_INTERLOCKED_PVOID_PTR)lock, (PTW32_INTERLOCKED_PVOID)0, (PTW32_INTERLOCKED_PVOID)node)) { return; } ptw32_mcs_flag_wait(&node->nextFlag); next = (ptw32_mcs_local_node_t *) PTW32_INTERLOCKED_EXCHANGE_ADD_SIZE((PTW32_INTERLOCKED_SIZEPTR)&node->next, (PTW32_INTERLOCKED_SIZE)0); } ptw32_mcs_flag_set(&next->readyFlag); }
/* * ptw32_mcs_lock_acquire -- acquire an MCS lock. * * See: * J. M. Mellor-Crummey and M. L. Scott. * Algorithms for Scalable Synchronization on Shared-Memory Multiprocessors. * ACM Transactions on Computer Systems, 9(1):21-65, Feb. 1991. */ static inline void ptw32_mcs_lock_acquire(ptw32_mcs_lock_t * lock, ptw32_mcs_local_node_t * node) { ptw32_mcs_local_node_t *pred; node->lock = lock; node->nextFlag = 0; node->readyFlag = 0; node->next = 0; /* initially, no successor */ /* queue for the lock */ pred = (ptw32_mcs_local_node_t *) InterlockedExchangePointer((void **) lock, node); if (0 != pred) { /* the lock was not free. link behind predecessor. */ pred->next = node; ptw32_mcs_flag_set(&pred->nextFlag); ptw32_mcs_flag_wait(&node->readyFlag); } }
/* * ptw32_mcs_lock_acquire -- acquire an MCS lock. * * See: * J. M. Mellor-Crummey and M. L. Scott. * Algorithms for Scalable Synchronization on Shared-Memory Multiprocessors. * ACM Transactions on Computer Systems, 9(1):21-65, Feb. 1991. */ INLINE void ptw32_mcs_lock_acquire (ptw32_mcs_lock_t * lock, ptw32_mcs_local_node_t * node) { ptw32_mcs_local_node_t *pred; node->lock = lock; node->nextFlag = 0; node->readyFlag = 0; node->next = 0; /* initially, no successor */ /* queue for the lock */ pred = (ptw32_mcs_local_node_t *)PTW32_INTERLOCKED_EXCHANGE((LPLONG)lock, (LONG)node); if (0 != pred) { /* the lock was not free. link behind predecessor. */ pred->next = node; ptw32_mcs_flag_set(&pred->nextFlag); ptw32_mcs_flag_wait(&node->readyFlag); } }
/* * ptw32_mcs_lock_release -- release an MCS lock. * * See: * J. M. Mellor-Crummey and M. L. Scott. * Algorithms for Scalable Synchronization on Shared-Memory Multiprocessors. * ACM Transactions on Computer Systems, 9(1):21-65, Feb. 1991. */ static inline void ptw32_mcs_lock_release(ptw32_mcs_local_node_t * node) { ptw32_mcs_lock_t *lock = node->lock; ptw32_mcs_local_node_t *next = (ptw32_mcs_local_node_t *) InterlockedCompareExchangePointer((void * volatile*) &node->next, 0, 0); /* MBR fence */ if (0 == next) { /* no known successor */ if (node == (ptw32_mcs_local_node_t *) InterlockedCompareExchangePointer((void * volatile*) lock, 0, node)) { /* no successor, lock is free now */ return; } /* wait for successor */ ptw32_mcs_flag_wait(&node->nextFlag); next = (ptw32_mcs_local_node_t *) InterlockedCompareExchangePointer((void * volatile*) &node->next, 0, 0); /* MBR fence */ } /* pass the lock */ ptw32_mcs_flag_set(&next->readyFlag); }
INLINE #endif void ptw32_mcs_lock_acquire (ptw32_mcs_lock_t * lock, ptw32_mcs_local_node_t * node) { ptw32_mcs_local_node_t *pred; node->lock = lock; node->nextFlag = 0; node->readyFlag = 0; node->next = 0; pred = (ptw32_mcs_local_node_t *)PTW32_INTERLOCKED_EXCHANGE_PTR((PTW32_INTERLOCKED_PVOID_PTR)lock, (PTW32_INTERLOCKED_PVOID)node); if (0 != pred) { pred->next = node; ptw32_mcs_flag_set(&pred->nextFlag); ptw32_mcs_flag_wait(&node->readyFlag); } }