From 182b3de789119b6c4eed4b46c2483f6f3a7cc8b4 Mon Sep 17 00:00:00 2001 From: mheily Date: Sat, 27 Feb 2010 22:50:45 +0000 Subject: [PATCH] remove freebsd code from module, causes too many problems git-svn-id: svn://svn.code.sf.net/p/libkqueue/code/trunk@221 fb4e3144-bc1c-4b72-a658-5bcd248dd7f7 --- kern/freebsd-compat.h | 30 --- kern/knlist.c | 442 ------------------------------------------ kern/kqueue.c | 135 ------------- 3 files changed, 607 deletions(-) delete mode 100644 kern/freebsd-compat.h delete mode 100644 kern/knlist.c diff --git a/kern/freebsd-compat.h b/kern/freebsd-compat.h deleted file mode 100644 index 45c4cf7..0000000 --- a/kern/freebsd-compat.h +++ /dev/null @@ -1,30 +0,0 @@ -/*- - * Copyright (c) 2010 Mark Heily - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* Dumping ground for compatibility shims */ - -struct mtx { - spinlock_t mtx_slock; -}; diff --git a/kern/knlist.c b/kern/knlist.c deleted file mode 100644 index 6878055..0000000 --- a/kern/knlist.c +++ /dev/null @@ -1,442 +0,0 @@ -//from kern_event.c - -/* XXX - ensure not KN_INFLUX?? */ -#define KNOTE_ACTIVATE(kn, islock) do { \ - if ((islock)) \ - mtx_assert(&(kn)->kn_kq->kq_lock, MA_OWNED); \ - else \ - KQ_LOCK((kn)->kn_kq); \ - (kn)->kn_status |= KN_ACTIVE; \ - if (((kn)->kn_status & (KN_QUEUED | KN_DISABLED)) == 0) \ - knote_enqueue((kn)); \ - if (!(islock)) \ - KQ_UNLOCK((kn)->kn_kq); \ -} while(0) -#define KQ_LOCK(kq) do { \ - mtx_lock(&(kq)->kq_lock); \ -} while (0) -#define KQ_FLUX_WAKEUP(kq) do { \ - if (((kq)->kq_state & KQ_FLUXWAIT) == KQ_FLUXWAIT) { \ - (kq)->kq_state &= ~KQ_FLUXWAIT; \ - wakeup((kq)); \ - } \ -} while (0) -#define KQ_UNLOCK_FLUX(kq) do { \ - KQ_FLUX_WAKEUP(kq); \ - mtx_unlock(&(kq)->kq_lock); \ -} while (0) -#define KQ_UNLOCK(kq) do { \ - mtx_unlock(&(kq)->kq_lock); \ -} while (0) -#define KQ_OWNED(kq) do { \ - mtx_assert(&(kq)->kq_lock, MA_OWNED); \ -} while (0) -#define KQ_NOTOWNED(kq) do { \ - mtx_assert(&(kq)->kq_lock, MA_NOTOWNED); \ -} while (0) -#define KN_LIST_LOCK(kn) do { \ - if (kn->kn_knlist != NULL) \ - kn->kn_knlist->kl_lock(kn->kn_knlist->kl_lockarg); \ -} while (0) -#define KN_LIST_UNLOCK(kn) do { \ - if (kn->kn_knlist != NULL) \ - kn->kn_knlist->kl_unlock(kn->kn_knlist->kl_lockarg); \ -} while (0) -#define KNL_ASSERT_LOCK(knl, islocked) do { \ - if (islocked) \ - KNL_ASSERT_LOCKED(knl); \ - else \ - KNL_ASSERT_UNLOCKED(knl); \ -} while (0) -#ifdef INVARIANTS -#define KNL_ASSERT_LOCKED(knl) do { \ - knl->kl_assert_locked((knl)->kl_lockarg); \ -} while (0) -#define KNL_ASSERT_UNLOCKED(knl) do { \ - knl->kl_assert_unlocked((knl)->kl_lockarg); \ -} while (0) -#else /* !INVARIANTS */ -#define KNL_ASSERT_LOCKED(knl) do {} while(0) -#define KNL_ASSERT_UNLOCKED(knl) do {} while (0) -#endif /* INVARIANTS */ - -#define KN_HASHSIZE 64 /* XXX should be tunable */ -#define KN_HASH(val, mask) (((val) ^ (val >> 8)) & (mask)) - -/* - * add a knote to a knlist - */ -void -knlist_add(struct knlist *knl, struct knote *kn, int islocked) -{ - KNL_ASSERT_LOCK(knl, islocked); - KQ_NOTOWNED(kn->kn_kq); - KASSERT((kn->kn_status & (KN_INFLUX|KN_DETACHED)) == - (KN_INFLUX|KN_DETACHED), ("knote not KN_INFLUX and KN_DETACHED")); - if (!islocked) - knl->kl_lock(knl->kl_lockarg); - SLIST_INSERT_HEAD(&knl->kl_list, kn, kn_selnext); - if (!islocked) - knl->kl_unlock(knl->kl_lockarg); - KQ_LOCK(kn->kn_kq); - kn->kn_knlist = knl; - kn->kn_status &= ~KN_DETACHED; - KQ_UNLOCK(kn->kn_kq); -} - -static void -knlist_remove_kq(struct knlist *knl, struct knote *kn, int knlislocked, int kqislocked) -{ - KASSERT(!(!!kqislocked && !knlislocked), ("kq locked w/o knl locked")); - KNL_ASSERT_LOCK(knl, knlislocked); - mtx_assert(&kn->kn_kq->kq_lock, kqislocked ? MA_OWNED : MA_NOTOWNED); - if (!kqislocked) - KASSERT((kn->kn_status & (KN_INFLUX|KN_DETACHED)) == KN_INFLUX, - ("knlist_remove called w/o knote being KN_INFLUX or already removed")); - if (!knlislocked) - knl->kl_lock(knl->kl_lockarg); - SLIST_REMOVE(&knl->kl_list, kn, knote, kn_selnext); - kn->kn_knlist = NULL; - if (!knlislocked) - knl->kl_unlock(knl->kl_lockarg); - if (!kqislocked) - KQ_LOCK(kn->kn_kq); - kn->kn_status |= KN_DETACHED; - if (!kqislocked) - KQ_UNLOCK(kn->kn_kq); -} - -/* - * remove all knotes from a specified klist - */ -void -knlist_remove(struct knlist *knl, struct knote *kn, int islocked) -{ - - knlist_remove_kq(knl, kn, islocked, 0); -} - -/* - * remove knote from a specified klist while in f_event handler. - */ -void -knlist_remove_inevent(struct knlist *knl, struct knote *kn) -{ - - knlist_remove_kq(knl, kn, 1, - (kn->kn_status & KN_HASKQLOCK) == KN_HASKQLOCK); -} - -int -knlist_empty(struct knlist *knl) -{ - KNL_ASSERT_LOCKED(knl); - return SLIST_EMPTY(&knl->kl_list); -} - -static struct mtx knlist_lock; -MTX_SYSINIT(knlist_lock, &knlist_lock, "knlist lock for lockless objects", - MTX_DEF); -static void knlist_mtx_lock(void *arg); -static void knlist_mtx_unlock(void *arg); - -static void -knlist_mtx_lock(void *arg) -{ - mtx_lock((struct mtx *)arg); -} - -static void -knlist_mtx_unlock(void *arg) -{ - mtx_unlock((struct mtx *)arg); -} - -static void -knlist_mtx_assert_locked(void *arg) -{ - mtx_assert((struct mtx *)arg, MA_OWNED); -} - -static void -knlist_mtx_assert_unlocked(void *arg) -{ - mtx_assert((struct mtx *)arg, MA_NOTOWNED); -} - -void -knlist_init(struct knlist *knl, void *lock, void (*kl_lock)(void *), - void (*kl_unlock)(void *), - void (*kl_assert_locked)(void *), void (*kl_assert_unlocked)(void *)) -{ - - if (lock == NULL) - knl->kl_lockarg = &knlist_lock; - else - knl->kl_lockarg = lock; - - if (kl_lock == NULL) - knl->kl_lock = knlist_mtx_lock; - else - knl->kl_lock = kl_lock; - if (kl_unlock == NULL) - knl->kl_unlock = knlist_mtx_unlock; - else - knl->kl_unlock = kl_unlock; - if (kl_assert_locked == NULL) - knl->kl_assert_locked = knlist_mtx_assert_locked; - else - knl->kl_assert_locked = kl_assert_locked; - if (kl_assert_unlocked == NULL) - knl->kl_assert_unlocked = knlist_mtx_assert_unlocked; - else - knl->kl_assert_unlocked = kl_assert_unlocked; - - SLIST_INIT(&knl->kl_list); -} - -void -knlist_init_mtx(struct knlist *knl, struct mtx *lock) -{ - - knlist_init(knl, lock, NULL, NULL, NULL, NULL); -} - -void -knlist_destroy(struct knlist *knl) -{ - -#ifdef INVARIANTS - /* - * if we run across this error, we need to find the offending - * driver and have it call knlist_clear. - */ - if (!SLIST_EMPTY(&knl->kl_list)) - printf("WARNING: destroying knlist w/ knotes on it!\n"); -#endif - - knl->kl_lockarg = knl->kl_lock = knl->kl_unlock = NULL; - SLIST_INIT(&knl->kl_list); -} - -/* - * Even if we are locked, we may need to drop the lock to allow any influx - * knotes time to "settle". - */ -void -knlist_cleardel(struct knlist *knl, struct thread *td, int islocked, int killkn) -{ - struct knote *kn, *kn2; - struct kqueue *kq; - - if (islocked) - KNL_ASSERT_LOCKED(knl); - else { - KNL_ASSERT_UNLOCKED(knl); -again: /* need to reacquire lock since we have dropped it */ - knl->kl_lock(knl->kl_lockarg); - } - - SLIST_FOREACH_SAFE(kn, &knl->kl_list, kn_selnext, kn2) { - kq = kn->kn_kq; - KQ_LOCK(kq); - if ((kn->kn_status & KN_INFLUX)) { - KQ_UNLOCK(kq); - continue; - } - knlist_remove_kq(knl, kn, 1, 1); - if (killkn) { - kn->kn_status |= KN_INFLUX | KN_DETACHED; - KQ_UNLOCK(kq); - knote_drop(kn, td); - } else { - /* Make sure cleared knotes disappear soon */ - kn->kn_flags |= (EV_EOF | EV_ONESHOT); - KQ_UNLOCK(kq); - } - kq = NULL; - } - - if (!SLIST_EMPTY(&knl->kl_list)) { - /* there are still KN_INFLUX remaining */ - kn = SLIST_FIRST(&knl->kl_list); - kq = kn->kn_kq; - KQ_LOCK(kq); - KASSERT(kn->kn_status & KN_INFLUX, - ("knote removed w/o list lock")); - knl->kl_unlock(knl->kl_lockarg); - kq->kq_state |= KQ_FLUXWAIT; - msleep(kq, &kq->kq_lock, PSOCK | PDROP, "kqkclr", 0); - kq = NULL; - goto again; - } - - if (islocked) - KNL_ASSERT_LOCKED(knl); - else { - knl->kl_unlock(knl->kl_lockarg); - KNL_ASSERT_UNLOCKED(knl); - } -} - -/* - * Remove all knotes referencing a specified fd must be called with FILEDESC - * lock. This prevents a race where a new fd comes along and occupies the - * entry and we attach a knote to the fd. - */ -void -knote_fdclose(struct thread *td, int fd) -{ - struct filedesc *fdp = td->td_proc->p_fd; - struct kqueue *kq; - struct knote *kn; - int influx; - - FILEDESC_XLOCK_ASSERT(fdp); - - /* - * We shouldn't have to worry about new kevents appearing on fd - * since filedesc is locked. - */ - KNL_ASSERT_UNLOCKED(knl); - } -} - -/* - * Remove all knotes referencing a specified fd must be called with FILEDESC - * lock. This prevents a race where a new fd comes along and occupies the - * entry and we attach a knote to the fd. - */ -void -knote_fdclose(struct thread *td, int fd) -{ - struct filedesc *fdp = td->td_proc->p_fd; - struct kqueue *kq; - struct knote *kn; - int influx; - - FILEDESC_XLOCK_ASSERT(fdp); - - /* - * We shouldn't have to worry about new kevents appearing on fd - * since filedesc is locked. - */ - SLIST_FOREACH(kq, &fdp->fd_kqlist, kq_list) { - KQ_LOCK(kq); - -again: - influx = 0; - while (kq->kq_knlistsize > fd && - (kn = SLIST_FIRST(&kq->kq_knlist[fd])) != NULL) { - if (kn->kn_status & KN_INFLUX) { - /* someone else might be waiting on our knote */ - if (influx) - wakeup(kq); - kq->kq_state |= KQ_FLUXWAIT; - msleep(kq, &kq->kq_lock, PSOCK, "kqflxwt", 0); - goto again; - } - kn->kn_status |= KN_INFLUX; - KQ_UNLOCK(kq); - if (!(kn->kn_status & KN_DETACHED)) - kn->kn_fop->f_detach(kn); - knote_drop(kn, td); - influx = 1; - KQ_LOCK(kq); - } - KQ_UNLOCK_FLUX(kq); - } -} - -static int -knote_attach(struct knote *kn, struct kqueue *kq) -{ - struct klist *list; - - KASSERT(kn->kn_status & KN_INFLUX, ("knote not marked INFLUX")); - KQ_OWNED(kq); - - if (kn->kn_fop->f_isfd) { - if (kn->kn_id >= kq->kq_knlistsize) - return ENOMEM; - list = &kq->kq_knlist[kn->kn_id]; - } else { - if (kq->kq_knhash == NULL) - return ENOMEM; - list = &kq->kq_knhash[KN_HASH(kn->kn_id, kq->kq_knhashmask)]; - } - - SLIST_INSERT_HEAD(list, kn, kn_link); -#ifdef INVARIANTS - /* - * if we run across this error, we need to find the offending - * driver and have it call knlist_clear. - */ - if (!SLIST_EMPTY(&knl->kl_list)) - printf("WARNING: destroying knlist w/ knotes on it!\n"); -#endif - - knl->kl_lockarg = knl->kl_lock = knl->kl_unlock = NULL; - SLIST_INIT(&knl->kl_list); -} - -/* - * Even if we are locked, we may need to drop the lock to allow any influx - * knotes time to "settle". - */ -void -knlist_cleardel(struct knlist *knl, struct thread *td, int islocked, int killkn) -{ - struct knote *kn, *kn2; - struct kqueue *kq; - - if (islocked) - KNL_ASSERT_LOCKED(knl); - else { - KNL_ASSERT_UNLOCKED(knl); -again: /* need to reacquire lock since we have dropped it */ - knl->kl_lock(knl->kl_lockarg); - } - - SLIST_FOREACH_SAFE(kn, &knl->kl_list, kn_selnext, kn2) { - kq = kn->kn_kq; - KQ_LOCK(kq); - if ((kn->kn_status & KN_INFLUX)) { - KQ_UNLOCK(kq); - continue; - } - knlist_remove_kq(knl, kn, 1, 1); - if (killkn) { - kn->kn_status |= KN_INFLUX | KN_DETACHED; - KQ_UNLOCK(kq); - knote_drop(kn, td); - } else { - /* Make sure cleared knotes disappear soon */ - kn->kn_flags |= (EV_EOF | EV_ONESHOT); - KQ_UNLOCK(kq); - } - kq = NULL; - } - - if (!SLIST_EMPTY(&knl->kl_list)) { - /* there are still KN_INFLUX remaining */ - kn = SLIST_FIRST(&knl->kl_list); - kq = kn->kn_kq; - KQ_LOCK(kq); - KASSERT(kn->kn_status & KN_INFLUX, - ("knote removed w/o list lock")); - knl->kl_unlock(knl->kl_lockarg); - kq->kq_state |= KQ_FLUXWAIT; - msleep(kq, &kq->kq_lock, PSOCK | PDROP, "kqkclr", 0); - kq = NULL; - goto again; - } - - if (islocked) - KNL_ASSERT_LOCKED(knl); - else { - knl->kl_unlock(knl->kl_lockarg); - KNL_ASSERT_UNLOCKED(knl); - } -} - diff --git a/kern/kqueue.c b/kern/kqueue.c index 4e293d0..fbdab10 100644 --- a/kern/kqueue.c +++ b/kern/kqueue.c @@ -45,7 +45,6 @@ #include "../include/sys/event.h" #include "queue.h" -#include "freebsd-compat.h" static int kqueue_open (struct inode *inode, struct file *file); static int kqueue_release (struct inode *inode, struct file *file); @@ -69,140 +68,6 @@ struct kqueue_data { spinlock_t kq_lock; }; -/************* BEGIN COPY FROM sys/event.h ***************************/ - -/* - * Flags for knote call - */ -#define KNF_LISTLOCKED 0x0001 /* knlist is locked */ -#define KNF_NOKQLOCK 0x0002 /* do not keep KQ_LOCK */ - -#define KNOTE(list, hist, flags) knote(list, hist, flags) -#define KNOTE_LOCKED(list, hint) knote(list, hint, KNF_LISTLOCKED) -#define KNOTE_UNLOCKED(list, hint) knote(list, hint, 0) - -#define KNLIST_EMPTY(list) SLIST_EMPTY(&(list)->kl_list) - -struct knote; - -/* - * Flag indicating hint is a signal. Used by EVFILT_SIGNAL, and also - * shared by EVFILT_PROC (all knotes attached to p->p_klist) - */ -#define NOTE_SIGNAL 0x08000000 - -struct filterops { - int f_isfd; /* true if ident == filedescriptor */ - int (*f_attach)(struct knote *kn); - void (*f_detach)(struct knote *kn); - int (*f_event)(struct knote *kn, long hint); -}; - -/* - * Setting the KN_INFLUX flag enables you to unlock the kq that this knote - * is on, and modify kn_status as if you had the KQ lock. - * - * kn_sfflags, kn_sdata, and kn_kevent are protected by the knlist lock. - */ -struct knote { - SLIST_ENTRY(knote) kn_link; /* for kq */ - SLIST_ENTRY(knote) kn_selnext; /* for struct selinfo */ - struct knlist *kn_knlist; /* f_attach populated */ - TAILQ_ENTRY(knote) kn_tqe; - struct kqueue *kn_kq; /* which queue we are on */ - struct kevent kn_kevent; - int kn_status; /* protected by kq lock */ -#define KN_ACTIVE 0x01 /* event has been triggered */ -#define KN_QUEUED 0x02 /* event is on queue */ -#define KN_DISABLED 0x04 /* event is disabled */ -#define KN_DETACHED 0x08 /* knote is detached */ -#define KN_INFLUX 0x10 /* knote is in flux */ -#define KN_MARKER 0x20 /* ignore this knote */ -#define KN_KQUEUE 0x40 /* this knote belongs to a kq */ -#define KN_HASKQLOCK 0x80 /* for _inevent */ - int kn_sfflags; /* saved filter flags */ - intptr_t kn_sdata; /* saved data field */ - union { - struct file *p_fp; /* file data pointer */ - struct proc *p_proc; /* proc pointer */ - struct aiocblist *p_aio; /* AIO job pointer */ - struct aioliojob *p_lio; /* LIO job pointer */ - } kn_ptr; - struct filterops *kn_fop; - void *kn_hook; - -#define kn_id kn_kevent.ident -#define kn_filter kn_kevent.filter -#define kn_flags kn_kevent.flags -#define kn_fflags kn_kevent.fflags -#define kn_data kn_kevent.data -#define kn_fp kn_ptr.p_fp -}; -static void filt_kqdetach(struct knote *kn); -static int filt_kqueue(struct knote *kn, long hint); -static int filt_procattach(struct knote *kn); -static void filt_procdetach(struct knote *kn); -static int filt_proc(struct knote *kn, long hint); -static int filt_fileattach(struct knote *kn); -static void filt_timerexpire(void *knx); -static int filt_timerattach(struct knote *kn); -static void filt_timerdetach(struct knote *kn); -static int filt_timer(struct knote *kn, long hint); - -static struct filterops file_filtops = - { 1, filt_fileattach, NULL, NULL }; -static struct filterops kqread_filtops = - { 1, NULL, filt_kqdetach, filt_kqueue }; -/* XXX - move to kern_proc.c? */ -static struct filterops proc_filtops = - { 0, filt_procattach, filt_procdetach, filt_proc }; -static struct filterops timer_filtops = - { 0, filt_timerattach, filt_timerdetach, filt_timer }; - -/************* END COPY FROM sys/event.h ***************************/ - -/************* BEGIN COPY FROM kern_event.c ***************************/ - -static int -filt_nullattach(struct knote *kn) -{ - - return (ENXIO); -}; - -struct filterops null_filtops = - { 0, filt_nullattach, NULL, NULL }; - -/* XXX - make SYSINIT to add these, and move into respective modules. */ -extern struct filterops sig_filtops; -extern struct filterops fs_filtops; - -/* - * Table for for all system-defined filters. - */ -static DEFINE_SPINLOCK(filterops_lock); -static struct { - struct filterops *for_fop; - int for_refcnt; -} sysfilt_ops[EVFILT_SYSCOUNT] = { - { &file_filtops }, /* EVFILT_READ */ - { &file_filtops }, /* EVFILT_WRITE */ - { &null_filtops }, /* EVFILT_AIO */ - { &file_filtops }, /* EVFILT_VNODE */ - { &proc_filtops }, /* EVFILT_PROC */ - { &sig_filtops }, /* EVFILT_SIGNAL */ - { &timer_filtops }, /* EVFILT_TIMER */ - { &file_filtops }, /* EVFILT_NETDEV */ - { &fs_filtops }, /* EVFILT_FS */ - { &null_filtops }, /* EVFILT_LIO */ -}; - -/************* END COPY FROM kern_event.c ***************************/ - - -#include "knlist.c" - -/*************** BEGIN ORIGINAL CODE ********************************/ static int major; static struct class *kqueue_class; static struct task_struct *kq_thread;