summaryrefslogtreecommitdiffstats
path: root/src/include
diff options
context:
space:
mode:
authorDoug Gilbert <dgilbert@us.ibm.com>2012-01-12 10:32:19 -0600
committerDouglas R. Gilbert <dgilbert@us.ibm.com>2012-01-25 10:54:55 -0600
commitc4f6f3ee887c0fa89c4ed5c311410363f6d61cb4 (patch)
treee309f1aaef54ba14d38bd7d09c63e456edd7a612 /src/include
parentcad6f41c5ceb5affe968a32618e4cf5d53cb7554 (diff)
downloadtalos-hostboot-c4f6f3ee887c0fa89c4ed5c311410363f6d61cb4.tar.gz
talos-hostboot-c4f6f3ee887c0fa89c4ed5c311410363f6d61cb4.zip
Conditional Variable support
Change-Id: Ib715b3a4e775ef183244e8769c6560a85ac19104 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/612 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/include')
-rw-r--r--src/include/kernel/futexmgr.H34
-rw-r--r--src/include/kernel/syscalls.H6
-rw-r--r--src/include/sys/sync.h78
3 files changed, 92 insertions, 26 deletions
diff --git a/src/include/kernel/futexmgr.H b/src/include/kernel/futexmgr.H
index 75fc31b08..aeba05291 100644
--- a/src/include/kernel/futexmgr.H
+++ b/src/include/kernel/futexmgr.H
@@ -53,12 +53,18 @@ class FutexManager
static uint64_t wait(task_t * i_task, uint64_t * i_addr, uint64_t i_val);
/**
- * Wakeup threads
- * @param[in] i_addr pointer to a futex
- * @param[in] i_count The max number of threads to wake
- * @returns The number of threads awoken
+ * Wakeup and optionally move waiting processes.
+ * @param[in] i_futex1 pointer to a futex
+ * @param[in] i_count1 The max number of tasks to wake
+ * @param[in] i_futex2 pointer to a futex, (default NULL) Optional
+ * futex to move i_count_2 unwoken tasks to.
+ * @param[in] i_count2 The max number of theads to move from futex1 to
+ * futex2. (default 0)
+ *
+ * @returns The number of tasks awoken
*/
- static uint64_t wake(uint64_t * i_addr, uint64_t i_count);
+ static uint64_t wake(uint64_t * i_futex1, uint64_t i_count1,
+ uint64_t * i_futex2 = NULL, uint64_t i_count2 = 0);
protected:
@@ -74,22 +80,12 @@ class FutexManager
private: // functions
- /**
- * Put the current processes on a wait queue
- * @param[in] i_task pointer to the current task structure
- * @param[in] i_addr Futex address
- * @param[in] i_val Value that *i_addr should contain
- * @returns [0 | error code] if *i_addr != i_val returns EWOULDBLOCK
- */
+ /** see wait(...) */
uint64_t _wait(task_t * i_task, uint64_t * i_addr, uint64_t i_val);
- /**
- * Wakeup threads
- * @param[in] i_addr pointer to a futex
- * @param[in] i_count The max number of threads to wake
- * @returns The number of threads awoken
- */
- uint64_t _wake(uint64_t * i_addr, uint64_t i_count);
+ /** see wake(...) */
+ uint64_t _wake(uint64_t * i_futex1, uint64_t i_count1,
+ uint64_t * i_futex2, uint64_t i_count2);
private: // data
diff --git a/src/include/kernel/syscalls.H b/src/include/kernel/syscalls.H
index 856666d74..e09171596 100644
--- a/src/include/kernel/syscalls.H
+++ b/src/include/kernel/syscalls.H
@@ -77,10 +77,8 @@ namespace Systemcalls
/** nanosleep() */
TIME_NANOSLEEP,
- /** futex_wait() */
- FUTEX_WAIT,
- /** futex_wake() */
- FUTEX_WAKE,
+ /** futex_wake() futex_wait() futex_requeue() */
+ SYS_FUTEX,
/** shutdown() */
MISC_SHUTDOWN,
diff --git a/src/include/sys/sync.h b/src/include/sys/sync.h
index d0074cbc5..58e5c9327 100644
--- a/src/include/sys/sync.h
+++ b/src/include/sys/sync.h
@@ -51,10 +51,31 @@ typedef _barrier_imp_t barrier_t;
#define MUTEX_INITIALIZER {0}
/**
+ * Conditional variable types
+ */
+struct _cond_imp_t
+{
+ mutex_t * mutex;
+ uint64_t sequence;
+};
+
+typedef _cond_imp_t sync_cond_t;
+
+
+#define COND_INITIALIZER {NULL, 0}
+
+enum _FUTEX_OP
+{
+ FUTEX_WAIT,
+ FUTEX_WAKE,
+ FUTEX_REQUEUE
+};
+
+/**
* @fn barrier_init
* @brief Initialize a barrier object
* @param[out] o_barrier The barrier
- * @param[in] i_count The number of threads to wait on
+ * @param[in] i_count The number of tasks to wait on
* @pre an uninitialized barrier object
* @post a valid barrier object
*/
@@ -72,7 +93,7 @@ void barrier_destroy (barrier_t * i_barrier);
/**
* @fn barrier_wait
* @brief Wait on a barrier
- * This thread will block until the barrier count is reached.
+ * This tasks will block until the barrier count is reached.
* @param[in] i_barrier The barrier
*/
void barrier_wait (barrier_t * i_barrier);
@@ -99,7 +120,7 @@ void mutex_destroy(mutex_t * i_mutex);
* @fn mutex_lock
* @brief Obtain a lock on a mutex
* @param[in] i_mutex - The mutex
- * @post returns when this thread has the lock
+ * @post returns when this task has the lock
*/
void mutex_lock(mutex_t * i_mutex);
@@ -111,4 +132,55 @@ void mutex_lock(mutex_t * i_mutex);
*/
void mutex_unlock(mutex_t * i_mutex);
+/**
+ * @fn sync_cond_init
+ * @brief Initialize a condtional variable
+ * @param i_cond, The conditional variable
+ * @post
+ */
+void sync_cond_init(sync_cond_t * i_cond);
+
+/**
+ * @fn sync_cond_destroy
+ * @brief Destroy a conditional variable
+ * @param i_cond, The conditional variable
+ */
+void sync_cond_destroy(sync_cond_t * i_cond);
+
+/**
+ * @fn sync_cond_wait
+ * @brief Block the calling task until the specified condition is signaled
+ * @param i_cond, The condition variable
+ * @param i_mutex, A mutex for which this task has the lock
+ * @pre This task must have the mutex lock
+ * @post This task will have the mutex lock
+ * @note i_mutex will be unlocked while this task is in the wait state.
+ * @note failing to lock the mutex before calling this function may cause it
+ * not to block
+ */
+int sync_cond_wait(sync_cond_t * i_cond, mutex_t * i_mutex);
+
+/**
+ * @fn sync_cond_signal
+ * @brief Signal to wake a task waiting on the condition varible.
+ * @param i_cond, The condition variable
+ * @pre This task must hold the lock on the mutex used in sync_cond_wait()
+ * @pre sync_cond_wait() must have been called for conditional variable
+ * @note failing to unlock the mutex after this call may cause the waiting
+ * task to remain blocked. If there is more than one task waiting on the
+ * conditional variable then sync_cond_broadcast() should be used instead.
+ */
+void sync_cond_signal(sync_cond_t * i_cond);
+
+/**
+ * @fn sync_cond_broadcast
+ * @brief Signal to wake all tasks waiting on the condition variable
+ * @param i_cond, The conditional variable
+ * @note same restrictions as sync_cond_signal() except this function should
+ * be used if there is more than one task waiting on the conditional variable.
+ * There is no guarantee on which waiting task will get the mutex lock first
+ * when this task unlocks the mutex.
+ */
+void sync_cond_broadcast(sync_cond_t * i_cond);
+
#endif
OpenPOWER on IntegriCloud