wut/libraries/wutstdc++/wut_gthread_cond.cpp
fincs ee3bb10df4 First pass at adopting a devkitPro-style build system, see details:
- Added wut_rules and wut/rpx/rpl.specs to share/
- Replaced wut's CMake-based buildsystem with a standard Makefile
- Conflated all wut libraries into a single libwut.a library
- wut's old buildsystems (CMake & plain make) are broken as a result,
  this will be fixed in the future
- Docs, tests and samples are not buildable either at the moment
- wutcrt/wutnewlib:
  - RPX start function is __rpx_start, while RPL is __rpl_start
  - __init/fini_wut_* functions are no longer weak
  - __init_wut/__fini_wut are instead weak
  - Removed _exit implementation
  - exit syscall now points to _Exit instead of pointing to itself
- wutstdc++:
  - Renamed .cc files to .cpp
  - Temporarily disabled, due to an issue that will be addressed shortly
- wutdevoptab:
  - Fixed uninitialized variable warnings in __wut_fs_read/write
2019-02-12 12:46:28 +01:00

101 lines
2.0 KiB
C++

#include "wut_gthread.h"
#include <sys/errno.h>
#include <coreinit/alarm.h>
#include <coreinit/systeminfo.h>
#include <coreinit/time.h>
#include <chrono>
void
__wut_cond_init_function(OSCondition *cond)
{
OSInitCond(cond);
}
int
__wut_cond_broadcast(OSCondition *cond)
{
OSSignalCond(cond);
return 0;
}
int
__wut_cond_signal(OSCondition *cond)
{
OSSignalCond(cond);
return 0;
}
int
__wut_cond_wait(OSCondition *cond,
OSMutex *mutex)
{
OSWaitCond(cond, mutex);
return 0;
}
struct __wut_cond_timedwait_data_t
{
OSCondition *cond;
bool timed_out;
};
static void
__wut_cond_timedwait_alarm_callback(OSAlarm *alarm,
OSContext *context)
{
__wut_cond_timedwait_data_t *data = (__wut_cond_timedwait_data_t *)OSGetAlarmUserData(alarm);
data->timed_out = true;
OSSignalCond(data->cond);
}
int
__wut_cond_timedwait(OSCondition *cond, OSMutex *mutex,
const __gthread_time_t *abs_timeout)
{
__wut_cond_timedwait_data_t data;
data.timed_out = false;
data.cond = cond;
auto time = std::chrono::system_clock::now();
auto timeout = std::chrono::system_clock::time_point(
std::chrono::seconds(abs_timeout->tv_sec) +
std::chrono::nanoseconds(abs_timeout->tv_nsec));
// Already timed out!
if (timeout <= time) {
return ETIMEDOUT;
}
auto duration =
std::chrono::duration_cast<std::chrono::nanoseconds>(timeout - time);
// Set an alarm
OSAlarm alarm;
OSCreateAlarm(&alarm);
OSSetAlarmUserData(&alarm, &data);
OSSetAlarm(&alarm, OSNanosecondsToTicks(duration.count()),
&__wut_cond_timedwait_alarm_callback);
// Wait on the condition
OSWaitCond(cond, mutex);
OSCancelAlarm(&alarm);
return data.timed_out ? ETIMEDOUT : 0;
}
int
__wut_cond_wait_recursive(OSCondition *cond,
OSMutex *mutex)
{
OSWaitCond(cond, mutex);
return 0;
}
int
__wut_cond_destroy(OSCondition* cond)
{
return 0;
}