Switch to one-big-mutex mode
This commit is contained in:
parent
e8038416e7
commit
d174307651
@ -28,9 +28,7 @@ static int startTime;
|
|||||||
static std::map<std::pair<int, int>, Action> handlersMap;
|
static std::map<std::pair<int, int>, Action> handlersMap;
|
||||||
|
|
||||||
static pthread_mutex_t execMutex;
|
static pthread_mutex_t execMutex;
|
||||||
static pthread_t execThread;
|
|
||||||
static pthread_cond_t newEventBroadcast;
|
static pthread_cond_t newEventBroadcast;
|
||||||
static pthread_mutex_t newEventMutex;
|
|
||||||
|
|
||||||
struct Thread {
|
struct Thread {
|
||||||
struct Thread *next;
|
struct Thread *next;
|
||||||
@ -76,44 +74,15 @@ extern "C" void target_reset() {
|
|||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkUserMode() {
|
|
||||||
assert(execThread == pthread_self());
|
|
||||||
}
|
|
||||||
|
|
||||||
void startUser() {
|
void startUser() {
|
||||||
assert(execThread != pthread_self());
|
|
||||||
pthread_mutex_lock(&execMutex);
|
pthread_mutex_lock(&execMutex);
|
||||||
execThread = pthread_self();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void stopUser() {
|
void stopUser() {
|
||||||
assert(execThread == pthread_self());
|
|
||||||
execThread = 0;
|
|
||||||
pthread_mutex_unlock(&execMutex);
|
pthread_mutex_unlock(&execMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sleep_core_ms(uint32_t ms) {
|
void sleep_core_us(uint64_t us) {
|
||||||
struct timespec ts;
|
|
||||||
ts.tv_sec = ms / 1000;
|
|
||||||
ts.tv_nsec = (ms % 1000) * 1000000;
|
|
||||||
while (nanosleep(&ts, &ts))
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sleep_ms(uint32_t ms) {
|
|
||||||
if (execThread == pthread_self()) {
|
|
||||||
stopUser();
|
|
||||||
sleep_core_ms(ms);
|
|
||||||
startUser();
|
|
||||||
} else {
|
|
||||||
sleep_core_ms(ms);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void sleep_us(uint64_t us) {
|
|
||||||
if (us > 10000) {
|
|
||||||
sleep_ms(us / 1000);
|
|
||||||
}
|
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
ts.tv_sec = us / 1000000;
|
ts.tv_sec = us / 1000000;
|
||||||
ts.tv_nsec = (us % 1000000) * 1000;
|
ts.tv_nsec = (us % 1000000) * 1000;
|
||||||
@ -121,6 +90,19 @@ void sleep_us(uint64_t us) {
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sleep_ms(uint32_t ms) {
|
||||||
|
stopUser();
|
||||||
|
sleep_core_us(ms * 1000);
|
||||||
|
startUser();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sleep_us(uint64_t us) {
|
||||||
|
if (us > 50000) {
|
||||||
|
sleep_ms(us / 1000);
|
||||||
|
}
|
||||||
|
sleep_core_us(us);
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t currTime() {
|
uint64_t currTime() {
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
gettimeofday(&tv, NULL);
|
gettimeofday(&tv, NULL);
|
||||||
@ -195,13 +177,10 @@ void waitForEvent(int source, int value) {
|
|||||||
if (t->pid == self) {
|
if (t->pid == self) {
|
||||||
t->waitSource = source;
|
t->waitSource = source;
|
||||||
t->waitValue = value;
|
t->waitValue = value;
|
||||||
stopUser();
|
|
||||||
// spourious wake ups may occur they say
|
// spourious wake ups may occur they say
|
||||||
while (t->waitSource) {
|
while (t->waitSource) {
|
||||||
pthread_mutex_lock(&newEventMutex);
|
pthread_cond_wait(&t->waitCond, &execMutex);
|
||||||
pthread_cond_wait(&t->waitCond, &newEventMutex);
|
|
||||||
}
|
}
|
||||||
startUser();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -221,9 +200,9 @@ static void dispatchEvent(Event &e) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void *evtDispatcher(void *dummy) {
|
static void *evtDispatcher(void *dummy) {
|
||||||
pthread_mutex_lock(&newEventMutex);
|
startUser();
|
||||||
while (true) {
|
while (true) {
|
||||||
pthread_cond_wait(&newEventBroadcast, &newEventMutex);
|
pthread_cond_wait(&newEventBroadcast, &execMutex);
|
||||||
while (eventHead != NULL) {
|
while (eventHead != NULL) {
|
||||||
Event *ev = eventHead;
|
Event *ev = eventHead;
|
||||||
eventHead = ev->next;
|
eventHead = ev->next;
|
||||||
@ -245,9 +224,7 @@ static void *evtDispatcher(void *dummy) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void raiseEvent(int id, int event) {
|
void raiseEvent(int id, int event) {
|
||||||
checkUserMode();
|
|
||||||
auto e = mkEvent(id, event);
|
auto e = mkEvent(id, event);
|
||||||
pthread_mutex_lock(&newEventMutex);
|
|
||||||
if (eventTail == NULL) {
|
if (eventTail == NULL) {
|
||||||
assert(eventHead == NULL);
|
assert(eventHead == NULL);
|
||||||
eventHead = eventTail = e;
|
eventHead = eventTail = e;
|
||||||
@ -256,7 +233,6 @@ void raiseEvent(int id, int event) {
|
|||||||
eventTail = e;
|
eventTail = e;
|
||||||
}
|
}
|
||||||
pthread_cond_broadcast(&newEventBroadcast);
|
pthread_cond_broadcast(&newEventBroadcast);
|
||||||
pthread_mutex_unlock(&newEventMutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void registerWithDal(int id, int event, Action a) {
|
void registerWithDal(int id, int event, Action a) {
|
||||||
@ -282,5 +258,6 @@ void initRuntime() {
|
|||||||
pthread_t disp;
|
pthread_t disp;
|
||||||
pthread_create(&disp, NULL, evtDispatcher, NULL);
|
pthread_create(&disp, NULL, evtDispatcher, NULL);
|
||||||
pthread_detach(disp);
|
pthread_detach(disp);
|
||||||
|
startUser();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user