]>
git.proxmox.com Git - rustc.git/blob - vendor/hermit-abi-0.2.6/src/lib.rs
1 //! `hermit-abi` is small interface to call functions from the unikernel
2 //! [RustyHermit](https://github.com/hermitcore/libhermit-rs).
5 #![allow(clippy::missing_safety_doc)]
6 #![allow(clippy::result_unit_err)]
12 use core
::mem
::MaybeUninit
;
16 // sysmbols, which are part of the library operating system
20 fn sys_srand(seed
: u32);
21 fn sys_secure_rand32(value
: *mut u32) -> i32;
22 fn sys_secure_rand64(value
: *mut u64) -> i32;
23 fn sys_get_processor_count() -> usize;
24 fn sys_malloc(size
: usize, align
: usize) -> *mut u8;
25 fn sys_realloc(ptr
: *mut u8, size
: usize, align
: usize, new_size
: usize) -> *mut u8;
26 fn sys_free(ptr
: *mut u8, size
: usize, align
: usize);
27 fn sys_init_queue(ptr
: usize) -> i32;
28 fn sys_notify(id
: usize, count
: i32) -> i32;
29 fn sys_add_queue(id
: usize, timeout_ns
: i64) -> i32;
30 fn sys_wait(id
: usize) -> i32;
31 fn sys_destroy_queue(id
: usize) -> i32;
32 fn sys_read(fd
: i32, buf
: *mut u8, len
: usize) -> isize;
33 fn sys_write(fd
: i32, buf
: *const u8, len
: usize) -> isize;
34 fn sys_close(fd
: i32) -> i32;
38 timeout
: *const timespec
,
41 fn sys_futex_wake(address
: *mut u32, count
: i32) -> i32;
42 fn sys_sem_init(sem
: *mut *const c_void
, value
: u32) -> i32;
43 fn sys_sem_destroy(sem
: *const c_void
) -> i32;
44 fn sys_sem_post(sem
: *const c_void
) -> i32;
45 fn sys_sem_trywait(sem
: *const c_void
) -> i32;
46 fn sys_sem_timedwait(sem
: *const c_void
, ms
: u32) -> i32;
47 fn sys_recmutex_init(recmutex
: *mut *const c_void
) -> i32;
48 fn sys_recmutex_destroy(recmutex
: *const c_void
) -> i32;
49 fn sys_recmutex_lock(recmutex
: *const c_void
) -> i32;
50 fn sys_recmutex_unlock(recmutex
: *const c_void
) -> i32;
51 fn sys_getpid() -> u32;
52 fn sys_exit(arg
: i32) -> !;
54 fn sys_usleep(usecs
: u64);
57 func
: extern "C" fn(usize),
63 func
: extern "C" fn(usize),
69 fn sys_join(id
: Tid
) -> i32;
71 fn sys_clock_gettime(clock_id
: u64, tp
: *mut timespec
) -> i32;
72 fn sys_open(name
: *const i8, flags
: i32, mode
: i32) -> i32;
73 fn sys_unlink(name
: *const i8) -> i32;
74 fn sys_network_init() -> i32;
75 fn sys_block_current_task();
76 fn sys_block_current_task_with_timeout(timeout
: u64);
77 fn sys_wakeup_task(tid
: Tid
);
78 fn sys_get_priority() -> u8;
79 fn sys_set_priority(tid
: Tid
, prio
: u8);
82 /// A thread handle type
85 /// Maximum number of priorities
86 pub const NO_PRIORITIES
: usize = 31;
88 /// Priority of a thread
89 #[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Copy)]
90 pub struct Priority(u8);
93 pub const fn into(self) -> u8 {
97 pub const fn from(x
: u8) -> Self {
102 pub const HIGH_PRIO
: Priority
= Priority
::from(3);
103 pub const NORMAL_PRIO
: Priority
= Priority
::from(2);
104 pub const LOW_PRIO
: Priority
= Priority
::from(1);
106 /// A handle, identifying a socket
107 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default, Hash)]
108 pub struct Handle(usize);
110 pub const NSEC_PER_SEC
: u64 = 1_000_000_000;
111 pub const FUTEX_RELATIVE_TIMEOUT
: u32 = 1;
112 pub const CLOCK_REALTIME
: u64 = 1;
113 pub const CLOCK_MONOTONIC
: u64 = 4;
114 pub const STDIN_FILENO
: libc
::c_int
= 0;
115 pub const STDOUT_FILENO
: libc
::c_int
= 1;
116 pub const STDERR_FILENO
: libc
::c_int
= 2;
117 pub const O_RDONLY
: i32 = 0o0;
118 pub const O_WRONLY
: i32 = 0o1;
119 pub const O_RDWR
: i32 = 0o2;
120 pub const O_CREAT
: i32 = 0o100;
121 pub const O_EXCL
: i32 = 0o200;
122 pub const O_TRUNC
: i32 = 0o1000;
123 pub const O_APPEND
: i32 = 0o2000;
125 /// returns true if file descriptor `fd` is a tty
126 pub fn isatty(_fd
: libc
::c_int
) -> bool
{
130 /// initialize the network stack
131 pub fn network_init() -> i32 {
132 unsafe { sys_network_init() }
135 /// `timespec` is used by `clock_gettime` to retrieve the
137 #[derive(Copy, Clone, Debug)]
139 pub struct timespec
{
146 /// Internet protocol version.
147 #[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
154 /// A four-octet IPv4 address.
155 #[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default)]
156 pub struct Ipv4Address(pub [u8; 4]);
158 /// A sixteen-octet IPv6 address.
159 #[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default)]
160 pub struct Ipv6Address(pub [u8; 16]);
162 /// An internetworking address.
163 #[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
165 /// An unspecified address.
166 /// May be used as a placeholder for storage where the address is not assigned yet.
174 /// determines the number of activated processors
176 pub unsafe fn get_processor_count() -> usize {
177 sys_get_processor_count()
182 pub unsafe fn malloc(size
: usize, align
: usize) -> *mut u8 {
183 sys_malloc(size
, align
)
188 pub unsafe fn realloc(ptr
: *mut u8, size
: usize, align
: usize, new_size
: usize) -> *mut u8 {
189 sys_realloc(ptr
, size
, align
, new_size
)
194 pub unsafe fn free(ptr
: *mut u8, size
: usize, align
: usize) {
195 sys_free(ptr
, size
, align
)
199 pub unsafe fn notify(id
: usize, count
: i32) -> i32 {
200 sys_notify(id
, count
)
205 pub unsafe fn add_queue(id
: usize, timeout_ns
: i64) -> i32 {
206 sys_add_queue(id
, timeout_ns
)
211 pub unsafe fn wait(id
: usize) -> i32 {
217 pub unsafe fn init_queue(id
: usize) -> i32 {
223 pub unsafe fn destroy_queue(id
: usize) -> i32 {
224 sys_destroy_queue(id
)
227 /// read from a file descriptor
229 /// read() attempts to read `len` bytes of data from the object
230 /// referenced by the descriptor `fd` into the buffer pointed
233 pub unsafe fn read(fd
: i32, buf
: *mut u8, len
: usize) -> isize {
234 sys_read(fd
, buf
, len
)
237 /// write to a file descriptor
239 /// write() attempts to write `len` of data to the object
240 /// referenced by the descriptor `fd` from the
241 /// buffer pointed to by `buf`.
243 pub unsafe fn write(fd
: i32, buf
: *const u8, len
: usize) -> isize {
244 sys_write(fd
, buf
, len
)
247 /// close a file descriptor
249 /// The close() call deletes a file descriptor `fd` from the object
252 pub unsafe fn close(fd
: i32) -> i32 {
256 /// If the value at address matches the expected value, park the current thread until it is either
257 /// woken up with [`futex_wake`] (returns 0) or an optional timeout elapses (returns -ETIMEDOUT).
259 /// Setting `timeout` to null means the function will only return if [`futex_wake`] is called.
260 /// Otherwise, `timeout` is interpreted as an absolute time measured with [`CLOCK_MONOTONIC`].
261 /// If [`FUTEX_RELATIVE_TIMEOUT`] is set in `flags` the timeout is understood to be relative
262 /// to the current time.
264 /// Returns -EINVAL if `address` is null, the timeout is negative or `flags` contains unknown values.
266 pub unsafe fn futex_wait(
269 timeout
: *const timespec
,
272 sys_futex_wait(address
, expected
, timeout
, flags
)
275 /// Wake `count` threads waiting on the futex at `address`. Returns the number of threads
276 /// woken up (saturates to `i32::MAX`). If `count` is `i32::MAX`, wake up all matching
277 /// waiting threads. If `count` is negative or `address` is null, returns -EINVAL.
279 pub unsafe fn futex_wake(address
: *mut u32, count
: i32) -> i32 {
280 sys_futex_wake(address
, count
)
283 /// sem_init() initializes the unnamed semaphore at the address
284 /// pointed to by `sem`. The `value` argument specifies the
285 /// initial value for the semaphore.
287 pub unsafe fn sem_init(sem
: *mut *const c_void
, value
: u32) -> i32 {
288 sys_sem_init(sem
, value
)
291 /// sem_destroy() frees the unnamed semaphore at the address
292 /// pointed to by `sem`.
294 pub unsafe fn sem_destroy(sem
: *const c_void
) -> i32 {
298 /// sem_post() increments the semaphore pointed to by `sem`.
299 /// If the semaphore's value consequently becomes greater
300 /// than zero, then another thread blocked in a sem_wait call
301 /// will be woken up and proceed to lock the semaphore.
303 pub unsafe fn sem_post(sem
: *const c_void
) -> i32 {
307 /// try to decrement a semaphore
309 /// sem_trywait() is the same as sem_timedwait(), except that
310 /// if the decrement cannot be immediately performed, then call
311 /// returns a negative value instead of blocking.
313 pub unsafe fn sem_trywait(sem
: *const c_void
) -> i32 {
317 /// decrement a semaphore
319 /// sem_timedwait() decrements the semaphore pointed to by `sem`.
320 /// If the semaphore's value is greater than zero, then the
321 /// the function returns immediately. If the semaphore currently
322 /// has the value zero, then the call blocks until either
323 /// it becomes possible to perform the decrement of the time limit
324 /// to wait for the semaphore is expired. A time limit `ms` of
325 /// means infinity waiting time.
327 pub unsafe fn sem_timedwait(sem
: *const c_void
, ms
: u32) -> i32 {
328 sys_sem_timedwait(sem
, ms
)
333 pub unsafe fn recmutex_init(recmutex
: *mut *const c_void
) -> i32 {
334 sys_recmutex_init(recmutex
)
339 pub unsafe fn recmutex_destroy(recmutex
: *const c_void
) -> i32 {
340 sys_recmutex_destroy(recmutex
)
345 pub unsafe fn recmutex_lock(recmutex
: *const c_void
) -> i32 {
346 sys_recmutex_lock(recmutex
)
351 pub unsafe fn recmutex_unlock(recmutex
: *const c_void
) -> i32 {
352 sys_recmutex_unlock(recmutex
)
355 /// Determines the id of the current thread
357 pub unsafe fn getpid() -> u32 {
361 /// cause normal termination and return `arg`
362 /// to the host system
364 pub unsafe fn exit(arg
: i32) -> ! {
368 /// cause abnormal termination
370 pub unsafe fn abort() -> ! {
374 /// suspend execution for microsecond intervals
376 /// The usleep() function suspends execution of the calling
377 /// thread for (at least) `usecs` microseconds.
379 pub unsafe fn usleep(usecs
: u64) {
383 /// spawn a new thread
385 /// spawn() starts a new thread. The new thread starts execution
386 /// by invoking `func(usize)`; `arg` is passed as the argument
387 /// to `func`. `prio` defines the priority of the new thread,
388 /// which can be between `LOW_PRIO` and `HIGH_PRIO`.
389 /// `core_id` defines the core, where the thread is located.
390 /// A negative value give the operating system the possibility
391 /// to select the core by its own.
395 func
: extern "C" fn(usize),
400 sys_spawn(id
, func
, arg
, prio
, core_id
)
403 /// spawn a new thread with user-specified stack size
405 /// spawn2() starts a new thread. The new thread starts execution
406 /// by invoking `func(usize)`; `arg` is passed as the argument
407 /// to `func`. `prio` defines the priority of the new thread,
408 /// which can be between `LOW_PRIO` and `HIGH_PRIO`.
409 /// `core_id` defines the core, where the thread is located.
410 /// A negative value give the operating system the possibility
411 /// to select the core by its own.
412 /// In contrast to spawn(), spawn2() is able to define the
415 pub unsafe fn spawn2(
416 func
: extern "C" fn(usize),
422 sys_spawn2(func
, arg
, prio
, stack_size
, core_id
)
425 /// join with a terminated thread
427 /// The join() function waits for the thread specified by `id`
430 pub unsafe fn join(id
: Tid
) -> i32 {
434 /// yield the processor
436 /// causes the calling thread to relinquish the CPU. The thread
437 /// is moved to the end of the queue for its static priority.
439 pub unsafe fn yield_now() {
445 /// The clock_gettime() functions allow the calling thread
446 /// to retrieve the value used by a clock which is specified
449 /// `CLOCK_REALTIME`: the system's real time clock,
450 /// expressed as the amount of time since the Epoch.
452 /// `CLOCK_MONOTONIC`: clock that increments monotonically,
453 /// tracking the time since an arbitrary point
455 pub unsafe fn clock_gettime(clock_id
: u64, tp
: *mut timespec
) -> i32 {
456 sys_clock_gettime(clock_id
, tp
)
459 /// open and possibly create a file
461 /// The open() system call opens the file specified by `name`.
462 /// If the specified file does not exist, it may optionally
463 /// be created by open().
465 pub unsafe fn open(name
: *const i8, flags
: i32, mode
: i32) -> i32 {
466 sys_open(name
, flags
, mode
)
469 /// delete the file it refers to `name`
471 pub unsafe fn unlink(name
: *const i8) -> i32 {
475 /// The largest number `rand` will return
476 pub const RAND_MAX
: u64 = 2_147_483_647;
478 /// The function computes a sequence of pseudo-random integers
479 /// in the range of 0 to RAND_MAX
481 pub unsafe fn rand() -> u32 {
485 /// The function sets its argument as the seed for a new sequence
486 /// of pseudo-random numbers to be returned by `rand`
488 pub unsafe fn srand(seed
: u32) {
492 /// Create a cryptographicly secure 32bit random number with the support of
493 /// the underlying hardware. If the required hardware isn't available,
494 /// the function returns `None`.
496 pub unsafe fn secure_rand32() -> Option
<u32> {
497 let mut rand
= MaybeUninit
::uninit();
498 let res
= sys_secure_rand32(rand
.as_mut_ptr());
499 (res
== 0).then(|| rand
.assume_init())
502 /// Create a cryptographicly secure 64bit random number with the support of
503 /// the underlying hardware. If the required hardware isn't available,
504 /// the function returns `None`.
506 pub unsafe fn secure_rand64() -> Option
<u64> {
507 let mut rand
= MaybeUninit
::uninit();
508 let res
= sys_secure_rand64(rand
.as_mut_ptr());
509 (res
== 0).then(|| rand
.assume_init())
512 /// Add current task to the queue of blocked tasks. After calling `block_current_task`,
513 /// call `yield_now` to switch to another task.
515 pub unsafe fn block_current_task() {
516 sys_block_current_task();
519 /// Add current task to the queue of blocked tasks, but wake it when `timeout` milliseconds
522 /// After calling `block_current_task`, call `yield_now` to switch to another task.
524 pub unsafe fn block_current_task_with_timeout(timeout
: u64) {
525 sys_block_current_task_with_timeout(timeout
);
528 /// Wakeup task with the thread id `tid`
530 pub unsafe fn wakeup_task(tid
: Tid
) {
531 sys_wakeup_task(tid
);
534 /// Determine the priority of the current thread
536 pub unsafe fn get_priority() -> Priority
{
537 Priority
::from(sys_get_priority())
540 /// Determine the priority of the current thread
542 pub unsafe fn set_priority(tid
: Tid
, prio
: Priority
) {
543 sys_set_priority(tid
, prio
.into());