Pull ticket-spinaphore into release branch
This commit is contained in:
@@ -100,24 +100,36 @@ wrap_mmu_context (struct mm_struct *mm)
|
|||||||
* this primitive it can be moved up to a spinaphore.h header.
|
* this primitive it can be moved up to a spinaphore.h header.
|
||||||
*/
|
*/
|
||||||
struct spinaphore {
|
struct spinaphore {
|
||||||
atomic_t cur;
|
unsigned long ticket;
|
||||||
|
unsigned long serve;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void spinaphore_init(struct spinaphore *ss, int val)
|
static inline void spinaphore_init(struct spinaphore *ss, int val)
|
||||||
{
|
{
|
||||||
atomic_set(&ss->cur, val);
|
ss->ticket = 0;
|
||||||
|
ss->serve = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void down_spin(struct spinaphore *ss)
|
static inline void down_spin(struct spinaphore *ss)
|
||||||
{
|
{
|
||||||
while (unlikely(!atomic_add_unless(&ss->cur, -1, 0)))
|
unsigned long t = ia64_fetchadd(1, &ss->ticket, acq), serve;
|
||||||
while (atomic_read(&ss->cur) == 0)
|
|
||||||
|
if (time_before(t, ss->serve))
|
||||||
|
return;
|
||||||
|
|
||||||
|
ia64_invala();
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
asm volatile ("ld4.c.nc %0=[%1]" : "=r"(serve) : "r"(&ss->serve) : "memory");
|
||||||
|
if (time_before(t, serve))
|
||||||
|
return;
|
||||||
cpu_relax();
|
cpu_relax();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static inline void up_spin(struct spinaphore *ss)
|
static inline void up_spin(struct spinaphore *ss)
|
||||||
{
|
{
|
||||||
atomic_add(1, &ss->cur);
|
ia64_fetchadd(1, &ss->serve, rel);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct spinaphore ptcg_sem;
|
static struct spinaphore ptcg_sem;
|
||||||
|
Reference in New Issue
Block a user