summaryrefslogtreecommitdiffstats
path: root/src/include
diff options
context:
space:
mode:
authorPatrick Williams <iawillia@us.ibm.com>2010-06-24 15:51:29 -0500
committerPatrick Williams <iawillia@us.ibm.com>2010-06-24 15:51:29 -0500
commit8085c7634979f38c1b152d0a35b98c2447ce497a (patch)
tree844b3527d7b1e8770540f77d1f95c59254aaca60 /src/include
parentf760d7d1b0a7872228870b84ebfa85ab9999eb54 (diff)
downloadtalos-hostboot-8085c7634979f38c1b152d0a35b98c2447ce497a.tar.gz
talos-hostboot-8085c7634979f38c1b152d0a35b98c2447ce497a.zip
Add messaging
Diffstat (limited to 'src/include')
-rw-r--r--src/include/kernel/msg.H28
-rw-r--r--src/include/kernel/syscalls.H10
-rw-r--r--src/include/string.h1
-rw-r--r--src/include/sys/msg.h47
-rw-r--r--src/include/util/locked/list.H153
-rw-r--r--src/include/util/locked/queue.H2
6 files changed, 240 insertions, 1 deletions
diff --git a/src/include/kernel/msg.H b/src/include/kernel/msg.H
new file mode 100644
index 000000000..7a32197f5
--- /dev/null
+++ b/src/include/kernel/msg.H
@@ -0,0 +1,28 @@
+#ifndef __KERNEL_MSG_H
+#define __KERNEL_MSG_H
+
+#include <kernel/types.h>
+#include <sys/msg.h>
+#include <util/locked/list.H>
+#include <util/locked/queue.H>
+
+struct MessagePending
+{
+ typedef msg_t* key_type;
+ key_type key;
+ task_t* task;
+
+ MessagePending* prev;
+ MessagePending* next;
+};
+
+class MessageQueue
+{
+ public:
+ Spinlock lock;
+ Util::Locked::List<MessagePending, MessagePending::key_type> messages;
+ Util::Locked::List<MessagePending, MessagePending::key_type> responses;
+ Util::Locked::Queue<task_t> waiting;
+};
+
+#endif
diff --git a/src/include/kernel/syscalls.H b/src/include/kernel/syscalls.H
index ebe7d0059..9a0672d63 100644
--- a/src/include/kernel/syscalls.H
+++ b/src/include/kernel/syscalls.H
@@ -15,6 +15,16 @@ namespace Systemcalls
MUTEX_LOCK_CONTESTED,
MUTEX_UNLOCK_CONTESTED,
+ MSGQ_CREATE,
+ MSGQ_DESTROY,
+ MSGQ_REGISTER_ROOT,
+ MSGQ_RESOLVE_ROOT,
+
+ MSG_SEND,
+ MSG_SENDRECV,
+ MSG_RESPOND,
+ MSG_WAIT,
+
SYSCALL_MAX
};
};
diff --git a/src/include/string.h b/src/include/string.h
index f1465a4c0..a2b704067 100644
--- a/src/include/string.h
+++ b/src/include/string.h
@@ -9,6 +9,7 @@ extern "C"
#endif
void* memset(void* s, int c, size_t n);
+ int strcmp(const char* s1, const char* s2);
#ifdef __cplusplus
};
diff --git a/src/include/sys/msg.h b/src/include/sys/msg.h
new file mode 100644
index 000000000..ca5dab7e6
--- /dev/null
+++ b/src/include/sys/msg.h
@@ -0,0 +1,47 @@
+#ifndef __SYS_MSG_H
+#define __SYS_MSG_H
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef void* msg_q_t;
+
+struct msg_t
+{
+ uint32_t type;
+ uint32_t __reserved__async;
+ uint64_t data[2];
+ void* extra_data;
+};
+
+// Message queue interfaces.
+msg_q_t msg_q_create();
+int msg_q_destroy();
+int msg_q_register(msg_q_t q, char* name);
+msg_q_t msg_q_resolve(char* name);
+
+// Message interfaces.
+__attribute__((always_inline))
+ inline msg_t* msg_allocate() { return (msg_t*)malloc(sizeof(msg_t)); }
+__attribute__((always_inline))
+ inline void msg_free(msg_t* m) { free(m); }
+
+int msg_send(msg_q_t q, msg_t* msg);
+int msg_sendrecv(msg_q_t q, msg_t* msg);
+int msg_respond(msg_q_t q, msg_t* msg);
+msg_t* msg_wait(msg_q_t q);
+
+__attribute__((always_inline))
+ inline uint32_t msg_is_async(msg_t* msg)
+ { return 0 == msg->__reserved__async; }
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/include/util/locked/list.H b/src/include/util/locked/list.H
new file mode 100644
index 000000000..e4bc0f99c
--- /dev/null
+++ b/src/include/util/locked/list.H
@@ -0,0 +1,153 @@
+#ifndef __UTIL_LOCKED_LIST_H
+#define __UTIL_LOCKED_LIST_H
+
+#include <util/locked/lock.H>
+
+namespace Util
+{
+ namespace Locked
+ {
+ template <typename _T, typename _K,
+ bool locked = false, typename _S = int>
+ class List
+ {
+ public:
+ List() : head(NULL), tail(NULL), lock() {};
+ ~List() {};
+
+ _T* remove();
+ void insert(_T*);
+
+ void erase(_T* node);
+ void erase(_K& key);
+
+ _T* find(_K& key);
+
+ protected:
+ _T* head;
+ _T* tail;
+
+ _S lock;
+
+ void __lock();
+ void __unlock();
+ };
+
+ template <typename _T, typename _K, bool locked, typename _S>
+ _T* List<_T,_K,locked,_S>::remove()
+ {
+ _T* item = NULL;
+
+ __lock();
+
+ if (tail != NULL)
+ {
+ item = tail;
+ if (head == tail)
+ head = tail = NULL;
+ else
+ tail = item->prev;
+ }
+
+ __unlock();
+
+ return item;
+ }
+
+ template <typename _T, typename _K, bool locked, typename _S>
+ void List<_T,_K,locked,_S>::insert(_T* item)
+ {
+ __lock();
+
+ if (head == NULL)
+ {
+ item->next = item->prev = NULL;
+ head = tail = item;
+ }
+ else
+ {
+ item->prev = NULL;
+ item->next = head;
+ head = head->prev = item;
+ }
+
+ __unlock();
+ }
+
+ template <typename _T, typename _K, bool locked, typename _S>
+ void List<_T,_K,locked,_S>::__lock()
+ {
+ Util::Locked::LockHelper<locked,_S>(lock).lock();
+ }
+
+ template <typename _T, typename _K, bool locked, typename _S>
+ void List<_T,_K,locked,_S>::__unlock()
+ {
+ Util::Locked::LockHelper<locked,_S>(lock).unlock();
+ }
+
+ template <typename _T, typename _K, bool locked, typename _S>
+ void List<_T,_K,locked,_S>::erase(_T* node)
+ {
+ __lock();
+
+ if (node == head)
+ head = node->next;
+ else
+ node->prev->next = node->next;
+
+ if (node == tail)
+ tail = node->prev;
+ else
+ node->next->prev = node->prev;
+
+ __unlock();
+ }
+
+ template <typename _T, typename _K, bool locked, typename _S>
+ void List<_T,_K,locked,_S>::erase(_K& key)
+ {
+ __lock();
+
+ _T* node = head;
+
+ while((node != NULL) && (node->key != key))
+ node = node->next;
+
+ if (node != NULL)
+ {
+ if (node == head)
+ head = node->next;
+ else
+ node->prev->next = node->next;
+
+ if (node == tail)
+ tail = node->prev;
+ else
+ node->next->prev = node->prev;
+ }
+
+ __unlock();
+
+ return node;
+ }
+
+ template <typename _T, typename _K, bool locked, typename _S>
+ _T* List<_T,_K,locked,_S>::find(_K& key)
+ {
+ __lock();
+
+ _T* node = head;
+
+ while((node != NULL) && (node->key != key))
+ node = node->next;
+
+ __unlock();
+
+ return node;
+ }
+ }
+}
+
+
+#endif
diff --git a/src/include/util/locked/queue.H b/src/include/util/locked/queue.H
index 51d2c430e..651e24a80 100644
--- a/src/include/util/locked/queue.H
+++ b/src/include/util/locked/queue.H
@@ -17,7 +17,7 @@ namespace Util
_T* remove();
void insert(_T*);
- private:
+ protected:
_T* head;
_T* tail;
OpenPOWER on IntegriCloud