diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2009-09-02 14:05:06 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2009-09-02 14:05:06 +0000 |
commit | 2de40a35d82ec6b2760a45b24d358182bf34e450 (patch) | |
tree | ff175cda8b291c8a3dbb2ee39d5fa6bd1e31b50a | |
parent | 41a51176f9e0dd52dfaffaab7ad0f3f12394606c (diff) |
when you add a task to a workq, it allocates memory to handle the
task and shove it on a list. allocations can fail, so if something
that wants to run a task later already has memory to handle the
workq task then let it provide it via a new function called
workq_queue_task.
ok kettenis@
-rw-r--r-- | sys/kern/kern_workq.c | 36 | ||||
-rw-r--r-- | sys/sys/workq.h | 20 |
2 files changed, 37 insertions, 19 deletions
diff --git a/sys/kern/kern_workq.c b/sys/kern/kern_workq.c index 6c98f35baf2..3f186e5c3e2 100644 --- a/sys/kern/kern_workq.c +++ b/sys/kern/kern_workq.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_workq.c,v 1.10 2009/06/24 14:56:41 jsg Exp $ */ +/* $OpenBSD: kern_workq.c,v 1.11 2009/09/02 14:05:05 dlg Exp $ */ /* * Copyright (c) 2007 David Gwynne <dlg@openbsd.org> @@ -26,15 +26,6 @@ #include <sys/kthread.h> #include <sys/workq.h> -struct workq_task { - int wqt_flags; - workq_fn wqt_func; - void *wqt_arg1; - void *wqt_arg2; - - SIMPLEQ_ENTRY(workq_task) wqt_entry; -}; - struct workq { int wq_flags; #define WQ_F_RUNNING (1<<0) @@ -54,6 +45,9 @@ struct workq workq_syswq = { "syswq" }; +/* if we allocate the wqt, we need to know we free it too */ +#define WQT_F_POOL (1 << 31) + void workq_init(void); /* called in init_main.c */ void workq_init_syswq(void *); void workq_create_thread(void *); @@ -127,27 +121,34 @@ int workq_add_task(struct workq *wq, int flags, workq_fn func, void *a1, void *a2) { struct workq_task *wqt; - - if (wq == NULL) - wq = &workq_syswq; wqt = pool_get(&workq_task_pool, (flags & WQ_WAITOK) ? PR_WAITOK : PR_NOWAIT); if (!wqt) return (ENOMEM); + workq_queue_task(wq, wqt, WQT_F_POOL | flags, func, a1, a2); + + return (0); +} + +void +workq_queue_task(struct workq *wq, struct workq_task *wqt, int flags, + workq_fn func, void *a1, void *a2) +{ wqt->wqt_flags = flags; wqt->wqt_func = func; wqt->wqt_arg1 = a1; wqt->wqt_arg2 = a2; + if (wq == NULL) + wq = &workq_syswq; + mtx_enter(&wq->wq_mtx); SIMPLEQ_INSERT_TAIL(&wq->wq_tasklist, wqt, wqt_entry); mtx_leave(&wq->wq_mtx); wakeup_one(wq); - - return (0); } void @@ -202,10 +203,13 @@ workq_thread(void *arg) { struct workq *wq = arg; struct workq_task *wqt; + int mypool; while ((wqt = workq_next_task(wq)) != NULL) { + mypool = (wqt->wqt_flags & WQT_F_POOL); wqt->wqt_func(wqt->wqt_arg1, wqt->wqt_arg2); - pool_put(&workq_task_pool, wqt); + if (mypool) + pool_put(&workq_task_pool, wqt); } kthread_exit(0); diff --git a/sys/sys/workq.h b/sys/sys/workq.h index 728dc64e6a4..dc7289a5af8 100644 --- a/sys/sys/workq.h +++ b/sys/sys/workq.h @@ -1,4 +1,4 @@ -/* $OpenBSD: workq.h,v 1.5 2008/10/30 23:55:22 dlg Exp $ */ +/* $OpenBSD: workq.h,v 1.6 2009/09/02 14:05:05 dlg Exp $ */ /* * Copyright (c) 2007 David Gwynne <dlg@openbsd.org> @@ -20,15 +20,29 @@ #ifndef _SYS_WORKQ_H_ #define _SYS_WORKQ_H_ -struct workq; +#include <sys/queue.h> + +typedef void (*workq_fn)(void *, void *); + +struct workq_task { + int wqt_flags; + workq_fn wqt_func; + void *wqt_arg1; + void *wqt_arg2; + + SIMPLEQ_ENTRY(workq_task) wqt_entry; +}; #define WQ_WAITOK (1<<0) #define WQ_MPSAFE (1<<1) -typedef void (*workq_fn)(void *, void *); +struct workq; + struct workq *workq_create(const char *, int, int); int workq_add_task(struct workq *, int /* flags */, workq_fn, void *, void *); +void workq_queue_task(struct workq *, struct workq_task *, + int /* flags */, workq_fn, void *, void *); void workq_destroy(struct workq *); #endif /* _SYS_WORKQ_H_ */ |