Deleted Added
full compact
kern_sx.c (164246) kern_sx.c (167012)
1/*-
2 * Copyright (C) 2001 Jason Evans <jasone@freebsd.org>. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice(s), this list of conditions and the following disclaimer as

--- 20 unchanged lines hidden (view full) ---

29 * Shared/exclusive locks. This implementation assures deterministic lock
30 * granting behavior, so that slocks and xlocks are interleaved.
31 *
32 * Priority propagation will not generally raise the priority of lock holders,
33 * so should not be relied upon in combination with sx locks.
34 */
35
36#include <sys/cdefs.h>
1/*-
2 * Copyright (C) 2001 Jason Evans <jasone@freebsd.org>. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice(s), this list of conditions and the following disclaimer as

--- 20 unchanged lines hidden (view full) ---

29 * Shared/exclusive locks. This implementation assures deterministic lock
30 * granting behavior, so that slocks and xlocks are interleaved.
31 *
32 * Priority propagation will not generally raise the priority of lock holders,
33 * so should not be relied upon in combination with sx locks.
34 */
35
36#include <sys/cdefs.h>
37__FBSDID("$FreeBSD: head/sys/kern/kern_sx.c 164246 2006-11-13 05:41:46Z kmacy $");
37__FBSDID("$FreeBSD: head/sys/kern/kern_sx.c 167012 2007-02-26 08:26:44Z kmacy $");
38
39#include "opt_ddb.h"
40
41#include <sys/param.h>
42#include <sys/systm.h>
43#include <sys/ktr.h>
44#include <sys/linker_set.h>
45#include <sys/condvar.h>

--- 60 unchanged lines hidden (view full) ---

106 lock_profile_object_destroy(&sx->sx_object);
107 lock_destroy(&sx->sx_object);
108}
109
110void
111_sx_slock(struct sx *sx, const char *file, int line)
112{
113 uint64_t waittime = 0;
38
39#include "opt_ddb.h"
40
41#include <sys/param.h>
42#include <sys/systm.h>
43#include <sys/ktr.h>
44#include <sys/linker_set.h>
45#include <sys/condvar.h>

--- 60 unchanged lines hidden (view full) ---

106 lock_profile_object_destroy(&sx->sx_object);
107 lock_destroy(&sx->sx_object);
108}
109
110void
111_sx_slock(struct sx *sx, const char *file, int line)
112{
113 uint64_t waittime = 0;
114 int contested;
114 int contested = 0;
115
116 mtx_lock(sx->sx_lock);
117 KASSERT(sx->sx_xholder != curthread,
118 ("%s (%s): slock while xlock is held @ %s:%d\n", __func__,
119 sx->sx_object.lo_name, file, line));
120 WITNESS_CHECKORDER(&sx->sx_object, LOP_NEWORDER, file, line);
121
122 /*
123 * Loop in case we lose the race for lock acquisition.
124 */
115
116 mtx_lock(sx->sx_lock);
117 KASSERT(sx->sx_xholder != curthread,
118 ("%s (%s): slock while xlock is held @ %s:%d\n", __func__,
119 sx->sx_object.lo_name, file, line));
120 WITNESS_CHECKORDER(&sx->sx_object, LOP_NEWORDER, file, line);
121
122 /*
123 * Loop in case we lose the race for lock acquisition.
124 */
125 if (sx->sx_cnt < 0)
126 lock_profile_waitstart(&waittime);
127 while (sx->sx_cnt < 0) {
128 sx->sx_shrd_wcnt++;
125 while (sx->sx_cnt < 0) {
126 sx->sx_shrd_wcnt++;
129 lock_profile_obtain_lock_failed(&sx->sx_object, &contested);
127 lock_profile_obtain_lock_failed(&sx->sx_object, &contested, &waittime);
130 cv_wait(&sx->sx_shrd_cv, sx->sx_lock);
131 sx->sx_shrd_wcnt--;
132 }
133
134 /* Acquire a shared lock. */
135 sx->sx_cnt++;
136
137 if (sx->sx_cnt == 1)
128 cv_wait(&sx->sx_shrd_cv, sx->sx_lock);
129 sx->sx_shrd_wcnt--;
130 }
131
132 /* Acquire a shared lock. */
133 sx->sx_cnt++;
134
135 if (sx->sx_cnt == 1)
138 lock_profile_obtain_lock_success(&sx->sx_object, waittime, file, line);
136 lock_profile_obtain_lock_success(&sx->sx_object, contested, waittime, file, line);
139
140 LOCK_LOG_LOCK("SLOCK", &sx->sx_object, 0, 0, file, line);
141 WITNESS_LOCK(&sx->sx_object, 0, file, line);
142 curthread->td_locks++;
143
144 mtx_unlock(sx->sx_lock);
145}
146

