Commit c067c58f authored by Georg Martin Reinke's avatar Georg Martin Reinke
Browse files

use C++11 std thread library instead of pthreads


Former-commit-id: 66312bb8
parent 9940a47e
#include <Python.h> #include <Python.h>
#include <condition_variable>
#include <iostream> #include <iostream>
#include <mutex>
#include <string> #include <string>
#include <pthread.h> #include <thread>
#include "CIMReader.h" #include "CIMReader.h"
#include "Simulation.h" #include "Simulation.h"
#include "ShmemInterface.h" #include "ShmemInterface.h"
...@@ -42,13 +46,13 @@ enum SimState { ...@@ -42,13 +46,13 @@ enum SimState {
StatePaused StatePaused
}; };
static pthread_t simThread; static std::thread *simThread;
struct SimContext { struct SimContext {
Simulation &sim; Simulation &sim;
Logger &log, &llog, &rlog; Logger &log, &llog, &rlog;
pthread_cond_t cond; std::condition_variable cond;
pthread_mutex_t mut; std::mutex mut;
std::atomic_int stop, numStep; std::atomic_int stop, numStep;
SimState state; SimState state;
...@@ -56,9 +60,7 @@ struct SimContext { ...@@ -56,9 +60,7 @@ struct SimContext {
}; };
SimContext::SimContext(Simulation &sim, Logger &log, Logger &llog, Logger &rlog) : SimContext::SimContext(Simulation &sim, Logger &log, Logger &llog, Logger &rlog) :
sim(sim), log(log), llog(llog), rlog(rlog) { sim(sim), log(log), llog(llog), rlog(rlog), mut(), cond() {
pthread_mutex_init(&this->mut, nullptr);
pthread_cond_init(&this->cond, nullptr);
this->stop = 0; this->stop = 0;
this->numStep = 0; this->numStep = 0;
this->state = StateStopped; this->state = StateStopped;
...@@ -66,98 +68,87 @@ SimContext::SimContext(Simulation &sim, Logger &log, Logger &llog, Logger &rlog) ...@@ -66,98 +68,87 @@ SimContext::SimContext(Simulation &sim, Logger &log, Logger &llog, Logger &rlog)
static SimContext *globalCtx; static SimContext *globalCtx;
static void* simThreadFunction(void* arg) { static void simThreadFunction(SimContext* ctx) {
bool running = true; bool running = true;
SimContext* ctx = (SimContext*) arg;
std::unique_lock<std::mutex> lk(ctx->mut, std::defer_lock);
ctx->numStep = 0; ctx->numStep = 0;
while (running) { while (running) {
running = ctx->sim.step(ctx->log, ctx->llog, ctx->rlog); running = ctx->sim.step(ctx->log, ctx->llog, ctx->rlog);
ctx->numStep++; ctx->numStep++;
ctx->sim.increaseByTimeStep(); ctx->sim.increaseByTimeStep();
if (ctx->stop) { if (ctx->stop) {
pthread_mutex_lock(&ctx->mut); lk.lock();
ctx->state = StatePaused; ctx->state = StatePaused;
pthread_cond_signal(&ctx->cond); ctx->cond.notify_one();
pthread_cond_wait(&ctx->cond, &ctx->mut); ctx->cond.wait(lk);
ctx->state = StateRunning; ctx->state = StateRunning;
pthread_mutex_unlock(&ctx->mut); lk.unlock();
} }
} }
pthread_mutex_lock(&ctx->mut); lk.lock();
ctx->state = StateStopped; ctx->state = StateStopped;
pthread_cond_signal(&ctx->cond); ctx->cond.notify_one();
pthread_mutex_unlock(&ctx->mut);
return nullptr;
} }
static PyObject* pythonStart(PyObject *self, PyObject *args) { static PyObject* pythonStart(PyObject *self, PyObject *args) {
pthread_mutex_lock(&globalCtx->mut); std::unique_lock<std::mutex> lk(globalCtx->mut);
if (globalCtx->state != StateStopped) { if (globalCtx->state != StateStopped) {
PyErr_SetString(PyExc_SystemError, "Simulation already started"); PyErr_SetString(PyExc_SystemError, "Simulation already started");
pthread_mutex_unlock(&globalCtx->mut);
return nullptr; return nullptr;
} }
globalCtx->stop = 0; globalCtx->stop = 0;
globalCtx->state = StateRunning; globalCtx->state = StateRunning;
pthread_create(&simThread, nullptr, simThreadFunction, globalCtx); simThread = new std::thread(simThreadFunction, globalCtx);
pthread_mutex_unlock(&globalCtx->mut);
Py_INCREF(Py_None); Py_INCREF(Py_None);
return Py_None; return Py_None;
} }
static PyObject* pythonStep(PyObject *self, PyObject *args) { static PyObject* pythonStep(PyObject *self, PyObject *args) {
pthread_mutex_lock(&globalCtx->mut); std::unique_lock<std::mutex> lk(globalCtx->mut);
int oldStep = globalCtx->numStep; int oldStep = globalCtx->numStep;
if (globalCtx->state == StateStopped) { if (globalCtx->state == StateStopped) {
globalCtx->state = StateRunning; globalCtx->state = StateRunning;
globalCtx->stop = 1; globalCtx->stop = 1;
pthread_create(&simThread, nullptr, simThreadFunction, globalCtx); simThread = new std::thread(simThreadFunction, globalCtx);
} else if (globalCtx->state == StatePaused) { } else if (globalCtx->state == StatePaused) {
globalCtx->stop = 1; globalCtx->stop = 1;
pthread_cond_signal(&globalCtx->cond); globalCtx->cond.notify_one();
} else { } else {
PyErr_SetString(PyExc_SystemError, "Simulation currently running"); PyErr_SetString(PyExc_SystemError, "Simulation currently running");
pthread_mutex_unlock(&globalCtx->mut);
return nullptr; return nullptr;
} }
while (globalCtx->numStep == oldStep) while (globalCtx->numStep == oldStep)
pthread_cond_wait(&globalCtx->cond, &globalCtx->mut); globalCtx->cond.wait(lk);
pthread_mutex_unlock(&globalCtx->mut);
Py_INCREF(Py_None); Py_INCREF(Py_None);
return Py_None; return Py_None;
} }
static PyObject* pythonPause(PyObject *self, PyObject *args) { static PyObject* pythonPause(PyObject *self, PyObject *args) {
pthread_mutex_lock(&globalCtx->mut); std::unique_lock<std::mutex> lk(globalCtx->mut);
if (globalCtx->state != StateRunning) { if (globalCtx->state != StateRunning) {
PyErr_SetString(PyExc_SystemError, "Simulation not currently running"); PyErr_SetString(PyExc_SystemError, "Simulation not currently running");
pthread_mutex_unlock(&globalCtx->mut);
return nullptr; return nullptr;
} }
globalCtx->stop = 1; globalCtx->stop = 1;
pthread_cond_signal(&globalCtx->cond); globalCtx->cond.notify_one();
while (globalCtx->state == StateRunning) while (globalCtx->state == StateRunning)
pthread_cond_wait(&globalCtx->cond, &globalCtx->mut); globalCtx->cond.wait(lk);
pthread_mutex_unlock(&globalCtx->mut);
Py_INCREF(Py_None); Py_INCREF(Py_None);
return Py_None; return Py_None;
} }
static PyObject* pythonWait(PyObject *self, PyObject *args) { static PyObject* pythonWait(PyObject *self, PyObject *args) {
pthread_mutex_lock(&globalCtx->mut); std::unique_lock<std::mutex> lk(globalCtx->mut);
if (globalCtx->state == StateStopped) { if (globalCtx->state == StateStopped) {
pthread_mutex_unlock(&globalCtx->mut);
Py_INCREF(Py_None); Py_INCREF(Py_None);
return Py_None; return Py_None;
} else if (globalCtx->state == StatePaused) { } else if (globalCtx->state == StatePaused) {
pthread_mutex_unlock(&globalCtx->mut);
PyErr_SetString(PyExc_SystemError, "Simulation currently paused"); PyErr_SetString(PyExc_SystemError, "Simulation currently paused");
return nullptr; return nullptr;
} }
while (globalCtx->state == StateRunning) while (globalCtx->state == StateRunning)
pthread_cond_wait(&globalCtx->cond, &globalCtx->mut); globalCtx->cond.wait(lk);
pthread_mutex_unlock(&globalCtx->mut);
Py_INCREF(Py_None); Py_INCREF(Py_None);
return Py_None; return Py_None;
} }
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment