summaryrefslogtreecommitdiffstats
path: root/src/include/util/locked/list.H
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/util/locked/list.H')
-rw-r--r--src/include/util/locked/list.H153
1 files changed, 153 insertions, 0 deletions
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
OpenPOWER on IntegriCloud