summaryrefslogtreecommitdiffstats
path: root/src/include
diff options
context:
space:
mode:
authordgilbert <dgilbert@us.ibm.com>2011-06-03 12:54:41 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2011-06-17 12:23:52 -0500
commit609d6810b8bc92dc979f8bbb8e7e7d7b7b5d9490 (patch)
treecd517ec2e10a95638e675b037bb24e2d01296ef4 /src/include
parentf64ba52098e248e62b4ddb14c0a027c21066e9e2 (diff)
downloadtalos-hostboot-609d6810b8bc92dc979f8bbb8e7e7d7b7b5d9490.tar.gz
talos-hostboot-609d6810b8bc92dc979f8bbb8e7e7d7b7b5d9490.zip
Initial futex support
Change-Id: I51a4f1117085ce23c7993c1a38e4124596636726 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/141 Tested-by: Jenkins Server Reviewed-by: Douglas R. Gilbert <dgilbert@us.ibm.com> Reviewed-by: Thi N. Tran <thi@us.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/include')
-rw-r--r--src/include/errno.h7
-rw-r--r--src/include/kernel/cpu.H4
-rw-r--r--src/include/kernel/futexmgr.H89
-rw-r--r--src/include/kernel/syscalls.H15
-rw-r--r--src/include/kernel/usermutex.H18
-rw-r--r--src/include/sys/mmio.h4
-rw-r--r--src/include/sys/mutex.h20
-rw-r--r--src/include/sys/sync.h89
-rw-r--r--src/include/usr/trace/trace.H2
9 files changed, 196 insertions, 52 deletions
diff --git a/src/include/errno.h b/src/include/errno.h
new file mode 100644
index 000000000..664c3d46c
--- /dev/null
+++ b/src/include/errno.h
@@ -0,0 +1,7 @@
+#ifndef _ERRNO_H
+#define _ERRNO_H
+
+#define EAGAIN 11 // Try again
+#define EWOULDBLOCK EAGAIN // operation would block
+
+#endif
diff --git a/src/include/kernel/cpu.H b/src/include/kernel/cpu.H
index 87e769743..0f36dd941 100644
--- a/src/include/kernel/cpu.H
+++ b/src/include/kernel/cpu.H
@@ -9,7 +9,7 @@
#include <kernel/types.h>
#include <arch/ppc.H>
#include <builtins.h>
-#include <sys/mutex.h>
+#include <sys/sync.h>
// Thread ID support only, Power7 (4 threads).
#define KERNEL_MAX_SUPPORTED_CPUS (4 * 8 * 4) // Sockets, cores, threads.
@@ -36,7 +36,7 @@ struct cpu_t
task_t* idle_task;
/** XSCOM mutex to serialize access per CPU */
- mutex_t xscom_mutex;
+ mutex_t * xscom_mutex;
};
/** @fn getCpuId
diff --git a/src/include/kernel/futexmgr.H b/src/include/kernel/futexmgr.H
new file mode 100644
index 000000000..824175136
--- /dev/null
+++ b/src/include/kernel/futexmgr.H
@@ -0,0 +1,89 @@
+#ifndef FUTEXMGR
+#define FUTEXMGR
+
+/**
+ * @file futexmgr.H
+ * @brief Declaration for kernel side futex management
+ */
+
+#include <stdint.h>
+#include <util/locked/list.H>
+#include <kernel/spinlock.H>
+
+struct task_t;
+
+
+/**
+ * @class FutexManager
+ * Kernel internal management of fuxtexs
+ */
+class FutexManager
+{
+ public:
+
+ /**
+ * 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
+ */
+ 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
+ */
+ static uint64_t wake(uint64_t * i_addr, uint64_t i_count);
+
+ protected:
+
+ /**
+ * Ctor
+ */
+ FutexManager() {};
+
+ /**
+ * Dtor
+ */
+ ~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
+ */
+ 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);
+
+ private: // data
+
+ struct _FutexWait_t
+ {
+ _FutexWait_t * next; ///< next _FutexWait_t in list
+ _FutexWait_t * prev; ///< prev _FutexWait_t in list
+ uint64_t * key; ///< search key is futex address
+ task_t* task; ///< task on wait list
+ };
+
+ typedef Util::Locked::List<_FutexWait_t, uint64_t *> FutexList_t;
+
+ Spinlock iv_lock; ///< lock
+ FutexList_t iv_list; ///< List of waiting tasks for all futexes
+};
+
+#endif
+
diff --git a/src/include/kernel/syscalls.H b/src/include/kernel/syscalls.H
index 1b87c5019..26e2bdf75 100644
--- a/src/include/kernel/syscalls.H
+++ b/src/include/kernel/syscalls.H
@@ -24,15 +24,6 @@ namespace Systemcalls
/** task_end() */
TASK_END,
- /** mutex_create() */
- MUTEX_CREATE,
- /** mutex_destroy() */
- MUTEX_DESTROY,
- /** mutex_lock() */
- MUTEX_LOCK_CONTESTED,
- /** mutex_unlock() */
- MUTEX_UNLOCK_CONTESTED,
-
/** msgq_create() */
MSGQ_CREATE,
/** msgq_destroy() */
@@ -59,6 +50,12 @@ namespace Systemcalls
/** nanosleep() */
TIME_NANOSLEEP,
+ /** futex_wait() */
+ FUTEX_WAIT,
+
+ /** futex_wake() */
+ FUTEX_WAKE,
+
SYSCALL_MAX
};
diff --git a/src/include/kernel/usermutex.H b/src/include/kernel/usermutex.H
deleted file mode 100644
index c9f631579..000000000
--- a/src/include/kernel/usermutex.H
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef __KERNEL_USERMUTEX_H
-#define __KERNEL_USERMUTEX_H
-
-#include <util/locked/queue.H>
-#include <kernel/spinlock.H>
-#include <kernel/task.H>
-
-struct UserMutex
-{
- uint64_t value;
- bool unlock_pend;
- Spinlock lock;
- Util::Locked::Queue<task_t> waiting;
-
- UserMutex() : value(0), unlock_pend(false) {};
-};
-
-#endif
diff --git a/src/include/sys/mmio.h b/src/include/sys/mmio.h
index c36a13821..3536071c8 100644
--- a/src/include/sys/mmio.h
+++ b/src/include/sys/mmio.h
@@ -2,7 +2,7 @@
#define __SYS_MMIO_H
#include <stdint.h>
-#include <sys/mutex.h>
+#include <sys/sync.h>
#ifdef __cplusplus
extern "C"
@@ -38,7 +38,7 @@ int mmio_hmer_write(uint64_t value);
* affinity pin. If the pin is moved the mutex is no longer
* guarenteed for the CPU the task is executing on.
*/
-mutex_t mmio_xscom_mutex();
+mutex_t * mmio_xscom_mutex();
#ifdef __cplusplus
}
diff --git a/src/include/sys/mutex.h b/src/include/sys/mutex.h
deleted file mode 100644
index 3eca65f06..000000000
--- a/src/include/sys/mutex.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef __SYS_MUTEX_H
-#define __SYS_MUTEX_H
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-typedef void* mutex_t;
-
-mutex_t mutex_create();
-int mutex_destroy(mutex_t);
-
-int mutex_lock(mutex_t);
-int mutex_unlock(mutex_t);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/src/include/sys/sync.h b/src/include/sys/sync.h
new file mode 100644
index 000000000..68b570aec
--- /dev/null
+++ b/src/include/sys/sync.h
@@ -0,0 +1,89 @@
+#ifndef SYNC
+#define SYNC
+
+#include <stdint.h>
+
+/**
+ * Mutex object type
+ */
+struct _futex_imp_t
+{
+ uint64_t iv_val;
+};
+
+typedef _futex_imp_t mutex_t;
+
+/**
+ * Barrier object type
+ */
+struct _barrier_imp_t
+{
+ mutex_t iv_mutex;
+ uint64_t iv_event;
+ uint64_t iv_missing;
+ uint64_t iv_count;
+};
+
+typedef _barrier_imp_t barrier_t;
+
+#define MUTEX_INITIALIZER {0}
+
+/**
+ * Initialize a barrier object
+ * @param[out] o_barrier The barrier
+ * @param[in] i_count The number of threads to wait on
+ * @pre an unitiailized barrier object
+ * @post a valid barrier object
+ */
+void barrier_init (barrier_t * o_barrier, uint64_t i_count);
+
+/**
+ * Destroy a barrier
+ * @param[in] i_barrier The barrier
+ */
+void barrier_destroy (barrier_t * i_barrier);
+
+/**
+ * Wait on a barrier
+ * @param[in] i_barrier The barrier
+ * @post this thread will be blocked until the barrier count is reached.
+ */
+void barrier_wait (barrier_t * i_barrier);
+
+/**
+ * Create a mutex and initialize a mutex
+ * @returns a pointer to the mutex
+ */
+mutex_t * mutex_create();
+
+/**
+ * Initialize a mutex object
+ * @param[out] o_mutex the mutex
+ * @pre an uninitialized mutex object
+ * @post a valid mutex object
+ */
+void mutex_init(mutex_t * o_mutex);
+
+/**
+ * Destroy a mutex
+ * @param[in/out] i_mutex The mutex
+ * @pre mutex must have been created with mutex_create()
+ */
+void mutex_destroy(mutex_t *& io_mutex);
+
+/**
+ * Obtain a lock on a mutex
+ * @param[in] i_mutex The mutex
+ * @post returns when this thread has the lock
+ */
+void mutex_lock(mutex_t * i_mutex);
+
+/**
+ * Release a lock on a mutex
+ * @param[in] i_mutex the mutex
+ * @returns non zero on error
+ * @post mutex lock release
+ */
+void mutex_unlock(mutex_t * i_mutex);
+
+#endif
diff --git a/src/include/usr/trace/trace.H b/src/include/usr/trace/trace.H
index 722d31929..e4ea8922c 100644
--- a/src/include/usr/trace/trace.H
+++ b/src/include/usr/trace/trace.H
@@ -15,7 +15,7 @@
#include <stdint.h>
#include <trace/interface.H>
#include <util/singleton.H>
-#include <sys/mutex.h>
+#include <sys/sync.h>
/******************************************************************************/
// Globals/Constants
OpenPOWER on IntegriCloud