ck_spinlock: Avoid modulus on unlock for power of 2 count.

ck_pring
Samy Al Bahra 14 years ago
parent 6b4d03b30d
commit 38c614222a

@ -50,7 +50,8 @@ struct ck_spinlock_anderson {
struct ck_spinlock_anderson_thread *slots; struct ck_spinlock_anderson_thread *slots;
unsigned int count; unsigned int count;
unsigned int wrap; 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; unsigned int next;
}; };
typedef struct ck_spinlock_anderson ck_spinlock_anderson_t; 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->slots = slots;
lock->count = count; lock->count = count;
lock->mask = count - 1;
lock->next = 0; lock->next = 0;
/* /*
@ -113,7 +115,7 @@ ck_spinlock_anderson_lock(struct ck_spinlock_anderson *lock,
position %= count; position %= count;
} else { } else {
position = ck_pr_faa_uint(&lock->next, 1); 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. */ /* 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; unsigned int position;
/* Mark next slot as available. */ /* Mark next slot as available. */
position = (slot->position + 1) % lock->count; if (lock->wrap == 0)
ck_pr_store_uint(&lock->slots[position].locked, false); position = (slot->position + 1) & lock->mask;
else
position = (slot->position + 1) % lock->count;
ck_pr_store_uint(&lock->slots[position].locked, false);
return; return;
} }
#endif /* CK_F_SPINLOCK_ANDERSON */ #endif /* CK_F_SPINLOCK_ANDERSON */

Loading…
Cancel
Save