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); }
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_flag_wait -- wait for notification from another. * * Store an event handle in the flag and wait on it if the flag has not been * set, and proceed without creating an event otherwise. */ INLINE void ptw32_mcs_flag_wait (HANDLE * flag) { if ((PTW32_INTERLOCKED_SIZE)0 == PTW32_INTERLOCKED_EXCHANGE_ADD_SIZE((PTW32_INTERLOCKED_SIZEPTR)flag, (PTW32_INTERLOCKED_SIZE)0)) /* MBR fence */ { /* the flag is not set. create event. */ HANDLE e = CreateEvent(NULL, PTW32_FALSE, PTW32_FALSE, NULL); if ((PTW32_INTERLOCKED_SIZE)0 == PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE( (PTW32_INTERLOCKED_SIZEPTR)flag, (PTW32_INTERLOCKED_SIZE)e, (PTW32_INTERLOCKED_SIZE)0)) { /* stored handle in the flag. wait on it now. */ WaitForSingleObject(e, INFINITE); } CloseHandle(e); } }
INLINE void ptw32_mcs_flag_wait (HANDLE * flag) { if ((PTW32_INTERLOCKED_LONG)0 == PTW32_INTERLOCKED_EXCHANGE_ADD_SIZE((PTW32_INTERLOCKED_SIZEPTR)flag, (PTW32_INTERLOCKED_SIZE)0)) { HANDLE e = CreateEvent(NULL, PTW32_FALSE, PTW32_FALSE, NULL); if ((PTW32_INTERLOCKED_SIZE)0 == PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE( (PTW32_INTERLOCKED_SIZEPTR)flag, (PTW32_INTERLOCKED_SIZE)e, (PTW32_INTERLOCKED_SIZE)0)) { WaitForSingleObject(e, INFINITE); } CloseHandle(e); } }