Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/kern_rmlock.c
Show First 20 Lines • Show All 150 Lines • ▼ Show 20 Lines | unlock_rm(struct lock_object *lock) | ||||
else { | else { | ||||
/* | /* | ||||
* Find the right rm_priotracker structure for curthread. | * Find the right rm_priotracker structure for curthread. | ||||
* The guarantee about its uniqueness is given by the fact | * The guarantee about its uniqueness is given by the fact | ||||
* we already asserted the lock wasn't recursively acquired. | * we already asserted the lock wasn't recursively acquired. | ||||
*/ | */ | ||||
critical_enter(); | critical_enter(); | ||||
td = curthread; | td = curthread; | ||||
pc = pcpu_find(curcpu); | pc = get_pcpu(); | ||||
for (queue = pc->pc_rm_queue.rmq_next; | for (queue = pc->pc_rm_queue.rmq_next; | ||||
queue != &pc->pc_rm_queue; queue = queue->rmq_next) { | queue != &pc->pc_rm_queue; queue = queue->rmq_next) { | ||||
tracker = (struct rm_priotracker *)queue; | tracker = (struct rm_priotracker *)queue; | ||||
if ((tracker->rmp_rmlock == rm) && | if ((tracker->rmp_rmlock == rm) && | ||||
(tracker->rmp_thread == td)) { | (tracker->rmp_thread == td)) { | ||||
how = (uintptr_t)tracker; | how = (uintptr_t)tracker; | ||||
break; | break; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | |||||
static void | static void | ||||
rm_cleanIPI(void *arg) | rm_cleanIPI(void *arg) | ||||
{ | { | ||||
struct pcpu *pc; | struct pcpu *pc; | ||||
struct rmlock *rm = arg; | struct rmlock *rm = arg; | ||||
struct rm_priotracker *tracker; | struct rm_priotracker *tracker; | ||||
struct rm_queue *queue; | struct rm_queue *queue; | ||||
pc = pcpu_find(curcpu); | pc = get_pcpu(); | ||||
for (queue = pc->pc_rm_queue.rmq_next; queue != &pc->pc_rm_queue; | for (queue = pc->pc_rm_queue.rmq_next; queue != &pc->pc_rm_queue; | ||||
queue = queue->rmq_next) { | queue = queue->rmq_next) { | ||||
tracker = (struct rm_priotracker *)queue; | tracker = (struct rm_priotracker *)queue; | ||||
if (tracker->rmp_rmlock == rm && tracker->rmp_flags == 0) { | if (tracker->rmp_rmlock == rm && tracker->rmp_flags == 0) { | ||||
tracker->rmp_flags = RMPF_ONQUEUE; | tracker->rmp_flags = RMPF_ONQUEUE; | ||||
mtx_lock_spin(&rm_spinlock); | mtx_lock_spin(&rm_spinlock); | ||||
LIST_INSERT_HEAD(&rm->rm_activeReaders, tracker, | LIST_INSERT_HEAD(&rm->rm_activeReaders, tracker, | ||||
▲ Show 20 Lines • Show All 80 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
static int | static int | ||||
_rm_rlock_hard(struct rmlock *rm, struct rm_priotracker *tracker, int trylock) | _rm_rlock_hard(struct rmlock *rm, struct rm_priotracker *tracker, int trylock) | ||||
{ | { | ||||
struct pcpu *pc; | struct pcpu *pc; | ||||
critical_enter(); | critical_enter(); | ||||
pc = pcpu_find(curcpu); | pc = get_pcpu(); | ||||
/* Check if we just need to do a proper critical_exit. */ | /* Check if we just need to do a proper critical_exit. */ | ||||
if (!CPU_ISSET(pc->pc_cpuid, &rm->rm_writecpus)) { | if (!CPU_ISSET(pc->pc_cpuid, &rm->rm_writecpus)) { | ||||
critical_exit(); | critical_exit(); | ||||
return (1); | return (1); | ||||
} | } | ||||
/* Remove our tracker from the per-cpu list. */ | /* Remove our tracker from the per-cpu list. */ | ||||
▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | if (rm->lock_object.lo_flags & LO_SLEEPABLE) { | ||||
THREAD_SLEEPING_OK(); | THREAD_SLEEPING_OK(); | ||||
sx_xlock(&rm->rm_lock_sx); | sx_xlock(&rm->rm_lock_sx); | ||||
THREAD_NO_SLEEPING(); | THREAD_NO_SLEEPING(); | ||||
} else | } else | ||||
mtx_lock(&rm->rm_lock_mtx); | mtx_lock(&rm->rm_lock_mtx); | ||||
} | } | ||||
critical_enter(); | critical_enter(); | ||||
pc = pcpu_find(curcpu); | pc = get_pcpu(); | ||||
CPU_CLR(pc->pc_cpuid, &rm->rm_writecpus); | CPU_CLR(pc->pc_cpuid, &rm->rm_writecpus); | ||||
rm_tracker_add(pc, tracker); | rm_tracker_add(pc, tracker); | ||||
sched_pin(); | sched_pin(); | ||||
critical_exit(); | critical_exit(); | ||||
if (rm->lock_object.lo_flags & LO_SLEEPABLE) | if (rm->lock_object.lo_flags & LO_SLEEPABLE) | ||||
sx_xunlock(&rm->rm_lock_sx); | sx_xunlock(&rm->rm_lock_sx); | ||||
else | else | ||||
▲ Show 20 Lines • Show All 208 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
if (SCHEDULER_STOPPED()) | if (SCHEDULER_STOPPED()) | ||||
return (1); | return (1); | ||||
#ifdef INVARIANTS | #ifdef INVARIANTS | ||||
if (!(rm->lock_object.lo_flags & LO_RECURSABLE) && !trylock) { | if (!(rm->lock_object.lo_flags & LO_RECURSABLE) && !trylock) { | ||||
critical_enter(); | critical_enter(); | ||||
KASSERT(rm_trackers_present(pcpu_find(curcpu), rm, | KASSERT(rm_trackers_present(get_pcpu(), rm, | ||||
curthread) == 0, | curthread) == 0, | ||||
("rm_rlock: recursed on non-recursive rmlock %s @ %s:%d\n", | ("rm_rlock: recursed on non-recursive rmlock %s @ %s:%d\n", | ||||
rm->lock_object.lo_name, file, line)); | rm->lock_object.lo_name, file, line)); | ||||
critical_exit(); | critical_exit(); | ||||
} | } | ||||
#endif | #endif | ||||
KASSERT(kdb_active != 0 || !TD_IS_IDLETHREAD(curthread), | KASSERT(kdb_active != 0 || !TD_IS_IDLETHREAD(curthread), | ||||
("rm_rlock() by idle thread %p on rmlock %s @ %s:%d", | ("rm_rlock() by idle thread %p on rmlock %s @ %s:%d", | ||||
▲ Show 20 Lines • Show All 113 Lines • ▼ Show 20 Lines | if (rm_wowned(rm)) { | ||||
rm->lock_object.lo_name, file, line); | rm->lock_object.lo_name, file, line); | ||||
if (what & RA_RECURSED) | if (what & RA_RECURSED) | ||||
panic("Lock %s not recursed @ %s:%d\n", | panic("Lock %s not recursed @ %s:%d\n", | ||||
rm->lock_object.lo_name, file, line); | rm->lock_object.lo_name, file, line); | ||||
break; | break; | ||||
} | } | ||||
critical_enter(); | critical_enter(); | ||||
count = rm_trackers_present(pcpu_find(curcpu), rm, curthread); | count = rm_trackers_present(get_pcpu(), rm, curthread); | ||||
critical_exit(); | critical_exit(); | ||||
if (count == 0) | if (count == 0) | ||||
panic("Lock %s not %slocked @ %s:%d\n", | panic("Lock %s not %slocked @ %s:%d\n", | ||||
rm->lock_object.lo_name, (what & RA_RLOCKED) ? | rm->lock_object.lo_name, (what & RA_RLOCKED) ? | ||||
"read " : "", file, line); | "read " : "", file, line); | ||||
if (count > 1) { | if (count > 1) { | ||||
if (what & RA_NOTRECURSED) | if (what & RA_NOTRECURSED) | ||||
Show All 9 Lines | if (!rm_wowned(rm)) | ||||
rm->lock_object.lo_name, file, line); | rm->lock_object.lo_name, file, line); | ||||
break; | break; | ||||
case RA_UNLOCKED: | case RA_UNLOCKED: | ||||
if (rm_wowned(rm)) | if (rm_wowned(rm)) | ||||
panic("Lock %s exclusively locked @ %s:%d\n", | panic("Lock %s exclusively locked @ %s:%d\n", | ||||
rm->lock_object.lo_name, file, line); | rm->lock_object.lo_name, file, line); | ||||
critical_enter(); | critical_enter(); | ||||
count = rm_trackers_present(pcpu_find(curcpu), rm, curthread); | count = rm_trackers_present(get_pcpu(), rm, curthread); | ||||
critical_exit(); | critical_exit(); | ||||
if (count != 0) | if (count != 0) | ||||
panic("Lock %s read locked @ %s:%d\n", | panic("Lock %s read locked @ %s:%d\n", | ||||
rm->lock_object.lo_name, file, line); | rm->lock_object.lo_name, file, line); | ||||
break; | break; | ||||
default: | default: | ||||
panic("Unknown rm lock assertion: %d @ %s:%d", what, file, | panic("Unknown rm lock assertion: %d @ %s:%d", what, file, | ||||
▲ Show 20 Lines • Show All 52 Lines • Show Last 20 Lines |