--- 14 unchanged lines hidden (view full) ---

161 mtx_unlock(sx->sx_lock);
162 return (0);
163 }
164}
165
166void
167_sx_xlock(struct sx *sx, const char *file, int line)
168{
137
138 LOCK_LOG_LOCK("SLOCK", &sx->sx_object, 0, 0, file, line);
139 WITNESS_LOCK(&sx->sx_object, 0, file, line);
140 curthread->td_locks++;
141
142 mtx_unlock(sx->sx_lock);
143}
144

--- 14 unchanged lines hidden (view full) ---

159 mtx_unlock(sx->sx_lock);
160 return (0);
161 }
162}
163
164void
165_sx_xlock(struct sx *sx, const char *file, int line)
166{
169 int contested;
167 int contested = 0;
170 uint64_t waittime = 0;
171
172 mtx_lock(sx->sx_lock);
173
174 /*
175 * With sx locks, we're absolutely not permitted to recurse on
176 * xlocks, as it is fatal (deadlock). Normally, recursion is handled
177 * by WITNESS, but as it is not semantically correct to hold the
178 * xlock while in here, we consider it API abuse and put it under
179 * INVARIANTS.
180 */
181 KASSERT(sx->sx_xholder != curthread,
182 ("%s (%s): xlock already held @ %s:%d", __func__,
183 sx->sx_object.lo_name, file, line));
184 WITNESS_CHECKORDER(&sx->sx_object, LOP_NEWORDER | LOP_EXCLUSIVE, file,
185 line);
186
168 uint64_t waittime = 0;
169
170 mtx_lock(sx->sx_lock);
171
172 /*
173 * With sx locks, we're absolutely not permitted to recurse on
174 * xlocks, as it is fatal (deadlock). Normally, recursion is handled
175 * by WITNESS, but as it is not semantically correct to hold the
176 * xlock while in here, we consider it API abuse and put it under
177 * INVARIANTS.
178 */
179 KASSERT(sx->sx_xholder != curthread,
180 ("%s (%s): xlock already held @ %s:%d", __func__,
181 sx->sx_object.lo_name, file, line));
182 WITNESS_CHECKORDER(&sx->sx_object, LOP_NEWORDER | LOP_EXCLUSIVE, file,
183 line);
184
187 if (sx->sx_cnt)
188 lock_profile_waitstart(&waittime);
189 /* Loop in case we lose the race for lock acquisition. */
190 while (sx->sx_cnt != 0) {
191 sx->sx_excl_wcnt++;
185 /* Loop in case we lose the race for lock acquisition. */
186 while (sx->sx_cnt != 0) {
187 sx->sx_excl_wcnt++;
192 lock_profile_obtain_lock_failed(&sx->sx_object, &contested);
188 lock_profile_obtain_lock_failed(&sx->sx_object, &contested, &waittime);
193 cv_wait(&sx->sx_excl_cv, sx->sx_lock);
194 sx->sx_excl_wcnt--;
195 }
196
197 MPASS(sx->sx_cnt == 0);
198
199 /* Acquire an exclusive lock. */
200 sx->sx_cnt--;
201 sx->sx_xholder = curthread;
202
189 cv_wait(&sx->sx_excl_cv, sx->sx_lock);
190 sx->sx_excl_wcnt--;
191 }
192
193 MPASS(sx->sx_cnt == 0);
194
195 /* Acquire an exclusive lock. */
196 sx->sx_cnt--;
197 sx->sx_xholder = curthread;
198
203 lock_profile_obtain_lock_success(&sx->sx_object, waittime, file, line);
199 lock_profile_obtain_lock_success(&sx->sx_object, contested, waittime, file, line);
204 LOCK_LOG_LOCK("XLOCK", &sx->sx_object, 0, 0, file, line);
205 WITNESS_LOCK(&sx->sx_object, LOP_EXCLUSIVE, file, line);
206 curthread->td_locks++;
207
208 mtx_unlock(sx->sx_lock);
209}
210
211int

--- 260 unchanged lines hidden ---
200 LOCK_LOG_LOCK("XLOCK", &sx->sx_object, 0, 0, file, line);
201 WITNESS_LOCK(&sx->sx_object, LOP_EXCLUSIVE, file, line);
202 curthread->td_locks++;
203
204 mtx_unlock(sx->sx_lock);
205}
206
207int

--- 260 unchanged lines hidden ---