diff options
author | phk <phk@FreeBSD.org> | 2004-11-17 07:39:58 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2004-11-17 07:39:58 +0000 |
commit | 3dab450860a416318f4975a44933d133725c58bb (patch) | |
tree | fc2f3ae8dd58585583da1e142f53250efe72fb5e | |
parent | a94fe69bb706e2f650c3f695ff3920d6f3a0ed9f (diff) | |
download | FreeBSD-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
-rw-r--r-- | sys/sys/filedesc.h | 65 |
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; |