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