From: <ljs...@us...> - 2012-06-10 15:44:55
|
Revision: 811 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=811&view=rev Author: ljsebald Date: 2012-06-10 15:44:49 +0000 (Sun, 10 Jun 2012) Log Message: ----------- Add genwait_wake_thd() function. Modified Paths: -------------- kos/include/kos/genwait.h kos/kernel/thread/genwait.c Modified: kos/include/kos/genwait.h =================================================================== --- kos/include/kos/genwait.h 2012-06-09 23:16:30 UTC (rev 810) +++ kos/include/kos/genwait.h 2012-06-10 15:44:49 UTC (rev 811) @@ -25,7 +25,6 @@ #include <sys/cdefs.h> __BEGIN_DECLS -#include <sys/queue.h> #include <kos/thread.h> /** \brief Sleep on an object. @@ -106,6 +105,25 @@ */ void genwait_wake_one_err(void *obj, int err); +/** \brief Wake up a specific thread that is sleeping on an object. + + This function wakes up the specfied thread, assuming it is sleeping on the + specified object. + + \param obj The object to wake the thread from + \param thd The specific thread to wake + \param err The errno code to set as the errno value on the + woken thread. If this is 0 (EOK), then the thread's + errno will not be changed, and the thread will get a + return value of 0 from the genwait_wait(). If it is + non-zero, the thread will get a return value of -1 + and errno will be set to this value for the woken + threads. + \return The number of threads woken, which should be 1 on + success. +*/ +int genwait_wake_thd(void *obj, kthread_t *thd, int err); + /** \brief Look for timed out genwait_wait() calls. There should be no reason you need to call this function, it is called Modified: kos/kernel/thread/genwait.c =================================================================== --- kos/kernel/thread/genwait.c 2012-06-09 23:16:30 UTC (rev 810) +++ kos/kernel/thread/genwait.c 2012-06-10 15:44:49 UTC (rev 811) @@ -191,6 +191,48 @@ genwait_wake_cnt(obj, -1, err); } +int genwait_wake_thd(void *obj, kthread_t *thd, int err) { + kthread_t *t, *nt; + struct slpquehead *qp; + int old, rv = 0; + + /* Twiddle interrupt state */ + old = irq_disable(); + + /* Find the queue */ + qp = &slpque[LOOKUP(obj)]; + + /* Go through and find any matching entries */ + for(t = TAILQ_FIRST(qp); t != NULL; t = nt) { + /* Get the next thread up front */ + nt = TAILQ_NEXT(t, thdq); + + /* Is this thread a match? */ + if(t->wait_obj == obj && t == thd) { + /* Yes, remove it from the wait queue */ + genwait_unqueue(t); + + /* Set the wake return value */ + if(err) { + CONTEXT_RET(t->context) = -1; + t->thd_errno = err; + } + else { + CONTEXT_RET(t->context) = 0; + } + + /* We found it, so we're done... */ + rv = 1; + break; + } + } + + /* Re-fix IRQs */ + irq_restore(old); + + return rv; +} + void genwait_check_timeouts(uint64 tm) { kthread_t *t; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |