This repository has been archived by the owner on Sep 21, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 46
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d80eb0b
commit 10ac72b
Showing
7 changed files
with
131 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
/** | ||
* @file libtransistor/condvar.h | ||
* @brief Condition variables | ||
*/ | ||
|
||
#pragma once | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
#include<libtransistor/types.h> | ||
#include<libtransistor/mutex.h> | ||
|
||
typedef struct { | ||
uint32_t key; | ||
} trn_condvar_t; | ||
|
||
#define TRN_CONDVAR_STATIC_INITIALIZER {.key = 0} | ||
|
||
/** | ||
* @brief Creates a condition variable | ||
* | ||
* Alternatively, a statically allocated condition variable | ||
* may be initialized with /ref TRN_CONDVAR_STATIC_INITIALIZER | ||
*/ | ||
void trn_condvar_create(trn_condvar_t *condvar); | ||
|
||
/** | ||
* @brief Signals n threads waiting on the condition variable, or -1 for all of them | ||
*/ | ||
result_t trn_condvar_signal(trn_condvar_t *condvar, int n); | ||
|
||
/** | ||
* @brief Waits for the condition variable to be signalled | ||
* | ||
* @param timeout How long (in nanoseconds) to wait, or -1 for no timeout | ||
*/ | ||
result_t trn_condvar_wait(trn_condvar_t *condvar, trn_mutex_t *mutex, uint64_t timeout) REQUIRES(mutex); | ||
|
||
/** | ||
* @brief Destroys a condition variable | ||
*/ | ||
void trn_condvar_destroy(trn_condvar_t *condvar); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#include<libtransistor/condvar.h> | ||
|
||
#include<libtransistor/svc.h> | ||
#include<libtransistor/tls.h> | ||
|
||
void trn_condvar_create(trn_condvar_t *condvar) { | ||
condvar->key = 0; | ||
} | ||
|
||
result_t trn_condvar_signal(trn_condvar_t *condvar, int n) { | ||
return svcSignalProcessWideKey(&condvar->key, n); | ||
} | ||
|
||
result_t trn_condvar_wait(trn_condvar_t *condvar, trn_mutex_t *mutex, uint64_t timeout) NO_THREAD_SAFETY_ANALYSIS { | ||
result_t r; | ||
|
||
r = svcWaitProcessWideKeyAtomic((void*) &mutex->lock, &condvar->key, get_thread_handle(), timeout); | ||
|
||
if(r == 0xea01) { | ||
trn_mutex_lock(mutex); | ||
} | ||
|
||
return r; | ||
} | ||
|
||
void trn_condvar_destroy(trn_condvar_t *condvar) { | ||
condvar->key = -1; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
#include<libtransistor/util.h> | ||
#include<libtransistor/mutex.h> | ||
#include<libtransistor/condvar.h> | ||
#include<libtransistor/thread.h> | ||
#include<libtransistor/svc.h> | ||
|
||
#include<stdio.h> | ||
|
||
static trn_mutex_t mutex; | ||
static trn_condvar_t condvar; | ||
static volatile bool pred = 0; | ||
|
||
void other_thread(void *arg) { | ||
printf("O: other thread started\n"); | ||
|
||
printf("O: trying to lock mutex\n"); | ||
trn_mutex_lock(&mutex); | ||
printf("O: acquired mutex\n"); | ||
while(!pred) { | ||
printf("O: waiting on condvar...\n"); | ||
trn_condvar_wait(&condvar, &mutex, -1); | ||
printf("O: woke up\n"); | ||
} | ||
trn_mutex_unlock(&mutex); | ||
} | ||
|
||
int main(int argc, char *argv[]) { | ||
result_t r; | ||
trn_mutex_create(&mutex); | ||
trn_condvar_create(&condvar); | ||
|
||
trn_thread_t thread; | ||
ASSERT_OK(fail, trn_thread_create(&thread, other_thread, NULL, -1, -2, 1024 * 64, NULL)); | ||
ASSERT_OK(fail_thread, trn_thread_start(&thread)); | ||
|
||
printf("M: started other thread\n"); | ||
svcSleepThread(5000000000); | ||
printf("M: signalling spuriously\n"); | ||
trn_condvar_signal(&condvar, 1); | ||
svcSleepThread(5000000000); | ||
printf("M: signalling\n"); | ||
pred = 1; | ||
trn_condvar_signal(&condvar, 1); | ||
|
||
trn_thread_join(&thread, -1); | ||
|
||
fail_thread: | ||
trn_thread_destroy(&thread); | ||
fail: | ||
return r; | ||
} |