summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPixel <pixel@nobis-crew.org>2011-10-09 22:58:44 -0700
committerPixel <pixel@nobis-crew.org>2011-10-09 22:58:44 -0700
commitcf9a801ebcb4df0a8b1ea75e58ca8ea8960ba13b (patch)
treed27f9bf411f2c8d222a85935dec09a2616f61681
parent4010635b9c3d74e544d37d1e9295316cff01b014 (diff)
Adding basic locks from libpthread. Also, that 'pending' loop belongs after we activate the tasks.
-rw-r--r--Makefile1
-rw-r--r--includes/TaskMan.h2
-rw-r--r--includes/Threads.h17
-rw-r--r--src/TaskMan.cc27
-rw-r--r--src/Threads.cc13
5 files changed, 46 insertions, 14 deletions
diff --git a/Makefile b/Makefile
index 5d0ed2b..f0424e3 100644
--- a/Makefile
+++ b/Makefile
@@ -62,6 +62,7 @@ Main.cc \
Printer.cc \
Task.cc \
TaskMan.cc \
+Threads.cc \
LIBCORO_SOURCES = \
coro.c \
diff --git a/includes/TaskMan.h b/includes/TaskMan.h
index d8d0c80..fd00172 100644
--- a/includes/TaskMan.h
+++ b/includes/TaskMan.h
@@ -5,6 +5,7 @@
#include <ev++.h>
#include <ext/hash_set>
#include <vector>
+#include <Threads.h>
namespace gnu = __gnu_cxx;
@@ -32,6 +33,7 @@ class TaskMan {
typedef std::vector<Task *> taskList_t;
taskHash_t m_tasks, m_signaledTasks;
taskList_t m_pendingAdd;
+ Lock m_pendingLock;
volatile bool m_stopped;
struct ev_loop * m_loop;
};
diff --git a/includes/Threads.h b/includes/Threads.h
new file mode 100644
index 0000000..5a4ef61
--- /dev/null
+++ b/includes/Threads.h
@@ -0,0 +1,17 @@
+#pragma once
+
+#include <pthread.h>
+
+namespace Balau {
+
+class Lock {
+ public:
+ Lock();
+ ~Lock() { pthread_mutex_destroy(&m_lock); }
+ void enter() { pthread_mutex_lock(&m_lock); }
+ void leave() { pthread_mutex_unlock(&m_lock); }
+ private:
+ pthread_mutex_t m_lock;
+};
+
+};
diff --git a/src/TaskMan.cc b/src/TaskMan.cc
index a9ad709..fd0246f 100644
--- a/src/TaskMan.cc
+++ b/src/TaskMan.cc
@@ -33,21 +33,10 @@ void Balau::TaskMan::mainLoop() {
// checking "STARTING" tasks, and running them once
for (iH = m_tasks.begin(); iH != m_tasks.end(); iH++) {
t = *iH;
- if (t->getStatus() == Task::STARTING) {
+ if (t->getStatus() == Task::STARTING)
t->switchTo();
- }
}
- // lock pending
- // Adding tasks that were added, maybe from other threads
- for (iL = m_pendingAdd.begin(); iL != m_pendingAdd.end(); iL++) {
- t = *iL;
- Assert(m_tasks.find(t) == m_tasks.end());
- m_tasks.insert(t);
- }
- m_pendingAdd.clear();
- // unlock pending
-
ev_run(m_loop, EVRUN_ONCE);
// let's check who got signaled, and call them
@@ -56,6 +45,16 @@ void Balau::TaskMan::mainLoop() {
t->switchTo();
}
+ m_pendingLock.enter();
+ // Adding tasks that were added, maybe from other threads
+ for (iL = m_pendingAdd.begin(); iL != m_pendingAdd.end(); iL++) {
+ t = *iL;
+ Assert(m_tasks.find(t) == m_tasks.end());
+ m_tasks.insert(t);
+ }
+ m_pendingAdd.clear();
+ m_pendingLock.leave();
+
// Dealing with stopped and faulted tasks.
// First by signalling the waiters.
for (iH = m_tasks.begin(); iH != m_tasks.end(); iH++) {
@@ -93,9 +92,9 @@ void Balau::TaskMan::mainLoop() {
}
void Balau::TaskMan::registerTask(Balau::Task * t) {
- // lock pending
+ m_pendingLock.enter();
m_pendingAdd.push_back(t);
- // unlock pending
+ m_pendingLock.leave();
}
void Balau::TaskMan::signalTask(Task * t) {
diff --git a/src/Threads.cc b/src/Threads.cc
new file mode 100644
index 0000000..7c928f8
--- /dev/null
+++ b/src/Threads.cc
@@ -0,0 +1,13 @@
+#include <Exceptions.h>
+#include <Threads.h>
+
+Balau::Lock::Lock() {
+ int r;
+ pthread_mutexattr_t attr;
+ r = pthread_mutexattr_init(&attr);
+ Assert(r == 0);
+ r = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+ Assert(r == 0);
+ r = pthread_mutex_init(&m_lock, &attr);
+ Assert(r == 0);
+}