kern_rmlock.c (253047) | kern_rmlock.c (255745) |
---|---|
1/*- 2 * Copyright (c) 2007 Stephan Uphoff <ups@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 18 unchanged lines hidden (view full) --- 27 * SUCH DAMAGE. 28 */ 29 30/* 31 * Machine independent bits of reader/writer lock implementation. 32 */ 33 34#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2007 Stephan Uphoff <ups@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 18 unchanged lines hidden (view full) --- 27 * SUCH DAMAGE. 28 */ 29 30/* 31 * Machine independent bits of reader/writer lock implementation. 32 */ 33 34#include <sys/cdefs.h> |
35__FBSDID("$FreeBSD: head/sys/kern/kern_rmlock.c 253047 2013-07-08 21:17:20Z jhb $"); | 35__FBSDID("$FreeBSD: head/sys/kern/kern_rmlock.c 255745 2013-09-20 23:06:21Z davide $"); |
36 37#include "opt_ddb.h" 38#include "opt_kdtrace.h" 39 40#include <sys/param.h> 41#include <sys/systm.h> 42 43#include <sys/kernel.h> --- 28 unchanged lines hidden (view full) --- 72#ifndef INVARIANTS 73#define _rm_assert(c, what, file, line) 74#endif 75 76static void assert_rm(const struct lock_object *lock, int what); 77#ifdef DDB 78static void db_show_rm(const struct lock_object *lock); 79#endif | 36 37#include "opt_ddb.h" 38#include "opt_kdtrace.h" 39 40#include <sys/param.h> 41#include <sys/systm.h> 42 43#include <sys/kernel.h> --- 28 unchanged lines hidden (view full) --- 72#ifndef INVARIANTS 73#define _rm_assert(c, what, file, line) 74#endif 75 76static void assert_rm(const struct lock_object *lock, int what); 77#ifdef DDB 78static void db_show_rm(const struct lock_object *lock); 79#endif |
80static void lock_rm(struct lock_object *lock, int how); | 80static void lock_rm(struct lock_object *lock, uintptr_t how); |
81#ifdef KDTRACE_HOOKS 82static int owner_rm(const struct lock_object *lock, struct thread **owner); 83#endif | 81#ifdef KDTRACE_HOOKS 82static int owner_rm(const struct lock_object *lock, struct thread **owner); 83#endif |
84static int unlock_rm(struct lock_object *lock); | 84static uintptr_t unlock_rm(struct lock_object *lock); |
85 86struct lock_class lock_class_rm = { 87 .lc_name = "rm", 88 .lc_flags = LC_SLEEPLOCK | LC_RECURSABLE, 89 .lc_assert = assert_rm, 90#ifdef DDB 91 .lc_ddb_show = db_show_rm, 92#endif --- 20 unchanged lines hidden (view full) --- 113 114static void 115assert_rm(const struct lock_object *lock, int what) 116{ 117 118 rm_assert((const struct rmlock *)lock, what); 119} 120 | 85 86struct lock_class lock_class_rm = { 87 .lc_name = "rm", 88 .lc_flags = LC_SLEEPLOCK | LC_RECURSABLE, 89 .lc_assert = assert_rm, 90#ifdef DDB 91 .lc_ddb_show = db_show_rm, 92#endif --- 20 unchanged lines hidden (view full) --- 113 114static void 115assert_rm(const struct lock_object *lock, int what) 116{ 117 118 rm_assert((const struct rmlock *)lock, what); 119} 120 |
121/* 122 * These do not support read locks because it would be hard to make 123 * the tracker work correctly with the current lock_class API as you 124 * would need to have the tracker pointer available when calling 125 * rm_rlock() in lock_rm(). 126 */ | |
127static void | 121static void |
128lock_rm(struct lock_object *lock, int how) | 122lock_rm(struct lock_object *lock, uintptr_t how) |
129{ 130 struct rmlock *rm; | 123{ 124 struct rmlock *rm; |
125 struct rm_priotracker *tracker; |
|
131 132 rm = (struct rmlock *)lock; | 126 127 rm = (struct rmlock *)lock; |
133 if (how) | 128 if (how == 0) |
134 rm_wlock(rm); | 129 rm_wlock(rm); |
135#ifdef INVARIANTS 136 else 137 panic("lock_rm called in read mode"); 138#endif | 130 else { 131 tracker = (struct rm_priotracker *)how; 132 rm_rlock(rm, tracker); 133 } |
139} 140 | 134} 135 |
141static int | 136static uintptr_t |
142unlock_rm(struct lock_object *lock) 143{ | 137unlock_rm(struct lock_object *lock) 138{ |
139 struct thread *td; 140 struct pcpu *pc; |
|
144 struct rmlock *rm; | 141 struct rmlock *rm; |
142 struct rm_queue *queue; 143 struct rm_priotracker *tracker; 144 uintptr_t how; |
|
145 146 rm = (struct rmlock *)lock; | 145 146 rm = (struct rmlock *)lock; |
147 rm_wunlock(rm); 148 return (1); | 147 tracker = NULL; 148 how = 0; 149 rm_assert(rm, RA_LOCKED | RA_NOTRECURSED); 150 if (rm_wowned(rm)) 151 rm_wunlock(rm); 152 else { 153 /* 154 * Find the right rm_priotracker structure for curthread. 155 * The guarantee about its uniqueness is given by the fact 156 * we already asserted the lock wasn't recursively acquired. 157 */ 158 critical_enter(); 159 td = curthread; 160 pc = pcpu_find(curcpu); 161 for (queue = pc->pc_rm_queue.rmq_next; 162 queue != &pc->pc_rm_queue; queue = queue->rmq_next) { 163 tracker = (struct rm_priotracker *)queue; 164 if ((tracker->rmp_rmlock == rm) && 165 (tracker->rmp_thread == td)) { 166 how = (uintptr_t)tracker; 167 break; 168 } 169 } 170 KASSERT(tracker != NULL, 171 ("rm_priotracker is non-NULL when lock held in read mode")); 172 critical_exit(); 173 rm_runlock(rm, tracker); 174 } 175 return (how); |
149} 150 151#ifdef KDTRACE_HOOKS 152static int 153owner_rm(const struct lock_object *lock, struct thread **owner) 154{ 155 const struct rmlock *rm; 156 struct lock_class *lc; --- 675 unchanged lines hidden --- | 176} 177 178#ifdef KDTRACE_HOOKS 179static int 180owner_rm(const struct lock_object *lock, struct thread **owner) 181{ 182 const struct rmlock *rm; 183 struct lock_class *lc; --- 675 unchanged lines hidden --- |