Skip to content

Commit 7319a36

Browse files
Yangzheng BaiYangzheng Bai
authored andcommitted
Fixed a transient pointer overwritten problem which caused live-lock
Need to save node->prev to a temporary variable, because once clh_unlock() has been called, the current clh_node may be used by another thread for many times and node->prev value might be changed. Therefore two thread may end up using the same clh_node next time and cause circular linked list problem (live-lock on the same clh_node)
1 parent a70863f commit 7319a36

File tree

1 file changed

+10
-3
lines changed

1 file changed

+10
-3
lines changed

ext/sms/clh_spinlock.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ static inline void clh_lock(struct clh_lock *lock, struct clh_node *node, bool u
226226
}
227227

228228
/* return the previous node as reused node for the next clh_lock() */
229-
static inline struct clh_node* clh_unlock(struct clh_node *node, unsigned long tid)
229+
static inline void clh_unlock(struct clh_node *node, unsigned long tid)
230230
{
231231
#ifdef DDEBUG
232232
printf("T%lu UNLOCK: node: %llx\n", tid, (long long unsigned int)node);
@@ -238,7 +238,6 @@ static inline struct clh_node* clh_unlock(struct clh_node *node, unsigned long t
238238
#else
239239
__atomic_store_n(&node->wait, 0, __ATOMIC_RELEASE);
240240
#endif
241-
return node->prev;
242241
}
243242

244243
/* standard lockhammer lock_acquire and lock_release interfaces */
@@ -251,5 +250,13 @@ lock_acquire (uint64_t *lock, unsigned long threadnum)
251250

252251
static inline void lock_release (uint64_t *lock, unsigned long threadnum)
253252
{
254-
clh_nodeptr[threadnum].ptr = clh_unlock(clh_nodeptr[threadnum].ptr, threadnum);
253+
/*
254+
* Have to save prev first, once called clh_unlock(), node->prev might
255+
* be overwritten by another thread and caused two thread use the same
256+
* nodepool clh_node, therefore generated a circular linked list after
257+
* another round of lock acquisition.
258+
*/
259+
struct clh_node* prev = clh_nodeptr[threadnum].ptr->prev;
260+
clh_unlock(clh_nodeptr[threadnum].ptr, threadnum);
261+
clh_nodeptr[threadnum].ptr = prev;
255262
}

0 commit comments

Comments
 (0)