|
|
|
@ -50,7 +50,8 @@ struct ck_spinlock_anderson {
|
|
|
|
|
struct ck_spinlock_anderson_thread *slots;
|
|
|
|
|
unsigned int count;
|
|
|
|
|
unsigned int wrap;
|
|
|
|
|
char pad[CK_MD_CACHELINE - sizeof(unsigned int) * 2 - sizeof(void *)];
|
|
|
|
|
unsigned int mask;
|
|
|
|
|
char pad[CK_MD_CACHELINE - sizeof(unsigned int) * 3 - sizeof(void *)];
|
|
|
|
|
unsigned int next;
|
|
|
|
|
};
|
|
|
|
|
typedef struct ck_spinlock_anderson ck_spinlock_anderson_t;
|
|
|
|
@ -71,6 +72,7 @@ ck_spinlock_anderson_init(struct ck_spinlock_anderson *lock,
|
|
|
|
|
|
|
|
|
|
lock->slots = slots;
|
|
|
|
|
lock->count = count;
|
|
|
|
|
lock->mask = count - 1;
|
|
|
|
|
lock->next = 0;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -113,7 +115,7 @@ ck_spinlock_anderson_lock(struct ck_spinlock_anderson *lock,
|
|
|
|
|
position %= count;
|
|
|
|
|
} else {
|
|
|
|
|
position = ck_pr_faa_uint(&lock->next, 1);
|
|
|
|
|
position &= count - 1;
|
|
|
|
|
position &= lock->mask;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Spin until slot is marked as unlocked. First slot is initialized to false. */
|
|
|
|
@ -136,9 +138,12 @@ ck_spinlock_anderson_unlock(struct ck_spinlock_anderson *lock,
|
|
|
|
|
unsigned int position;
|
|
|
|
|
|
|
|
|
|
/* Mark next slot as available. */
|
|
|
|
|
position = (slot->position + 1) % lock->count;
|
|
|
|
|
ck_pr_store_uint(&lock->slots[position].locked, false);
|
|
|
|
|
if (lock->wrap == 0)
|
|
|
|
|
position = (slot->position + 1) & lock->mask;
|
|
|
|
|
else
|
|
|
|
|
position = (slot->position + 1) % lock->count;
|
|
|
|
|
|
|
|
|
|
ck_pr_store_uint(&lock->slots[position].locked, false);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
#endif /* CK_F_SPINLOCK_ANDERSON */
|
|
|
|
|