20#include <lwip/arch/sys_arch.h>
24#include <pedigree/kernel/Log.h>
25#include <pedigree/kernel/panic.h>
26#include <pedigree/kernel/process/Mutex.h>
27#include <pedigree/kernel/process/Semaphore.h>
28#include <pedigree/kernel/process/Thread.h>
29#include <pedigree/kernel/processor/Processor.h>
30#include <pedigree/kernel/utilities/Mailbox.h>
31#include <pedigree/kernel/utilities/SecureRandom.h>
32#include <pedigree/kernel/utilities/pocketknife.h>
55static bool dns_random_bytes(
void* buffer,
size_t length) {
57 return getentropy(buffer, length) == 0;
59 return secure_random_bytes(buffer, length) == length;
63extern "C" int pedigree_dns_random_ready(
void) {
65 const bool ready = dns_random_bytes(&scratch,
sizeof(scratch));
66 pedigree_random::erase(&scratch,
sizeof(scratch));
70extern "C" uint32_t pedigree_dns_random(
void) {
73 if (!dns_random_bytes(&result,
sizeof(result)))
74 panic(
"DNS random generator unavailable after request admission");
81 clock_gettime(CLOCK_REALTIME, &spec);
83 return (spec.tv_sec * 1000) + (spec.tv_nsec / 1000000);
85 return Time::getTimeNanoseconds() / Time::Multiplier::Millisecond;
95static int thread_shim(
void* arg) {
98 void* threadArg = meta->arg;
108 meta->thread = thread;
110 StringCopy(meta->name, name);
131 std::thread* candidate =
reinterpret_cast<std::thread*
>(thread);
132 return candidate->get_id() == std::this_thread::get_id() ? 1 : 0;
140 if (sem_init(sem, 0, count) != 0) {
147 *sem =
reinterpret_cast<void*
>(newsem);
191 struct timespec started = {};
192 clock_gettime(CLOCK_MONOTONIC, &started);
196 struct timespec deadline = {};
197 clock_gettime(CLOCK_REALTIME, &deadline);
198 deadline.tv_sec += timeout / 1000;
199 deadline.tv_nsec += (timeout % 1000) * 1000000;
200 if (deadline.tv_nsec >= 1000000000) {
202 deadline.tv_nsec -= 1000000000;
207 result = sem_wait(sem);
210 result = sem_timedwait(sem, &deadline);
211 }
while (result == -1 && errno == EINTR);
215 result = sem_wait(sem);
216 }
while (result == -1 && errno == EINTR);
220 struct timespec completed = {};
221 clock_gettime(CLOCK_MONOTONIC, &completed);
222 const uint64_t startedNs =
223 (
static_cast<uint64_t
>(started.tv_sec) * 1000000000ULL) + started.tv_nsec;
224 const uint64_t completedNs =
225 (
static_cast<uint64_t
>(completed.tv_sec) * 1000000000ULL) + completed.tv_nsec;
226 return (completedNs - startedNs) / 1000000ULL;
231 const Time::Timestamp begin = Time::getTicks();
234 const size_t timeoutSecs = timeout / 1000;
235 const size_t timeoutUsecs = (timeout % 1000) * 1000;
245 const Time::Timestamp end = Time::getTicks();
246 return (end - begin) / Time::Multiplier::Millisecond;
261 mailbox->buffer.
close();
267 if ((*mbox)->buffer.write(msg) != pedigree_mbox::Buffer::NoError) {
268 FATAL(
"sys_mbox_post failed");
273 if (!mbox || !*mbox) {
276 return (*mbox)->buffer.closeWritesWithFinal(msg) ?
ERR_OK :
ERR_CLSD;
280 void* value =
nullptr;
281 pedigree_mbox::Buffer::Error error = pedigree_mbox::Buffer::NoError;
282 if (!(*mbox)->buffer.read(value, error)) {
291 Time::Timestamp begin = Time::getTimeNanoseconds();
293 Time::Timestamp timeoutMs = 0;
295 timeoutMs = Time::Infinity;
297 timeoutMs = timeout * Time::Multiplier::Millisecond;
300 void* value =
nullptr;
301 pedigree_mbox::Buffer::Error error = pedigree_mbox::Buffer::NoError;
302 if (!(*mbox)->buffer.read(value, timeoutMs, error)) {
309 Time::Timestamp end = Time::getTimeNanoseconds();
310 return (end - begin) / Time::Multiplier::Millisecond;
321 Time::Timestamp timeout = 0;
322 const pedigree_mbox::Buffer::Error error = (*mbox)->buffer.write(msg, timeout);
323 if (error == pedigree_mbox::Buffer::TimedOut) {
327 return error == pedigree_mbox::Buffer::NoError ?
ERR_OK :
ERR_BUF;
331 return *mbox !=
nullptr ? 1 : 0;
362 return *mutex !=
nullptr ? 1 : 0;
369sys_prot_t sys_arch_protect() {
371 while (!g_Protection.acquire(
true))
382void sys_arch_unprotect(sys_prot_t pval) {
384 g_Protection.release();
static bool getInterrupts()
static ProcessorInformation & information()
static bool inDeviceHardIrq()
static void setInterrupts(bool bEnable)
MUST_USE_RESULT bool acquireForCompletion(size_t n=1, size_t timeoutSecs=0, size_t timeoutUsecs=0)
bool acquire(size_t n=1, size_t timeoutSecs=0, size_t timeoutUsecs=0)
void EXPORTED_PUBLIC panic(const char *msg) NORETURN
void sys_mbox_set_invalid(sys_mbox_t *mbox)
u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
int sys_mbox_valid(sys_mbox_t *mbox)
void sys_mbox_post(sys_mbox_t *mbox, void *msg)
err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
err_t sys_mbox_new(sys_mbox_t *mbox, int size)
void sys_mbox_free(sys_mbox_t *mbox)
u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio)
void sys_mutex_free(sys_mutex_t *mutex)
err_t sys_mutex_new(sys_mutex_t *mutex)
void sys_mutex_set_invalid(sys_mutex_t *mutex)
void sys_mutex_lock(sys_mutex_t *mutex)
void sys_mutex_unlock(sys_mutex_t *mutex)
int sys_mutex_valid(sys_mutex_t *mutex)
int sys_sem_valid(sys_sem_t *sem)
void sys_sem_set_invalid(sys_sem_t *sem)
void sys_sem_free(sys_sem_t *sem)
u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
void sys_sem_signal(sys_sem_t *sem)
err_t sys_sem_new(sys_sem_t *sem, u8_t count)
EXPORTED_PUBLIC bool attachToForCompletion(void *handle)
EXPORTED_PUBLIC int attachTo(void *handle)
EXPORTED_PUBLIC void * runConcurrentlyAttached(int(*func)(void *), void *param)
int sys_thread_is_current(sys_thread_t thread)
int sys_thread_join(sys_thread_t thread)
void(* lwip_thread_fn)(void *arg)
err_t sys_mbox_post_and_close(sys_mbox_t *mbox, void *msg)