[+] AuProcAddresses.Linux.*
This commit is contained in:
parent
1f173a8799
commit
737d3bb4d6
188
Source/AuProcAddresses.Linux.cpp
Normal file
188
Source/AuProcAddresses.Linux.cpp
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
/***
|
||||||
|
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||||
|
|
||||||
|
File: AuProcAddresses.Linux.cpp
|
||||||
|
Date: 2023-8-11
|
||||||
|
Author: Reece
|
||||||
|
***/
|
||||||
|
#include <RuntimeInternal.hpp>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <linux/futex.h>
|
||||||
|
|
||||||
|
namespace Aurora
|
||||||
|
{
|
||||||
|
#define read_barrier() __asm__ __volatile__("lfence" ::: "memory")
|
||||||
|
|
||||||
|
static const auto kAioRingMagic = 0xa10a10a1u;
|
||||||
|
|
||||||
|
void InitLinuxAddresses()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int pidfd_getfd(int pidfd, int targetfd,
|
||||||
|
unsigned int flags)
|
||||||
|
{
|
||||||
|
return syscall(SYS_pidfd_getfd, pidfd, targetfd, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
int pidfd_open(pid_t pid, unsigned int flags)
|
||||||
|
{
|
||||||
|
return syscall(SYS_pidfd_open, pid, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
long set_robust_list(struct robust_list_head *head, size_t len)
|
||||||
|
{
|
||||||
|
return syscall(SYS_set_robust_list, head, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
long get_robust_list(int pid, struct robust_list_head **head_ptr, size_t *len_ptr)
|
||||||
|
{
|
||||||
|
return syscall(SYS_get_robust_list, pid, head_ptr, len_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int futex(uint32_t *uaddr, int futex_op, uint32_t val,
|
||||||
|
const struct timespec *timeout,
|
||||||
|
uint32_t *uaddr2, uint32_t val3)
|
||||||
|
{
|
||||||
|
return syscall(SYS_futex, uaddr, futex_op, val, timeout, uaddr2, val3);
|
||||||
|
}
|
||||||
|
|
||||||
|
int futex_wait(volatile uint32_t *addr, uint32_t expected)
|
||||||
|
{
|
||||||
|
return futex((uint32_t *)addr, FUTEX_WAIT, expected, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int futex_wait(volatile uint32_t *addr, uint32_t expected, const struct timespec *timeout)
|
||||||
|
{
|
||||||
|
if (timeout)
|
||||||
|
{
|
||||||
|
return futex((uint32_t *)addr, FUTEX_WAIT_BITSET, expected, timeout, 0, FUTEX_BITSET_MATCH_ANY);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return futex((uint32_t *)addr, FUTEX_WAIT, expected, timeout, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int futex_wake(volatile uint32_t *addr, uint32_t nthreads)
|
||||||
|
{
|
||||||
|
return futex((uint32_t *)addr, FUTEX_WAKE, nthreads, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int futex_wait(uint32_t *addr, uint32_t expected)
|
||||||
|
{
|
||||||
|
return futex(addr, FUTEX_WAIT, expected, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int futex_wait(uint32_t *addr, uint32_t expected, const struct timespec *timeout)
|
||||||
|
{
|
||||||
|
if (timeout)
|
||||||
|
{
|
||||||
|
return futex(addr, FUTEX_WAIT_BITSET, expected, timeout, 0, FUTEX_BITSET_MATCH_ANY);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return futex(addr, FUTEX_WAIT, expected, timeout, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int futex_wake(uint32_t *addr, uint32_t nthreads)
|
||||||
|
{
|
||||||
|
return futex(addr, FUTEX_WAKE, nthreads, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int io_setup(unsigned nr, aio_context_t *ctxp)
|
||||||
|
{
|
||||||
|
return syscall(__NR_io_setup, nr, ctxp);
|
||||||
|
}
|
||||||
|
|
||||||
|
int io_destroy(aio_context_t ctx)
|
||||||
|
{
|
||||||
|
return syscall(__NR_io_destroy, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
int io_submit(aio_context_t ctx, long nr, struct iocb **iocbpp)
|
||||||
|
{
|
||||||
|
return syscall(__NR_io_submit, ctx, nr, iocbpp);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
int io_getevents(aio_context_t ctx, long min_nr, long max_nr,
|
||||||
|
struct io_event *events,
|
||||||
|
struct timespec *timeout)
|
||||||
|
{
|
||||||
|
return syscall(__NR_io_getevents, ctx, min_nr, max_nr, events, timeout);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct aio_ring
|
||||||
|
{
|
||||||
|
unsigned id;
|
||||||
|
unsigned nr;
|
||||||
|
unsigned head;
|
||||||
|
unsigned tail;
|
||||||
|
|
||||||
|
unsigned magic;
|
||||||
|
unsigned compat_features;
|
||||||
|
unsigned incompat_features;
|
||||||
|
unsigned header_length;
|
||||||
|
|
||||||
|
struct io_event events[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
int io_getevents(aio_context_t ctx,
|
||||||
|
long min_nr, long max_nr,
|
||||||
|
struct io_event *events,
|
||||||
|
struct timespec *timeout)
|
||||||
|
{
|
||||||
|
int i {};
|
||||||
|
|
||||||
|
auto pRing = (struct aio_ring *)ctx;
|
||||||
|
|
||||||
|
if (!pRing ||
|
||||||
|
pRing->magic != kAioRingMagic)
|
||||||
|
{
|
||||||
|
goto do_syscall;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i < max_nr)
|
||||||
|
{
|
||||||
|
auto head = pRing->head;
|
||||||
|
if (head == pRing->tail)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
events[i++] = pRing->events[head];
|
||||||
|
read_barrier();
|
||||||
|
pRing->head = (head + 1) % pRing->nr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!i &&
|
||||||
|
timeout &&
|
||||||
|
!timeout->tv_sec &&
|
||||||
|
!timeout->tv_nsec)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i &&
|
||||||
|
i >= min_nr)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
do_syscall:
|
||||||
|
return syscall(__NR_io_getevents,
|
||||||
|
ctx, min_nr - i,
|
||||||
|
max_nr - i,
|
||||||
|
&events[i], timeout) + i;
|
||||||
|
}
|
||||||
|
|
||||||
|
int io_cancel(aio_context_t ctx_id, struct iocb *iocb,
|
||||||
|
struct io_event *result)
|
||||||
|
{
|
||||||
|
return syscall(SYS_io_cancel, ctx_id, iocb, result);
|
||||||
|
}
|
||||||
|
}
|
55
Source/AuProcAddresses.Linux.hpp
Normal file
55
Source/AuProcAddresses.Linux.hpp
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/***
|
||||||
|
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||||
|
|
||||||
|
File: AuProcAddresses.Linux.hpp
|
||||||
|
Date: 2023-8-11
|
||||||
|
Author: Reece
|
||||||
|
***/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
#include <linux/aio_abi.h>
|
||||||
|
|
||||||
|
struct robust_list_head;
|
||||||
|
|
||||||
|
namespace Aurora
|
||||||
|
{
|
||||||
|
void InitLinuxAddresses();
|
||||||
|
|
||||||
|
int pidfd_getfd(int pidfd, int targetfd,
|
||||||
|
unsigned int flags);
|
||||||
|
|
||||||
|
int pidfd_open(pid_t pid, unsigned int flags);
|
||||||
|
|
||||||
|
long get_robust_list(int pid, struct robust_list_head **head_ptr, size_t *len_ptr);
|
||||||
|
|
||||||
|
long set_robust_list(struct robust_list_head *head, size_t len);
|
||||||
|
|
||||||
|
int futex_wake(volatile uint32_t *addr, uint32_t nthreads);
|
||||||
|
|
||||||
|
int futex_wait(volatile uint32_t *addr, uint32_t expected,
|
||||||
|
const struct timespec *timeout);
|
||||||
|
|
||||||
|
int futex_wait(volatile uint32_t *addr, uint32_t expected);
|
||||||
|
|
||||||
|
int futex_wake(uint32_t *addr, uint32_t nthreads);
|
||||||
|
|
||||||
|
int futex_wait(uint32_t *addr, uint32_t expected,
|
||||||
|
const struct timespec *timeout);
|
||||||
|
|
||||||
|
int futex_wait(uint32_t *addr, uint32_t expected);
|
||||||
|
|
||||||
|
|
||||||
|
int io_submit(aio_context_t ctx, long nr, struct iocb **iocbpp);
|
||||||
|
|
||||||
|
int io_cancel(aio_context_t ctx_id, struct iocb *iocb,
|
||||||
|
struct io_event *result);
|
||||||
|
|
||||||
|
int io_destroy(aio_context_t ctx);
|
||||||
|
|
||||||
|
int io_setup(unsigned nr, aio_context_t *ctxp);
|
||||||
|
|
||||||
|
int io_getevents(aio_context_t ctx, long min_nr, long max_nr,
|
||||||
|
struct io_event *events,
|
||||||
|
struct timespec *timeout);
|
||||||
|
}
|
@ -9,6 +9,8 @@
|
|||||||
|
|
||||||
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
||||||
#include "AuProcAddresses.NT.hpp"
|
#include "AuProcAddresses.NT.hpp"
|
||||||
|
#elif defined(AURORA_IS_LINUX_DERIVED)
|
||||||
|
#include "AuProcAddresses.Linux.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Aurora
|
namespace Aurora
|
||||||
|
@ -23,50 +23,6 @@
|
|||||||
// ...TIME UTILS
|
// ...TIME UTILS
|
||||||
#include <Source/Time/Time.hpp>
|
#include <Source/Time/Time.hpp>
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// SYSCALLS
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static int futex(uint32_t *uaddr, int futex_op, uint32_t val,
|
|
||||||
const struct timespec *timeout, /* or: uint32_t val2 */
|
|
||||||
uint32_t *uaddr2, uint32_t val3)
|
|
||||||
{
|
|
||||||
return syscall(SYS_futex, uaddr, futex_op, val, timeout, uaddr2, val3);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int futex_wait(uint32_t *addr, uint32_t expected)
|
|
||||||
{
|
|
||||||
return futex(addr, FUTEX_WAIT, expected, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int futex_wait(uint32_t *addr, uint32_t expected, const struct timespec *timeout)
|
|
||||||
{
|
|
||||||
if (timeout)
|
|
||||||
{
|
|
||||||
return futex(addr, FUTEX_WAIT_BITSET, expected, timeout, 0, FUTEX_BITSET_MATCH_ANY);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return futex(addr, FUTEX_WAIT, expected, timeout, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int futex_wake(uint32_t *addr, uint32_t nthreads)
|
|
||||||
{
|
|
||||||
return futex(addr, FUTEX_WAKE, nthreads, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static long set_robust_list(struct robust_list_head *head, size_t len)
|
|
||||||
{
|
|
||||||
return syscall(SYS_set_robust_list, head, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
static long get_robust_list(int pid, struct robust_list_head **head_ptr, size_t *len_ptr)
|
|
||||||
{
|
|
||||||
return syscall(SYS_get_robust_list, pid, head_ptr, len_ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
// CONSTANTS
|
// CONSTANTS
|
||||||
////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -202,7 +158,7 @@ bool FutexContext::SetGrugSelf()
|
|||||||
this->futexArrayHeader.list_op_pending = NULL;
|
this->futexArrayHeader.list_op_pending = NULL;
|
||||||
|
|
||||||
// Update TLS
|
// Update TLS
|
||||||
if (::set_robust_list(AuReinterpretCast<robust_list_head *>(&this->futexArrayHeader.list), sizeof(robust_list_head)) != 0)
|
if (Aurora::set_robust_list(AuReinterpretCast<robust_list_head *>(&this->futexArrayHeader.list), sizeof(robust_list_head)) != 0)
|
||||||
{
|
{
|
||||||
SysPushErrorIO("Set robust list failed");
|
SysPushErrorIO("Set robust list failed");
|
||||||
return false;
|
return false;
|
||||||
@ -366,7 +322,7 @@ static bool LinuxLockFutex(AuUInt32 *futex, AuUInt32 timeout)
|
|||||||
bContended = old != kFutexValueUnlocked;
|
bContended = old != kFutexValueUnlocked;
|
||||||
if (bContended)
|
if (bContended)
|
||||||
{
|
{
|
||||||
int res = ::futex_wait(futex, old, timeout ? &tspec : nullptr);
|
int res = Aurora::futex_wait(futex, old, timeout ? &tspec : nullptr);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
{
|
{
|
||||||
if (res == ETIMEDOUT || errno == ETIMEDOUT)
|
if (res == ETIMEDOUT || errno == ETIMEDOUT)
|
||||||
@ -419,7 +375,7 @@ static bool LinuxUnlockFutex(AuUInt32 *futex)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
::futex_wake(futex, 1);
|
Aurora::futex_wake(futex, 1);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -16,17 +16,6 @@
|
|||||||
|
|
||||||
#if defined(AURORA_IS_LINUX_DERIVED)
|
#if defined(AURORA_IS_LINUX_DERIVED)
|
||||||
|
|
||||||
static int pidfd_getfd(int pidfd, int targetfd,
|
|
||||||
unsigned int flags)
|
|
||||||
{
|
|
||||||
return syscall(SYS_pidfd_getfd, pidfd, targetfd, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pidfd_open(pid_t pid, unsigned int flags)
|
|
||||||
{
|
|
||||||
return syscall(SYS_pidfd_open, pid, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(PIDFD_NONBLOCK)
|
#if !defined(PIDFD_NONBLOCK)
|
||||||
#define PIDFD_NONBLOCK O_NONBLOCK
|
#define PIDFD_NONBLOCK O_NONBLOCK
|
||||||
#endif
|
#endif
|
||||||
@ -397,14 +386,14 @@ namespace Aurora::IO::UNIX
|
|||||||
{
|
{
|
||||||
#if defined(AURORA_IS_LINUX_DERIVED)
|
#if defined(AURORA_IS_LINUX_DERIVED)
|
||||||
|
|
||||||
int pid = ::pidfd_open(handle.ToUnixPid(), 0);
|
int pid = pidfd_open(handle.ToUnixPid(), 0);
|
||||||
if (pid <= 0)
|
if (pid <= 0)
|
||||||
{
|
{
|
||||||
SysPushErrorIO("Couldn't open IPC server pid, error: {}", pid);
|
SysPushErrorIO("Couldn't open IPC server pid, error: {}", pid);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int result = ::pidfd_getfd(pid, handle.cookie, 0);
|
int result = pidfd_getfd(pid, handle.cookie, 0);
|
||||||
if (result <= 0)
|
if (result <= 0)
|
||||||
{
|
{
|
||||||
SysPushErrorIO("Couldn't get IPC fd, error: {} {}", result, errno);
|
SysPushErrorIO("Couldn't get IPC fd, error: {} {}", result, errno);
|
||||||
|
@ -18,97 +18,6 @@
|
|||||||
#include <Source/IO/Loop/Loop.hpp>
|
#include <Source/IO/Loop/Loop.hpp>
|
||||||
#include <Source/IO/Loop/LSEvent.hpp>
|
#include <Source/IO/Loop/LSEvent.hpp>
|
||||||
|
|
||||||
static int io_setup(unsigned nr, aio_context_t *ctxp)
|
|
||||||
{
|
|
||||||
return syscall(__NR_io_setup, nr, ctxp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int io_destroy(aio_context_t ctx)
|
|
||||||
{
|
|
||||||
return syscall(__NR_io_destroy, ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int io_submit(aio_context_t ctx, long nr, struct iocb **iocbpp)
|
|
||||||
{
|
|
||||||
return syscall(__NR_io_submit, ctx, nr, iocbpp);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static int io_getevents(aio_context_t ctx, long min_nr, long max_nr,
|
|
||||||
struct io_event *events,
|
|
||||||
struct timespec *timeout)
|
|
||||||
{
|
|
||||||
return syscall(__NR_io_getevents, ctx, min_nr, max_nr, events, timeout);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define read_barrier() __asm__ __volatile__("lfence" ::: "memory")
|
|
||||||
|
|
||||||
#define AIO_RING_MAGIC 0xa10a10a1
|
|
||||||
|
|
||||||
struct aio_ring {
|
|
||||||
unsigned id; /** kernel internal index number */
|
|
||||||
unsigned nr; /** number of io_events */
|
|
||||||
unsigned head;
|
|
||||||
unsigned tail;
|
|
||||||
|
|
||||||
unsigned magic;
|
|
||||||
unsigned compat_features;
|
|
||||||
unsigned incompat_features;
|
|
||||||
unsigned header_length; /** size of aio_ring */
|
|
||||||
|
|
||||||
struct io_event events[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Code based on axboe/fio:
|
|
||||||
* https://github.com/axboe/fio/blob/702906e9e3e03e9836421d5e5b5eaae3cd99d398/engines/libaio.c#L149-L172
|
|
||||||
*/
|
|
||||||
static int io_getevents(aio_context_t ctx, long min_nr, long max_nr,
|
|
||||||
struct io_event *events,
|
|
||||||
struct timespec *timeout)
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
struct aio_ring *ring = (struct aio_ring *)ctx;
|
|
||||||
if (ring == NULL || ring->magic != AIO_RING_MAGIC) {
|
|
||||||
goto do_syscall;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (i < max_nr) {
|
|
||||||
unsigned head = ring->head;
|
|
||||||
if (head == ring->tail) {
|
|
||||||
/* There are no more completions */
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
/* There is another completion to reap */
|
|
||||||
events[i] = ring->events[head];
|
|
||||||
read_barrier();
|
|
||||||
ring->head = (head + 1) % ring->nr;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i == 0 && timeout != NULL && timeout->tv_sec == 0 &&
|
|
||||||
timeout->tv_nsec == 0) {
|
|
||||||
/* Requested non blocking operation. */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i && i >= min_nr) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
do_syscall:
|
|
||||||
return syscall(__NR_io_getevents, ctx, min_nr - i, max_nr - i,
|
|
||||||
&events[i], timeout) + i;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int io_cancel(aio_context_t ctx_id, struct iocb *iocb,
|
|
||||||
struct io_event *result)
|
|
||||||
{
|
|
||||||
return syscall(SYS_io_cancel, ctx_id, iocb, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Aurora::IO::UNIX
|
namespace Aurora::IO::UNIX
|
||||||
{
|
{
|
||||||
static bool LinuxOverlappedSubmit(int fd, int op, AuUInt offset, ASubmittable *context, AuLoop::ILSEvent *optEvent);
|
static bool LinuxOverlappedSubmit(int fd, int op, AuUInt offset, ASubmittable *context, AuLoop::ILSEvent *optEvent);
|
||||||
|
@ -14,8 +14,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(AURORA_IS_LINUX_DERIVED)
|
#if defined(AURORA_IS_LINUX_DERIVED)
|
||||||
#include <linux/futex.h>
|
|
||||||
#include <sys/syscall.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -32,32 +30,6 @@ namespace Aurora::Threading
|
|||||||
static thread_local WaitEntry tlsWaitEntry;
|
static thread_local WaitEntry tlsWaitEntry;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(AURORA_IS_LINUX_DERIVED)
|
|
||||||
static int futex(uint32_t *uaddr, int futex_op, uint32_t val,
|
|
||||||
const struct timespec *timeout,
|
|
||||||
uint32_t *uaddr2, uint32_t val3)
|
|
||||||
{
|
|
||||||
return syscall(SYS_futex, uaddr, futex_op, val, timeout, uaddr2, val3);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int futex_wait(uint32_t *addr, uint32_t expected, const struct timespec *timeout)
|
|
||||||
{
|
|
||||||
if (timeout)
|
|
||||||
{
|
|
||||||
return futex(addr, FUTEX_WAIT_BITSET, expected, timeout, 0, FUTEX_BITSET_MATCH_ANY);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return futex(addr, FUTEX_WAIT, expected, timeout, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int futex_wake(uint32_t *addr, uint32_t nthreads)
|
|
||||||
{
|
|
||||||
return futex(addr, FUTEX_WAKE, nthreads, 0, 0, 0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static ProcessWaitContainer gProcessWaitables;
|
static ProcessWaitContainer gProcessWaitables;
|
||||||
static int gShouldSpinOnlyInCPU = 1; // TODO: havent decided
|
static int gShouldSpinOnlyInCPU = 1; // TODO: havent decided
|
||||||
|
|
||||||
|
@ -20,35 +20,6 @@ namespace Aurora::Threading::Primitives
|
|||||||
#define barrier() __asm__ __volatile__("sfence": : :"memory")
|
#define barrier() __asm__ __volatile__("sfence": : :"memory")
|
||||||
#define compilerReorderBarrier() __asm__ __volatile__("": : :"memory")
|
#define compilerReorderBarrier() __asm__ __volatile__("": : :"memory")
|
||||||
|
|
||||||
static int futex(uint32_t *uaddr, int futex_op, uint32_t val,
|
|
||||||
const struct timespec *timeout,
|
|
||||||
uint32_t *uaddr2, uint32_t val3)
|
|
||||||
{
|
|
||||||
return syscall(SYS_futex, uaddr, futex_op, val, timeout, uaddr2, val3);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int futex_wait(volatile uint32_t *addr, uint32_t expected)
|
|
||||||
{
|
|
||||||
return futex((uint32_t *)addr, FUTEX_WAIT, expected, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int futex_wait(volatile uint32_t *addr, uint32_t expected, const struct timespec *timeout)
|
|
||||||
{
|
|
||||||
if (timeout)
|
|
||||||
{
|
|
||||||
return futex((uint32_t *)addr, FUTEX_WAIT_BITSET, expected, timeout, 0, FUTEX_BITSET_MATCH_ANY);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return futex((uint32_t *)addr, FUTEX_WAIT, expected, timeout, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int futex_wake(volatile uint32_t *addr, uint32_t nthreads)
|
|
||||||
{
|
|
||||||
return futex((uint32_t *)addr, FUTEX_WAKE, nthreads, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
MutexImpl::MutexImpl()
|
MutexImpl::MutexImpl()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -9,43 +9,11 @@
|
|||||||
#include "AuSemaphore.Generic.hpp"
|
#include "AuSemaphore.Generic.hpp"
|
||||||
#include "SMTYield.hpp"
|
#include "SMTYield.hpp"
|
||||||
|
|
||||||
#include <sys/syscall.h>
|
|
||||||
#include <linux/futex.h>
|
|
||||||
|
|
||||||
#if !defined(_AURUNTIME_GENERIC_SEMAPHORE)
|
#if !defined(_AURUNTIME_GENERIC_SEMAPHORE)
|
||||||
#include <Source/Time/Time.hpp>
|
#include <Source/Time/Time.hpp>
|
||||||
|
|
||||||
namespace Aurora::Threading::Primitives
|
namespace Aurora::Threading::Primitives
|
||||||
{
|
{
|
||||||
static int futex(uint32_t *uaddr, int futex_op, uint32_t val,
|
|
||||||
const struct timespec *timeout,
|
|
||||||
uint32_t *uaddr2, uint32_t val3)
|
|
||||||
{
|
|
||||||
return syscall(SYS_futex, uaddr, futex_op, val, timeout, uaddr2, val3);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int futex_wait(uint32_t *addr, uint32_t expected)
|
|
||||||
{
|
|
||||||
return futex(addr, FUTEX_WAIT, expected, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int futex_wait(uint32_t *addr, uint32_t expected, const struct timespec *timeout)
|
|
||||||
{
|
|
||||||
if (timeout)
|
|
||||||
{
|
|
||||||
return futex(addr, FUTEX_WAIT_BITSET, expected, timeout, 0, FUTEX_BITSET_MATCH_ANY);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return futex(addr, FUTEX_WAIT, expected, timeout, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int futex_wake(uint32_t *addr, uint32_t nthreads)
|
|
||||||
{
|
|
||||||
return futex(addr, FUTEX_WAKE, nthreads, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
SemaphoreImpl::SemaphoreImpl(long intialValue) : value_(intialValue)
|
SemaphoreImpl::SemaphoreImpl(long intialValue) : value_(intialValue)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user