Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/x68k/dev Replace tsleep(9)/wakeup(9) with condvar(9...



details:   https://anonhg.NetBSD.org/src/rev/3f3d5ddf363c
branches:  trunk
changeset: 327936:3f3d5ddf363c
user:      tsutsui <tsutsui%NetBSD.org@localhost>
date:      Fri Mar 21 16:58:54 2014 +0000

description:
Replace tsleep(9)/wakeup(9) with condvar(9) as practice.

Also replace malloc(9) with kmem_alloc(9).
Pevent more possible races.

Tested on both console and Xserver on X68030.

diffstat:

 sys/arch/x68k/dev/event.c     |  97 +++++++++++++++++++++++++++---------------
 sys/arch/x68k/dev/event_var.h |  26 +++--------
 sys/arch/x68k/dev/kbd.c       |  30 +++++++------
 sys/arch/x68k/dev/ms.c        |  36 +++++++-------
 4 files changed, 103 insertions(+), 86 deletions(-)

diffs (truncated from 525 to 300 lines):

diff -r 0ded8b896a74 -r 3f3d5ddf363c sys/arch/x68k/dev/event.c
--- a/sys/arch/x68k/dev/event.c Fri Mar 21 16:41:15 2014 +0000
+++ b/sys/arch/x68k/dev/event.c Fri Mar 21 16:58:54 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: event.c,v 1.13 2008/03/01 14:16:50 rmind Exp $ */
+/*     $NetBSD: event.c,v 1.14 2014/03/21 16:58:54 tsutsui Exp $ */
 
 /*
  * Copyright (c) 1992, 1993
@@ -45,16 +45,18 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: event.c,v 1.13 2008/03/01 14:16:50 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: event.c,v 1.14 2014/03/21 16:58:54 tsutsui Exp $");
 
 #include <sys/param.h>
 #include <sys/fcntl.h>
-#include <sys/malloc.h>
+#include <sys/kmem.h>
 #include <sys/proc.h>
 #include <sys/systm.h>
 #include <sys/vnode.h>
 #include <sys/select.h>
 #include <sys/poll.h>
+#include <sys/mutex.h>
+#include <sys/condvar.h>
 
 #include <machine/vuid_event.h>
 #include <x68k/dev/event_var.h>
@@ -63,13 +65,15 @@
  * Initialize a firm_event queue.
  */
 void
-ev_init(struct evvar *ev)
+ev_init(struct evvar *ev, const char *name, kmutex_t *mtx)
 {
 
        ev->ev_get = ev->ev_put = 0;
-       ev->ev_q = malloc((u_long)EV_QSIZE * sizeof(struct firm_event),
-           M_DEVBUF, M_WAITOK|M_ZERO);
+       ev->ev_q = kmem_zalloc((size_t)EV_QSIZE * sizeof(struct firm_event),
+           KM_SLEEP);
        selinit(&ev->ev_sel);
+       ev->ev_lock = mtx;
+       cv_init(&ev->ev_cv, name);
 }
 
 /*
@@ -79,8 +83,9 @@
 ev_fini(struct evvar *ev)
 {
 
+       cv_destroy(&ev->ev_cv);
        seldestroy(&ev->ev_sel);
-       free(ev->ev_q, M_DEVBUF);
+       kmem_free(ev->ev_q, (size_t)EV_QSIZE * sizeof(struct firm_event));
 }
 
 /*
@@ -90,23 +95,23 @@
 int
 ev_read(struct evvar *ev, struct uio *uio, int flags)
 {
-       int s, n, cnt, error;
+       int n, cnt, put, error;
 
        /*
         * Make sure we can return at least 1.
         */
        if (uio->uio_resid < sizeof(struct firm_event))
                return (EMSGSIZE);      /* ??? */
-       s = splev();
+       mutex_enter(ev->ev_lock);
        while (ev->ev_get == ev->ev_put) {
                if (flags & IO_NDELAY) {
-                       splx(s);
+                       mutex_exit(ev->ev_lock);
                        return (EWOULDBLOCK);
                }
-               ev->ev_wanted = 1;
-               error = tsleep((void *)ev, PEVENT | PCATCH, "firm_event", 0);
-               if (error) {
-                       splx(s);
+               ev->ev_wanted = true;
+               error = cv_wait_sig(&ev->ev_cv, ev->ev_lock);
+               if (error != 0) {
+                       mutex_exit(ev->ev_lock);
                        return (error);
                }
        }
@@ -118,7 +123,8 @@
                cnt = EV_QSIZE - ev->ev_get;    /* events in [get..QSIZE) */
        else
                cnt = ev->ev_put - ev->ev_get;  /* events in [get..put) */
-       splx(s);
+       put = ev->ev_put;
+       mutex_exit(ev->ev_lock);
        n = howmany(uio->uio_resid, sizeof(struct firm_event));
        if (cnt > n)
                cnt = n;
@@ -131,7 +137,7 @@
         * is anything there to move.
         */
        if ((ev->ev_get = (ev->ev_get + cnt) % EV_QSIZE) != 0 ||
-           n == 0 || error || (cnt = ev->ev_put) == 0)
+           n == 0 || error || (cnt = put) == 0)
                return (error);
        if (cnt > n)
                cnt = n;
@@ -144,9 +150,9 @@
 int
 ev_poll(struct evvar *ev, int events, struct lwp *l)
 {
-       int s, revents = 0;
+       int revents = 0;
 
-       s = splev();
+       mutex_enter(ev->ev_lock);
        if (events & (POLLIN | POLLRDNORM)) {
                if (ev->ev_get == ev->ev_put)
                        selrecord(l, &ev->ev_sel);
@@ -154,38 +160,60 @@
                        revents |= events & (POLLIN | POLLRDNORM);
        }
        revents |= events & (POLLOUT | POLLWRNORM);
-       splx(s);
+       mutex_exit(ev->ev_lock);
        return (revents);
 }
 
+void
+ev_wakeup(struct evvar *ev)
+{
+
+       mutex_enter(ev->ev_lock);
+       selnotify(&ev->ev_sel, 0, 0);
+       if (ev->ev_wanted) {
+               ev->ev_wanted = false;
+               cv_signal(&ev->ev_cv);
+       }
+       mutex_exit(ev->ev_lock);
+
+       if (ev->ev_async) {
+               mutex_enter(proc_lock);
+               psignal(ev->ev_io, SIGIO);
+               mutex_exit(proc_lock);
+       }
+}
+
 static void
 filt_evrdetach(struct knote *kn)
 {
        struct evvar *ev = kn->kn_hook;
-       int s;
 
-       s = splev();
+       mutex_enter(ev->ev_lock);
        SLIST_REMOVE(&ev->ev_sel.sel_klist, kn, knote, kn_selnext);
-       splx(s);
+       mutex_exit(ev->ev_lock);
 }
 
 static int
 filt_evread(struct knote *kn, long hint)
 {
        struct evvar *ev = kn->kn_hook;
-
-       if (ev->ev_get == ev->ev_put)
-               return (0);
+       int rv = 1;
 
-       if (ev->ev_get < ev->ev_put)
-               kn->kn_data = ev->ev_put - ev->ev_get;
-       else
-               kn->kn_data = (EV_QSIZE - ev->ev_get) +
-                   ev->ev_put;
+       mutex_enter(ev->ev_lock);
+       if (ev->ev_get == ev->ev_put) {
+               rv = 0;
+       } else {
+               if (ev->ev_get < ev->ev_put)
+                       kn->kn_data = ev->ev_put - ev->ev_get;
+               else
+                       kn->kn_data = (EV_QSIZE - ev->ev_get) +
+                           ev->ev_put;
 
-       kn->kn_data *= sizeof(struct firm_event);
+               kn->kn_data *= sizeof(struct firm_event);
+       }
+       mutex_exit(ev->ev_lock);
 
-       return (1);
+       return rv;
 }
 
 static const struct filterops ev_filtops =
@@ -195,7 +223,6 @@
 ev_kqfilter(struct evvar *ev, struct knote *kn)
 {
        struct klist *klist;
-       int s;
 
        switch (kn->kn_filter) {
        case EVFILT_READ:
@@ -209,9 +236,9 @@
 
        kn->kn_hook = ev;
 
-       s = splev();
+       mutex_enter(ev->ev_lock);
        SLIST_INSERT_HEAD(klist, kn, kn_selnext);
-       splx(s);
+       mutex_exit(ev->ev_lock);
 
        return (0);
 }
diff -r 0ded8b896a74 -r 3f3d5ddf363c sys/arch/x68k/dev/event_var.h
--- a/sys/arch/x68k/dev/event_var.h     Fri Mar 21 16:41:15 2014 +0000
+++ b/sys/arch/x68k/dev/event_var.h     Fri Mar 21 16:58:54 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: event_var.h,v 1.9 2012/08/15 19:13:58 tsutsui Exp $ */
+/*     $NetBSD: event_var.h,v 1.10 2014/03/21 16:58:54 tsutsui Exp $ */
 
 /*
  * Copyright (c) 1992, 1993
@@ -54,31 +54,19 @@
        volatile u_int ev_put;  /* put (write) index (modified by interrupt) */
        struct  selinfo ev_sel; /* process selecting */
        struct  proc *ev_io;    /* process that opened queue (can get SIGIO) */
-       char    ev_wanted;      /* wake up on input ready */
-       char    ev_async;       /* send SIGIO on input ready */
+       bool    ev_wanted;      /* wake up on input ready */
+       bool    ev_async;       /* send SIGIO on input ready */
        struct  firm_event *ev_q;/* circular buffer (queue) of events */
+       kmutex_t *ev_lock;      /* lock from the parent device */
+       kcondvar_t ev_cv;       /* condvar(9) to delever signal */
 };
 
-#define        splev() spltty()
-
-#define        EV_WAKEUP(ev) { \
-       selnotify(&(ev)->ev_sel, 0, 0); \
-       if ((ev)->ev_wanted) { \
-               (ev)->ev_wanted = 0; \
-               wakeup((void *)(ev)); \
-       } \
-       if ((ev)->ev_async) { \
-               mutex_enter(proc_lock); \
-               psignal((ev)->ev_io, SIGIO); \
-               mutex_exit(proc_lock); \
-       } \
-}
-
-void   ev_init(struct evvar *);
+void   ev_init(struct evvar *, const char *, kmutex_t *);
 void   ev_fini(struct evvar *);
 int    ev_read(struct evvar *, struct uio *, int);
 int    ev_select(struct evvar *, int, struct lwp *);
 int    ev_poll(struct evvar *, int, struct lwp *);
