Deleted Added
full compact
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 ---