Add sys_timeb header
This commit is contained in:
Jeremy Soller
2018-12-09 11:27:44 -07:00
parent fc9e3923f6
commit 8aae8e1564
10 changed files with 410 additions and 1 deletions
+3
View File
@@ -16,3 +16,6 @@
[submodule "posix-regex"]
path = posix-regex
url = https://gitlab.redox-os.org/redox-os/posix-regex.git
[submodule "pthreads-emb"]
path = pthreads-emb
url = https://gitlab.redox-os.org/redox-os/pthreads-emb.git
+13 -1
View File
@@ -31,7 +31,7 @@ SRC=\
.PHONY: all clean fmt include install libc libm test
all: | libc libm
all: | libc libm libpthread
clean:
$(CARGO) clean
@@ -61,6 +61,8 @@ libc: $(BUILD)/release/libc.a $(BUILD)/release/crt0.o $(BUILD)/release/crti.o $(
libm: $(BUILD)/openlibm/libopenlibm.a
libpthread: $(BUILD)/pthreads-emb/libpthread.a
sysroot: all
rm -rf $@
rm -rf $@.partial
@@ -112,3 +114,13 @@ $(BUILD)/openlibm: openlibm
$(BUILD)/openlibm/libopenlibm.a: $(BUILD)/openlibm $(BUILD)/include
make CC=$(CC) CPPFLAGS="-fno-stack-protector -I$(shell pwd)/include -I $(shell pwd)/$(BUILD)/include" -C $< libopenlibm.a
$(BUILD)/pthreads-emb: pthreads-emb
rm -rf $@ $@.partial
mkdir -p $(BUILD)
cp -r $< $@.partial
mv $@.partial $@
touch $@
$(BUILD)/pthreads-emb/libpthread.a: $(BUILD)/pthreads-emb $(BUILD)/include
make CC=$(CC) CFLAGS="-fno-stack-protector -I$(shell pwd)/include -I $(shell pwd)/$(BUILD)/include" -C $< libpthread.a
+2
View File
@@ -5,6 +5,8 @@
extern "C" {
#endif
#define ENOTSUP EOPNOTSUPP
//TODO extern __thread int errno;
extern int errno;
Submodule
+1
Submodule pthreads-emb added at 6720dfdc95
+1
View File
@@ -36,6 +36,7 @@ pub mod sys_select;
pub mod sys_socket;
pub mod sys_stat;
pub mod sys_time;
pub mod sys_timeb;
//pub mod sys_times;
pub mod sys_un;
pub mod sys_utsname;
+1
View File
@@ -16,6 +16,7 @@ pub struct timeval {
pub tv_usec: suseconds_t,
}
#[repr(C)]
#[derive(Default)]
pub struct timezone {
pub tz_minuteswest: c_int,
pub tz_dsttime: c_int,
+7
View File
@@ -0,0 +1,7 @@
sys_includes = ["sys/types.h"]
include_guard = "_SYS_TIMEB_H"
language = "C"
style = "Tag"
[enum]
prefix_with_name = true
+29
View File
@@ -0,0 +1,29 @@
//! sys/time implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/systime.h.html
use header::sys_time::{gettimeofday, timeval, timezone};
use platform::types::*;
#[repr(C)]
#[derive(Default)]
pub struct timeb {
pub time: time_t,
pub millitm: c_ushort,
pub timezone: c_short,
pub dstflag: c_short,
}
#[no_mangle]
pub unsafe extern "C" fn ftime(tp: *mut timeb) -> c_int {
let mut tv = timeval::default();
let mut tz = timezone::default();
if gettimeofday(&mut tv, &mut tz) < 0 {
return -1;
}
(*tp).time = tv.tv_sec;
(*tp).millitm = (tv.tv_usec/1000) as c_ushort;
(*tp).timezone = tz.tz_minuteswest as c_short;
(*tp).dstflag = tz.tz_dsttime as c_short;
0
}
+1
View File
@@ -28,6 +28,7 @@ use io::{self, BufReader, SeekFrom};
use super::types::*;
use super::{errno, Pal, Read};
mod pte;
mod signal;
mod socket;
+352
View File
@@ -0,0 +1,352 @@
use alloc::boxed::Box;
use alloc::collections::BTreeMap;
use core::{mem, intrinsics, ptr};
use core::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
use syscall;
use platform::types::{c_int, c_uint, c_void};
type pte_osThreadHandle = usize;
type pte_osMutexHandle = *mut i32;
type pte_osSemaphoreHandle = *mut i32;
type pte_osThreadEntryPoint = unsafe extern "C" fn(params: *mut c_void) -> c_int;
#[repr(C)]
pub enum pte_osResult {
PTE_OS_OK = 0,
PTE_OS_NO_RESOURCES,
PTE_OS_GENERAL_FAILURE,
PTE_OS_TIMEOUT,
PTE_OS_INTERRUPTED,
PTE_OS_INVALID_PARAM
}
use self::pte_osResult::*;
static mut pid_mutexes: Option<BTreeMap<pte_osThreadHandle, pte_osMutexHandle>> = None;
static mut pid_mutexes_lock: i32 = 0;
#[thread_local]
static mut LOCALS: *mut BTreeMap<c_uint, *mut c_void> = ptr::null_mut();
static NEXT_KEY: AtomicUsize = ATOMIC_USIZE_INIT;
unsafe fn locals() -> &'static mut BTreeMap<c_uint, *mut c_void> {
if LOCALS == ptr::null_mut() {
LOCALS = Box::into_raw(Box::new(BTreeMap::new()));
}
&mut *LOCALS
}
// pte_osResult pte_osInit(void)
#[no_mangle]
pub unsafe extern "C" fn pte_osInit() -> pte_osResult {
PTE_OS_OK
}
/*
pte_osResult pte_osThreadCreate(pte_osThreadEntryPoint entryPoint,
int stackSize,
int initialPriority,
void *argv,
pte_osThreadHandle* ppte_osThreadHandle)
*/
#[no_mangle]
pub unsafe extern "C" fn pte_osThreadCreate(entryPoint: pte_osThreadEntryPoint,
_stackSize: c_int,
_initialPriority: c_int,
argv: *mut c_void,
ppte_osThreadHandle: *mut pte_osThreadHandle
) -> pte_osResult {
// XXX error handling
let id = syscall::clone(syscall::CLONE_VM | syscall::CLONE_FS | syscall::CLONE_FILES).unwrap();
let mutex = Box::into_raw(Box::new(0));
pte_osMutexLock(mutex);
if id == 0 {
// Wait until pte_osThreadStart
pte_osMutexLock(mutex);
entryPoint(argv);
let _ = syscall::exit(0);
} else {
pte_osMutexLock(&mut pid_mutexes_lock);
if pid_mutexes.is_none() {
pid_mutexes = Some(BTreeMap::new());
}
pid_mutexes.as_mut().unwrap().insert(id, mutex);
pte_osMutexUnlock(&mut pid_mutexes_lock);
*ppte_osThreadHandle = id;
}
PTE_OS_OK
}
// pte_osResult pte_osThreadStart(pte_osThreadHandle osThreadHandle)
#[no_mangle]
pub unsafe extern "C" fn pte_osThreadStart(handle: pte_osThreadHandle) -> pte_osResult {
let mut ret = PTE_OS_GENERAL_FAILURE;
pte_osMutexLock(&mut pid_mutexes_lock);
if let Some(ref mutexes) = pid_mutexes {
if let Some(mutex) = mutexes.get(&handle) {
pte_osMutexUnlock(*mutex);
ret = PTE_OS_OK;
}
}
pte_osMutexUnlock(&mut pid_mutexes_lock);
ret
}
/*
void pte_osThreadExit()
pte_osResult pte_osThreadExitAndDelete(pte_osThreadHandle handle)
pte_osResult pte_osThreadDelete(pte_osThreadHandle handle)
*/
#[no_mangle]
pub unsafe extern "C" fn pte_osThreadExit() {
syscall::exit(0);
}
#[no_mangle]
pub unsafe extern "C" fn pte_osThreadExitAndDelete(handle: pte_osThreadHandle) -> pte_osResult {
pte_osThreadDelete(handle);
syscall::exit(0);
PTE_OS_OK
}
#[no_mangle]
pub unsafe extern "C" fn pte_osThreadDelete(handle: pte_osThreadHandle) -> pte_osResult {
pte_osMutexLock(&mut pid_mutexes_lock);
if let Some(ref mut mutexes) = pid_mutexes {
if let Some(mutex) = mutexes.remove(&handle) {
Box::from_raw(mutex);
}
}
pte_osMutexUnlock(&mut pid_mutexes_lock);
PTE_OS_OK
}
// pte_osResult pte_osThreadWaitForEnd(pte_osThreadHandle threadHandle)
#[no_mangle]
pub unsafe extern "C" fn pte_osThreadWaitForEnd(handle: pte_osThreadHandle) -> pte_osResult {
let mut status = 0;
syscall::waitpid(handle, &mut status, 0);
PTE_OS_OK
}
// pte_osResult pte_osThreadCancel(pte_osThreadHandle threadHandle)
// pte_osResult pte_osThreadCheckCancel(pte_osThreadHandle threadHandle)
//void pte_osThreadSleep(unsigned int msecs)
#[no_mangle]
pub unsafe extern "C" fn pte_osThreadSleep(msecs: c_uint) {
let tm = syscall::TimeSpec {
tv_sec: msecs as i64 / 1000,
tv_nsec: (msecs as i32 % 1000) * 1000,
};
let mut rmtp = mem::uninitialized();
let _ = syscall::nanosleep(&tm, &mut rmtp);
}
// pte_osThreadHandle pte_osThreadGetHandle(void)
#[no_mangle]
pub unsafe extern "C" fn pte_osThreadGetHandle() -> pte_osThreadHandle {
syscall::getpid().unwrap()
}
/*
int pte_osThreadGetPriority(pte_osThreadHandle threadHandle)
pte_osResult pte_osThreadSetPriority(pte_osThreadHandle threadHandle, int newPriority)
int pte_osThreadGetMinPriority()
int pte_osThreadGetMaxPriority()
int pte_osThreadGetDefaultPriority()
*/
#[no_mangle]
pub unsafe extern "C" fn pte_osThreadGetPriority(threadHandle: pte_osThreadHandle) -> c_int {
// XXX Shouldn't Redox support priorities?
1
}
#[no_mangle]
pub unsafe extern "C" fn pte_osThreadSetPriority(threadHandle: pte_osThreadHandle, newPriority: c_int) -> pte_osResult {
PTE_OS_OK
}
#[no_mangle]
pub unsafe extern "C" fn pte_osThreadGetMinPriority() -> c_int {
1
}
#[no_mangle]
pub unsafe extern "C" fn pte_osThreadGetMaxPriority() -> c_int {
1
}
#[no_mangle]
pub unsafe extern "C" fn pte_osThreadGetDefaultPriority() -> c_int {
1
}
/*
pte_osResult pte_osMutexCreate(pte_osMutexHandle *pHandle)
pte_osResult pte_osMutexDelete(pte_osMutexHandle handle)
pte_osResult pte_osMutexLock(pte_osMutexHandle handle)
pte_osResult pte_osMutexUnlock(pte_osMutexHandle handle)
*/
#[no_mangle]
pub unsafe extern "C" fn pte_osMutexCreate(pHandle: *mut pte_osMutexHandle) -> pte_osResult {
*pHandle = Box::into_raw(Box::new(0));
PTE_OS_OK
}
#[no_mangle]
pub unsafe extern "C" fn pte_osMutexDelete(handle: pte_osMutexHandle) -> pte_osResult {
Box::from_raw(handle);
PTE_OS_OK
}
#[no_mangle]
pub unsafe extern "C" fn pte_osMutexLock(handle: pte_osMutexHandle) -> pte_osResult {
let mut c = 0;
for _i in 0..100 {
c = intrinsics::atomic_cxchg(handle, 0, 1).0;
if c == 0 {
break;
}
}
if c == 1 {
c = intrinsics::atomic_xchg(handle, 2);
}
while c != 0 {
let _ = syscall::futex(handle, syscall::FUTEX_WAIT, 2, 0, ptr::null_mut());
c = intrinsics::atomic_xchg(handle, 2);
}
PTE_OS_OK
}
#[no_mangle]
pub unsafe extern "C" fn pte_osMutexUnlock(handle: pte_osMutexHandle) -> pte_osResult {
if *handle == 2 {
*handle = 0;
} else if intrinsics::atomic_xchg(handle, 0) == 1 {
return PTE_OS_OK;
}
for _i in 0..100 {
if *handle != 0 {
if intrinsics::atomic_cxchg(handle, 1, 2).0 != 0 {
return PTE_OS_OK;
}
}
}
let _ = syscall::futex(handle, syscall::FUTEX_WAKE, 1, 0, ptr::null_mut());
PTE_OS_OK
}
/*
pte_osResult pte_osSemaphoreCreate(int initialValue, pte_osSemaphoreHandle *pHandle)
pte_osResult pte_osSemaphoreDelete(pte_osSemaphoreHandle handle)
pte_osResult pte_osSemaphorePost(pte_osSemaphoreHandle handle, int count)
pte_osResult pte_osSemaphorePend(pte_osSemaphoreHandle handle, unsigned int *pTimeoutMsecs)
pte_osResult pte_osSemaphoreCancellablePend(pte_osSemaphoreHandle semHandle, unsigned int *pTimeout)
*/
#[no_mangle]
pub unsafe extern "C" fn pte_osSemaphoreCreate(initialValue: c_int, pHandle: *mut pte_osSemaphoreHandle) -> pte_osResult {
*pHandle = Box::into_raw(Box::new(initialValue));
PTE_OS_OK
}
#[no_mangle]
pub unsafe extern "C" fn pte_osSemaphoreDelete(handle: pte_osSemaphoreHandle) -> pte_osResult {
Box::from_raw(handle);
PTE_OS_OK
}
#[no_mangle]
pub unsafe extern "C" fn pte_osSemaphorePost(handle: pte_osSemaphoreHandle, count: c_int) -> pte_osResult {
if intrinsics::atomic_xadd(handle, 1) <= 0 {
while match syscall::futex(handle, syscall::FUTEX_WAKE, 1, 0, ptr::null_mut()) {
Ok(waiters) => waiters < 1,
Err(err) => return PTE_OS_GENERAL_FAILURE,
} {
syscall::sched_yield();
}
}
PTE_OS_OK
}
#[no_mangle]
pub unsafe extern "C" fn pte_osSemaphorePend(handle: pte_osSemaphoreHandle, pTimeout: *mut c_uint) -> pte_osResult {
if intrinsics::atomic_xsub(handle, 1) < 0 {
let _ = syscall::futex(handle, syscall::FUTEX_WAIT, *handle, 0, ptr::null_mut());
}
PTE_OS_OK
}
/*
int pte_osAtomicExchange(int *ptarg, int val)
int pte_osAtomicCompareExchange(int *pdest, int exchange, int comp)
int pte_osAtomicExchangeAdd(int volatile* pAddend, int value)
int pte_osAtomicDecrement(int *pdest)
int pte_osAtomicIncrement(int *pdest)
*/
#[no_mangle]
pub unsafe extern "C" fn pte_osAtomicExchange(ptarg: *mut c_int, val: c_int) -> c_int {
intrinsics::atomic_xchg(ptarg, val)
}
#[no_mangle]
pub unsafe extern "C" fn pte_osAtomicCompareExchange(pdest: *mut c_int, exchange: c_int, comp: c_int) -> c_int {
intrinsics::atomic_cxchg(pdest, comp, exchange).0
}
#[no_mangle]
pub unsafe extern "C" fn pte_osAtomicExchangeAdd(pAppend: *mut c_int, value: c_int) -> c_int {
intrinsics::atomic_xadd(pAppend, value)
}
#[no_mangle]
pub unsafe extern "C" fn pte_osAtomicDecrement(pdest: *mut c_int) -> c_int {
intrinsics::atomic_xadd(pdest, -1) - 1
}
#[no_mangle]
pub unsafe extern "C" fn pte_osAtomicIncrement(pdest: *mut c_int) -> c_int {
intrinsics::atomic_xadd(pdest, 1) + 1
}
/*
pte_osResult pte_osTlsSetValue(unsigned int index, void * value)
void * pte_osTlsGetValue(unsigned int index)
pte_osResult pte_osTlsAlloc(unsigned int *pKey)
pte_osResult pte_osTlsFree(unsigned int index)
*/
#[no_mangle]
pub unsafe extern "C" fn pte_osTlsSetValue(index: c_uint, value: *mut c_void) -> pte_osResult {
locals().insert(index, value);
PTE_OS_OK
}
#[no_mangle]
pub unsafe extern "C" fn pte_osTlsGetValue(index: c_uint) -> *mut c_void {
locals().get_mut(&index).map(|x| *x).unwrap_or(ptr::null_mut())
}
#[no_mangle]
pub unsafe extern "C" fn pte_osTlsAlloc(pKey: *mut c_uint) -> pte_osResult {
NEXT_KEY.fetch_add(1, Ordering::SeqCst);
PTE_OS_OK
}
#[no_mangle]
pub unsafe extern "C" fn pte_osTlsFree(index: c_uint) -> pte_osResult {
// XXX free keys
PTE_OS_OK
}