summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2004-11-17 07:39:58 +0000
committerphk <phk@FreeBSD.org>2004-11-17 07:39:58 +0000
commit3dab450860a416318f4975a44933d133725c58bb (patch)
treefc2f3ae8dd58585583da1e142f53250efe72fb5e /sys
parenta94fe69bb706e2f650c3f695ff3920d6f3a0ed9f (diff)
downloadFreeBSD-src-3dab450860a416318f4975a44933d133725c58bb.zip
FreeBSD-src-3dab450860a416318f4975a44933d133725c58bb.tar.gz
Split the FILEDESC_LOCK in two variants.
FILEDESC_LOCK_FAST will just grab the interlocking mutex and hold it. This should be used for simple modifications of a field. FILEDESC_LOCK holds a (homegrown) sleepable lock which should be used where sleeping is required. The homegrown lock will probably be replaced with a generic type of lock once we have found out how that should look. Help and reviews by: rwatson
Diffstat (limited to 'sys')
-rw-r--r--sys/sys/filedesc.h65
1 files changed, 57 insertions, 8 deletions
diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h
index d3cb5e2..fe606e3 100644
--- a/sys/sys/filedesc.h
+++ b/sys/sys/filedesc.h
@@ -35,6 +35,7 @@
#include <sys/queue.h>
#include <sys/event.h>
+#include <sys/priority.h>
#include <sys/_lock.h>
#include <sys/_mutex.h>
@@ -60,12 +61,13 @@ struct filedesc {
u_short fd_refcnt; /* reference count */
struct mtx fd_mtx; /* protects members of this struct */
+ int fd_locked; /* long lock flag */
+ int fd_wanted; /* "" */
struct kqlist fd_kqlist; /* list of kqueues on this filedesc */
int fd_holdleaderscount; /* block fdfree() for shared close() */
int fd_holdleaderswakeup; /* fdfree() needs wakeup */
};
-
/*
* Structure to keep track of (process leader, struct fildedesc) tuples.
* Each process has a pointer to such a structure when detailed tracking
@@ -93,14 +95,61 @@ struct filedesc_to_leader {
#ifdef _KERNEL
/* Lock a file descriptor table. */
-#define FILEDESC_LOCK(fd) mtx_lock(&(fd)->fd_mtx)
-#define FILEDESC_UNLOCK(fd) mtx_unlock(&(fd)->fd_mtx)
-#define FILEDESC_LOCKED(fd) mtx_owned(&(fd)->fd_mtx)
-#define FILEDESC_LOCK_ASSERT(fd, type) mtx_assert(&(fd)->fd_mtx, (type))
-#define FILEDESC_LOCK_DESC "filedesc structure"
+#define FILEDESC_LOCK(fd) \
+ do { \
+ mtx_lock(&(fd)->fd_mtx); \
+ (fd)->fd_wanted++; \
+ while ((fd)->fd_locked) \
+ msleep(&(fd)->fd_locked, &(fd)->fd_mtx, PLOCK, "fdesc", 0); \
+ (fd)->fd_locked = 2; \
+ (fd)->fd_wanted--; \
+ mtx_unlock(&(fd)->fd_mtx); \
+ } while (0);
+
+#define FILEDESC_UNLOCK(fd) \
+ do { \
+ mtx_lock(&(fd)->fd_mtx); \
+ KASSERT((fd)->fd_locked == 2, \
+ ("fdesc locking mistake %d should be %d", (fd)->fd_locked, 2)); \
+ (fd)->fd_locked = 0; \
+ if ((fd)->fd_wanted) \
+ wakeup(&(fd)->fd_locked); \
+ mtx_unlock(&(fd)->fd_mtx); \
+ } while (0);
+
+#define FILEDESC_LOCK_FAST(fd) \
+ do { \
+ mtx_lock(&(fd)->fd_mtx); \
+ (fd)->fd_wanted++; \
+ while ((fd)->fd_locked) \
+ msleep(&(fd)->fd_locked, &(fd)->fd_mtx, PLOCK, "fdesc", 0); \
+ (fd)->fd_locked = 1; \
+ (fd)->fd_wanted--; \
+ } while (0);
+
+#define FILEDESC_UNLOCK_FAST(fd) \
+ do { \
+ KASSERT((fd)->fd_locked == 1, \
+ ("fdesc locking mistake %d should be %d", (fd)->fd_locked, 1)); \
+ (fd)->fd_locked = 0; \
+ if ((fd)->fd_wanted) \
+ wakeup(&(fd)->fd_locked); \
+ mtx_unlock(&(fd)->fd_mtx); \
+ } while (0);
+
+#ifdef INVARIANT_SUPPORT
+#define FILEDESC_LOCK_ASSERT(fd, arg) \
+ do { \
+ if ((arg) == MA_OWNED) \
+ KASSERT((fd)->fd_locked != 0, ("fdesc locking mistake")); \
+ else \
+ KASSERT((fd)->fd_locked == 0, ("fdesc locking mistake")); \
+ } while (0);
+#else
+#define FILEDESC_LOCK_ASSERT(fd, arg)
+#endif
-#define FILEDESC_LOCK_FAST(fd) FILEDESC_LOCK(fd);
-#define FILEDESC_UNLOCK_FAST(fd) FILEDESC_UNLOCK(fd);
+#define FILEDESC_LOCK_DESC "filedesc structure"
struct thread;
OpenPOWER on IntegriCloud