+void   ev_wakeup(struct evvar *);
 int    ev_kqfilter(struct evvar *, struct knote *);
 
 /*
diff -r 0ded8b896a74 -r 3f3d5ddf363c sys/arch/x68k/dev/kbd.c
--- a/sys/arch/x68k/dev/kbd.c   Fri Mar 21 16:41:15 2014 +0000
+++ b/sys/arch/x68k/dev/kbd.c   Fri Mar 21 16:58:54 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kbd.c,v 1.38 2014/03/16 05:20:26 dholland Exp $        */
+/*     $NetBSD: kbd.c,v 1.39 2014/03/21 16:58:54 tsutsui Exp $ */
 
 /*
  * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kbd.c,v 1.38 2014/03/16 05:20:26 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kbd.c,v 1.39 2014/03/21 16:58:54 tsutsui Exp $");
 
 #include "ite.h"
 #include "bell.h"
@@ -50,6 +50,7 @@
 #include <sys/cpu.h>
 #include <sys/bus.h>
 #include <sys/intr.h>
+#include <sys/mutex.h>
 
 #include <arch/x68k/dev/intiovar.h>
 #include <arch/x68k/dev/mfp.h>
@@ -63,9 +64,11 @@
 #include <machine/vuid_event.h>
 
 struct kbd_softc {
+       device_t sc_dev;
        int sc_event_mode;      /* if true, collect events, else pass to ite */
        struct evvar sc_events; /* event queue state */
        void *sc_softintr_cookie;
+       kmutex_t sc_lock;
 };



Home | Main Index | Thread Index | Old Index