aboutsummaryrefslogtreecommitdiff
path: root/core/os
diff options
context:
space:
mode:
authorgingerBill <gingerBill@users.noreply.github.com>2019-12-01 11:33:23 +0000
committerGitHub <noreply@github.com>2019-12-01 11:33:23 +0000
commit3fd5c3cd851d8f4dfd441141ca7e96889f069933 (patch)
tree67f47e79f5c5bb80a3ed1b1e9d79a61c08c0a29d /core/os
parent0c0c83ee295fe8787a4bdc8b826a5432abba2ca9 (diff)
parent99121d6ff2b02f3d16b791eb103bb9f9e8b96475 (diff)
Merge pull request #458 from Tetralux/linux-threads
Implement core:thread and core:sync on Unix using pthreads
Diffstat (limited to 'core/os')
-rw-r--r--core/os/os.odin51
-rw-r--r--core/os/os_darwin.odin147
-rw-r--r--core/os/os_linux.odin213
-rw-r--r--core/os/os_windows.odin13
4 files changed, 347 insertions, 77 deletions
diff --git a/core/os/os.odin b/core/os/os.odin
index d9bb318c4..7d6f4451d 100644
--- a/core/os/os.odin
+++ b/core/os/os.odin
@@ -119,16 +119,54 @@ read_ptr :: proc(fd: Handle, data: rawptr, len: int) -> (int, Errno) {
return read(fd, s);
}
-
heap_allocator_proc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode,
size, alignment: int,
old_memory: rawptr, old_size: int, flags: u64 = 0, loc := #caller_location) -> rawptr {
+ //
+ // NOTE(tetra, 2019-11-10): The heap doesn't respect alignment.
+ // HACK: Overallocate, align forwards, and then use the two bytes immediately before
+ // the address we return, to store the padding we inserted.
+ // This allows us to pass the original pointer we got back from the heap to `free` later.
+ //
+
+ align_and_store_padding :: proc(ptr: rawptr, alignment: int) -> rawptr {
+ ptr := mem.ptr_offset(cast(^u8) ptr, 2);
+ new_ptr := cast(^u8) mem.align_forward(ptr, uintptr(alignment));
+ offset := mem.ptr_sub(new_ptr, cast(^u8) ptr) + 2;
+ assert(offset < int(max(u16)));
+ (^[2]u8)(mem.ptr_offset(new_ptr, -2))^ = transmute([2]u8) u16(offset);
+ return new_ptr;
+ }
+
+ recover_original_pointer :: proc(ptr: rawptr) -> rawptr {
+ ptr := cast(^u8) ptr;
+ offset := transmute(u16) (^[2]u8)(mem.ptr_offset(ptr, -2))^;
+ ptr = mem.ptr_offset(ptr, -int(offset));
+ return ptr;
+ }
+
+ aligned_heap_alloc :: proc(size: int, alignment: int) -> rawptr {
+ // NOTE(tetra): Alignment 1 will mean we only have one extra byte.
+ // This is not enough for a u16 - so we ensure there is at least two bytes extra.
+ // This also means that the pointer is always aligned to at least 2.
+ extra := alignment;
+ if extra <= 1 do extra = 2;
+
+ orig := cast(^u8) heap_alloc(size + extra);
+ if orig == nil do return nil;
+ ptr := align_and_store_padding(orig, alignment);
+ assert(recover_original_pointer(ptr) == orig);
+ return ptr;
+ }
+
switch mode {
case .Alloc:
- return heap_alloc(size);
+ return aligned_heap_alloc(size, alignment);
case .Free:
- heap_free(old_memory);
+ assert(old_memory != nil);
+ ptr := recover_original_pointer(old_memory);
+ heap_free(ptr);
return nil;
case .Free_All:
@@ -136,11 +174,12 @@ heap_allocator_proc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode,
case .Resize:
if old_memory == nil {
- return heap_alloc(size);
+ return aligned_heap_alloc(size, alignment);
}
- ptr := heap_resize(old_memory, size);
+ ptr := recover_original_pointer(old_memory);
+ ptr = heap_resize(ptr, size);
assert(ptr != nil);
- return ptr;
+ return align_and_store_padding(ptr, alignment);
}
return nil;
diff --git a/core/os/os_darwin.odin b/core/os/os_darwin.odin
index c252cf05c..3bca732ec 100644
--- a/core/os/os_darwin.odin
+++ b/core/os/os_darwin.odin
@@ -14,6 +14,142 @@ Errno :: distinct int;
INVALID_HANDLE :: ~Handle(0);
+ERROR_NONE: Errno : 0;
+EPERM: Errno : 1; /* Operation not permitted */
+ENOENT: Errno : 2; /* No such file or directory */
+ESRCH: Errno : 3; /* No such process */
+EINTR: Errno : 4; /* Interrupted system call */
+EIO: Errno : 5; /* Input/output error */
+ENXIO: Errno : 6; /* Device not configured */
+E2BIG: Errno : 7; /* Argument list too long */
+ENOEXEC: Errno : 8; /* Exec format error */
+EBADF: Errno : 9; /* Bad file descriptor */
+ECHILD: Errno : 10; /* No child processes */
+EDEADLK: Errno : 11; /* Resource deadlock avoided */
+ENOMEM: Errno : 12; /* Cannot allocate memory */
+EACCES: Errno : 13; /* Permission denied */
+EFAULT: Errno : 14; /* Bad address */
+ENOTBLK: Errno : 15; /* Block device required */
+EBUSY: Errno : 16; /* Device / Resource busy */
+EEXIST: Errno : 17; /* File exists */
+EXDEV: Errno : 18; /* Cross-device link */
+ENODEV: Errno : 19; /* Operation not supported by device */
+ENOTDIR: Errno : 20; /* Not a directory */
+EISDIR: Errno : 21; /* Is a directory */
+EINVAL: Errno : 22; /* Invalid argument */
+ENFILE: Errno : 23; /* Too many open files in system */
+EMFILE: Errno : 24; /* Too many open files */
+ENOTTY: Errno : 25; /* Inappropriate ioctl for device */
+ETXTBSY: Errno : 26; /* Text file busy */
+EFBIG: Errno : 27; /* File too large */
+ENOSPC: Errno : 28; /* No space left on device */
+ESPIPE: Errno : 29; /* Illegal seek */
+EROFS: Errno : 30; /* Read-only file system */
+EMLINK: Errno : 31; /* Too many links */
+EPIPE: Errno : 32; /* Broken pipe */
+
+/* math software */
+EDOM: Errno : 33; /* Numerical argument out of domain */
+ERANGE: Errno : 34; /* Result too large */
+
+/* non-blocking and interrupt i/o */
+EAGAIN: Errno : 35; /* Resource temporarily unavailable */
+EWOULDBLOCK: Errno : EAGAIN; /* Operation would block */
+EINPROGRESS: Errno : 36; /* Operation now in progress */
+EALREADY: Errno : 37; /* Operation already in progress */
+
+/* ipc/network software -- argument errors */
+ENOTSOCK: Errno : 38; /* Socket operation on non-socket */
+EDESTADDRREQ: Errno : 39; /* Destination address required */
+EMSGSIZE: Errno : 40; /* Message too long */
+EPROTOTYPE: Errno : 41; /* Protocol wrong type for socket */
+ENOPROTOOPT: Errno : 42; /* Protocol not available */
+EPROTONOSUPPORT: Errno : 43; /* Protocol not supported */
+ESOCKTNOSUPPORT: Errno : 44; /* Socket type not supported */
+ENOTSUP: Errno : 45; /* Operation not supported */
+EPFNOSUPPORT: Errno : 46; /* Protocol family not supported */
+EAFNOSUPPORT: Errno : 47; /* Address family not supported by protocol family */
+EADDRINUSE: Errno : 48; /* Address already in use */
+EADDRNOTAVAIL: Errno : 49; /* Can't assign requested address */
+
+/* ipc/network software -- operational errors */
+ENETDOWN: Errno : 50; /* Network is down */
+ENETUNREACH: Errno : 51; /* Network is unreachable */
+ENETRESET: Errno : 52; /* Network dropped connection on reset */
+ECONNABORTED: Errno : 53; /* Software caused connection abort */
+ECONNRESET: Errno : 54; /* Connection reset by peer */
+ENOBUFS: Errno : 55; /* No buffer space available */
+EISCONN: Errno : 56; /* Socket is already connected */
+ENOTCONN: Errno : 57; /* Socket is not connected */
+ESHUTDOWN: Errno : 58; /* Can't send after socket shutdown */
+ETOOMANYREFS: Errno : 59; /* Too many references: can't splice */
+ETIMEDOUT: Errno : 60; /* Operation timed out */
+ECONNREFUSED: Errno : 61; /* Connection refused */
+
+ELOOP: Errno : 62; /* Too many levels of symbolic links */
+ENAMETOOLONG: Errno : 63; /* File name too long */
+
+/* should be rearranged */
+EHOSTDOWN: Errno : 64; /* Host is down */
+EHOSTUNREACH: Errno : 65; /* No route to host */
+ENOTEMPTY: Errno : 66; /* Directory not empty */
+
+/* quotas & mush */
+EPROCLIM: Errno : 67; /* Too many processes */
+EUSERS: Errno : 68; /* Too many users */
+EDQUOT: Errno : 69; /* Disc quota exceeded */
+
+/* Network File System */
+ESTALE: Errno : 70; /* Stale NFS file handle */
+EREMOTE: Errno : 71; /* Too many levels of remote in path */
+EBADRPC: Errno : 72; /* RPC struct is bad */
+ERPCMISMATCH: Errno : 73; /* RPC version wrong */
+EPROGUNAVAIL: Errno : 74; /* RPC prog. not avail */
+EPROGMISMATCH: Errno : 75; /* Program version wrong */
+EPROCUNAVAIL: Errno : 76; /* Bad procedure for program */
+
+ENOLCK: Errno : 77; /* No locks available */
+ENOSYS: Errno : 78; /* Function not implemented */
+
+EFTYPE: Errno : 79; /* Inappropriate file type or format */
+EAUTH: Errno : 80; /* Authentication error */
+ENEEDAUTH: Errno : 81; /* Need authenticator */
+
+/* Intelligent device errors */
+EPWROFF: Errno : 82; /* Device power is off */
+EDEVERR: Errno : 83; /* Device error, e.g. paper out */
+EOVERFLOW: Errno : 84; /* Value too large to be stored in data type */
+
+/* Program loading errors */
+EBADEXEC: Errno : 85; /* Bad executable */
+EBADARCH: Errno : 86; /* Bad CPU type in executable */
+ESHLIBVERS: Errno : 87; /* Shared library version mismatch */
+EBADMACHO: Errno : 88; /* Malformed Macho file */
+
+ECANCELED: Errno : 89; /* Operation canceled */
+
+EIDRM: Errno : 90; /* Identifier removed */
+ENOMSG: Errno : 91; /* No message of desired type */
+EILSEQ: Errno : 92; /* Illegal byte sequence */
+ENOATTR: Errno : 93; /* Attribute not found */
+
+EBADMSG: Errno : 94; /* Bad message */
+EMULTIHOP: Errno : 95; /* Reserved */
+ENODATA: Errno : 96; /* No message available on STREAM */
+ENOLINK: Errno : 97; /* Reserved */
+ENOSR: Errno : 98; /* No STREAM resources */
+ENOSTR: Errno : 99; /* Not a STREAM */
+EPROTO: Errno : 100; /* Protocol error */
+ETIME: Errno : 101; /* STREAM ioctl timeout */
+
+ENOPOLICY: Errno : 103; /* No such policy registered */
+
+ENOTRECOVERABLE: Errno : 104; /* State not recoverable */
+EOWNERDEAD: Errno : 105; /* Previous owner died */
+
+EQFULL: Errno : 106; /* Interface output queue is full */
+ELAST: Errno : 106; /* Must be equal largest errno */
+
O_RDONLY :: 0x00000;
O_WRONLY :: 0x00001;
O_RDWR :: 0x00002;
@@ -133,6 +269,7 @@ foreign libc {
@(link_name="write") _unix_write :: proc(handle: Handle, buffer: rawptr, count: int) -> int ---;
@(link_name="lseek") _unix_lseek :: proc(fs: Handle, offset: int, whence: int) -> int ---;
@(link_name="gettid") _unix_gettid :: proc() -> u64 ---;
+ @(link_name="getpagesize") _unix_getpagesize :: proc() -> i32 ---;
@(link_name="stat") _unix_stat :: proc(path: cstring, stat: ^Stat) -> int ---;
@(link_name="access") _unix_access :: proc(path: cstring, mask: int) -> int ---;
@@ -287,6 +424,16 @@ dlerror :: proc() -> string {
return string(_unix_dlerror());
}
+get_page_size :: proc() -> int {
+ // NOTE(tetra): The page size never changes, so why do anything complicated
+ // if we don't have to.
+ @static page_size := -1;
+ if page_size != -1 do return page_size;
+
+ page_size = int(_unix_getpagesize());
+ return page_size;
+}
+
_alloc_command_line_arguments :: proc() -> []string {
res := make([]string, len(runtime.args__));
diff --git a/core/os/os_linux.odin b/core/os/os_linux.odin
index dc3cdde93..cf03dac71 100644
--- a/core/os/os_linux.odin
+++ b/core/os/os_linux.odin
@@ -15,37 +15,138 @@ Syscall :: distinct int;
INVALID_HANDLE :: ~Handle(0);
-ERROR_NONE: Errno : 0;
-EPERM: Errno : 1;
-ENOENT: Errno : 2;
-EINTR: Errno : 4;
-EIO: Errno : 5;
-ENXIO: Errno : 6;
-EBADF: Errno : 9;
-EAGAIN: Errno : 11;
-EWOULDBLOCK: Errno : EAGAIN;
-ENOMEM: Errno : 12;
-EACCES: Errno : 13;
-EFAULT: Errno : 14;
-EEXIST: Errno : 17;
-ENODEV: Errno : 19;
-ENOTDIR: Errno : 20;
-EISDIR: Errno : 21;
-EINVAL: Errno : 22;
-ENFILE: Errno : 23;
-EMFILE: Errno : 24;
-ETXTBSY: Errno : 26;
-EFBIG: Errno : 27;
-ENOSPC: Errno : 28;
-ESPIPE: Errno : 29;
-EROFS: Errno : 30;
-EPIPE: Errno : 32;
-ENAMETOOLONG: Errno : 36;
-ELOOP: Errno : 40;
-EOVERFLOW: Errno : 75;
-EDESTADDRREQ: Errno : 89;
-EOPNOTSUPP: Errno : 95;
-EDQUOT: Errno : 122;
+ERROR_NONE: Errno : 0;
+EPERM: Errno : 1;
+ENOENT: Errno : 2;
+ESRCH: Errno : 3;
+EINTR: Errno : 4;
+EIO: Errno : 5;
+ENXIO: Errno : 6;
+EBADF: Errno : 9;
+EAGAIN: Errno : 11;
+ENOMEM: Errno : 12;
+EACCES: Errno : 13;
+EFAULT: Errno : 14;
+EEXIST: Errno : 17;
+ENODEV: Errno : 19;
+ENOTDIR: Errno : 20;
+EISDIR: Errno : 21;
+EINVAL: Errno : 22;
+ENFILE: Errno : 23;
+EMFILE: Errno : 24;
+ETXTBSY: Errno : 26;
+EFBIG: Errno : 27;
+ENOSPC: Errno : 28;
+ESPIPE: Errno : 29;
+EROFS: Errno : 30;
+EPIPE: Errno : 32;
+
+EDEADLK: Errno : 35; /* Resource deadlock would occur */
+ENAMETOOLONG: Errno : 36; /* File name too long */
+ENOLCK: Errno : 37; /* No record locks available */
+
+ENOSYS: Errno : 38; /* Invalid system call number */
+
+ENOTEMPTY: Errno : 39; /* Directory not empty */
+ELOOP: Errno : 40; /* Too many symbolic links encountered */
+EWOULDBLOCK: Errno : EAGAIN; /* Operation would block */
+ENOMSG: Errno : 42; /* No message of desired type */
+EIDRM: Errno : 43; /* Identifier removed */
+ECHRNG: Errno : 44; /* Channel number out of range */
+EL2NSYNC: Errno : 45; /* Level 2 not synchronized */
+EL3HLT: Errno : 46; /* Level 3 halted */
+EL3RST: Errno : 47; /* Level 3 reset */
+ELNRNG: Errno : 48; /* Link number out of range */
+EUNATCH: Errno : 49; /* Protocol driver not attached */
+ENOCSI: Errno : 50; /* No CSI structure available */
+EL2HLT: Errno : 51; /* Level 2 halted */
+EBADE: Errno : 52; /* Invalid exchange */
+EBADR: Errno : 53; /* Invalid request descriptor */
+EXFULL: Errno : 54; /* Exchange full */
+ENOANO: Errno : 55; /* No anode */
+EBADRQC: Errno : 56; /* Invalid request code */
+EBADSLT: Errno : 57; /* Invalid slot */
+EDEADLOCK: Errno : EDEADLK;
+EBFONT: Errno : 59; /* Bad font file format */
+ENOSTR: Errno : 60; /* Device not a stream */
+ENODATA: Errno : 61; /* No data available */
+ETIME: Errno : 62; /* Timer expired */
+ENOSR: Errno : 63; /* Out of streams resources */
+ENONET: Errno : 64; /* Machine is not on the network */
+ENOPKG: Errno : 65; /* Package not installed */
+EREMOTE: Errno : 66; /* Object is remote */
+ENOLINK: Errno : 67; /* Link has been severed */
+EADV: Errno : 68; /* Advertise error */
+ESRMNT: Errno : 69; /* Srmount error */
+ECOMM: Errno : 70; /* Communication error on send */
+EPROTO: Errno : 71; /* Protocol error */
+EMULTIHOP: Errno : 72; /* Multihop attempted */
+EDOTDOT: Errno : 73; /* RFS specific error */
+EBADMSG: Errno : 74; /* Not a data message */
+EOVERFLOW: Errno : 75; /* Value too large for defined data type */
+ENOTUNIQ: Errno : 76; /* Name not unique on network */
+EBADFD: Errno : 77; /* File descriptor in bad state */
+EREMCHG: Errno : 78; /* Remote address changed */
+ELIBACC: Errno : 79; /* Can not access a needed shared library */
+ELIBBAD: Errno : 80; /* Accessing a corrupted shared library */
+ELIBSCN: Errno : 81; /* .lib section in a.out corrupted */
+ELIBMAX: Errno : 82; /* Attempting to link in too many shared libraries */
+ELIBEXEC: Errno : 83; /* Cannot exec a shared library directly */
+EILSEQ: Errno : 84; /* Illegal byte sequence */
+ERESTART: Errno : 85; /* Interrupted system call should be restarted */
+ESTRPIPE: Errno : 86; /* Streams pipe error */
+EUSERS: Errno : 87; /* Too many users */
+ENOTSOCK: Errno : 88; /* Socket operation on non-socket */
+EDESTADDRREQ: Errno : 89; /* Destination address required */
+EMSGSIZE: Errno : 90; /* Message too long */
+EPROTOTYPE: Errno : 91; /* Protocol wrong type for socket */
+ENOPROTOOPT: Errno : 92; /* Protocol not available */
+EPROTONOSUPPORT: Errno : 93; /* Protocol not supported */
+ESOCKTNOSUPPORT: Errno : 94; /* Socket type not supported */
+EOPNOTSUPP: Errno : 95; /* Operation not supported on transport endpoint */
+EPFNOSUPPORT: Errno : 96; /* Protocol family not supported */
+EAFNOSUPPORT: Errno : 97; /* Address family not supported by protocol */
+EADDRINUSE: Errno : 98; /* Address already in use */
+EADDRNOTAVAIL: Errno : 99; /* Cannot assign requested address */
+ENETDOWN: Errno : 100; /* Network is down */
+ENETUNREACH: Errno : 101; /* Network is unreachable */
+ENETRESET: Errno : 102; /* Network dropped connection because of reset */
+ECONNABORTED: Errno : 103; /* Software caused connection abort */
+ECONNRESET: Errno : 104; /* Connection reset by peer */
+ENOBUFS: Errno : 105; /* No buffer space available */
+EISCONN: Errno : 106; /* Transport endpoint is already connected */
+ENOTCONN: Errno : 107; /* Transport endpoint is not connected */
+ESHUTDOWN: Errno : 108; /* Cannot send after transport endpoint shutdown */
+ETOOMANYREFS: Errno : 109; /* Too many references: cannot splice */
+ETIMEDOUT: Errno : 110; /* Connection timed out */
+ECONNREFUSED: Errno : 111; /* Connection refused */
+EHOSTDOWN: Errno : 112; /* Host is down */
+EHOSTUNREACH: Errno : 113; /* No route to host */
+EALREADY: Errno : 114; /* Operation already in progress */
+EINPROGRESS: Errno : 115; /* Operation now in progress */
+ESTALE: Errno : 116; /* Stale file handle */
+EUCLEAN: Errno : 117; /* Structure needs cleaning */
+ENOTNAM: Errno : 118; /* Not a XENIX named type file */
+ENAVAIL: Errno : 119; /* No XENIX semaphores available */
+EISNAM: Errno : 120; /* Is a named type file */
+EREMOTEIO: Errno : 121; /* Remote I/O error */
+EDQUOT: Errno : 122; /* Quota exceeded */
+
+ENOMEDIUM: Errno : 123; /* No medium found */
+EMEDIUMTYPE: Errno : 124; /* Wrong medium type */
+ECANCELED: Errno : 125; /* Operation Canceled */
+ENOKEY: Errno : 126; /* Required key not available */
+EKEYEXPIRED: Errno : 127; /* Key has expired */
+EKEYREVOKED: Errno : 128; /* Key has been revoked */
+EKEYREJECTED: Errno : 129; /* Key was rejected by service */
+
+/* for robust mutexes */
+EOWNERDEAD: Errno : 130; /* Owner died */
+ENOTRECOVERABLE: Errno : 131; /* State not recoverable */
+
+ERFKILL: Errno : 132; /* Operation not possible due to RF-kill */
+
+EHWPOISON: Errno : 133; /* Memory page has hardware error */
O_RDONLY :: 0x00000;
O_WRONLY :: 0x00001;
@@ -152,22 +253,6 @@ X_OK :: 1; // Test for execute permission
W_OK :: 2; // Test for write permission
R_OK :: 4; // Test for read permission
-TimeSpec :: struct {
- tv_sec : i64, /* seconds */
- tv_nsec : i64, /* nanoseconds */
-};
-
-CLOCK_REALTIME :: 0;
-CLOCK_MONOTONIC :: 1;
-CLOCK_PROCESS_CPUTIME_ID :: 2;
-CLOCK_THREAD_CPUTIME_ID :: 3;
-CLOCK_MONOTONIC_RAW :: 4;
-CLOCK_REALTIME_COARSE :: 5;
-CLOCK_MONOTONIC_COARSE :: 6;
-CLOCK_BOOTTIME :: 7;
-CLOCK_REALTIME_ALARM :: 8;
-CLOCK_BOOTTIME_ALARM :: 9;
-
SYS_GETTID: Syscall : 186;
foreign libc {
@@ -180,6 +265,7 @@ foreign libc {
@(link_name="write") _unix_write :: proc(fd: Handle, buf: rawptr, size: int) -> int ---;
@(link_name="lseek64") _unix_seek :: proc(fd: Handle, offset: i64, whence: i32) -> i64 ---;
@(link_name="gettid") _unix_gettid :: proc() -> u64 ---;
+ @(link_name="getpagesize") _unix_getpagesize :: proc() -> i32 ---;
@(link_name="stat") _unix_stat :: proc(path: cstring, stat: ^Stat) -> int ---;
@(link_name="fstat") _unix_fstat :: proc(fd: Handle, stat: ^Stat) -> int ---;
@(link_name="access") _unix_access :: proc(path: cstring, mask: int) -> int ---;
@@ -190,10 +276,6 @@ foreign libc {
@(link_name="realloc") _unix_realloc :: proc(ptr: rawptr, size: int) -> rawptr ---;
@(link_name="getenv") _unix_getenv :: proc(cstring) -> cstring ---;
- @(link_name="clock_gettime") _unix_clock_gettime :: proc(clock_id: u64, timespec: ^TimeSpec) ---;
- @(link_name="nanosleep") _unix_nanosleep :: proc(requested: ^TimeSpec, remaining: ^TimeSpec) -> int ---;
- @(link_name="sleep") _unix_sleep :: proc(seconds: u64) -> int ---;
-
@(link_name="exit") _unix_exit :: proc(status: int) -> ! ---;
}
foreign dl {
@@ -349,25 +431,6 @@ exit :: proc(code: int) -> ! {
_unix_exit(code);
}
-clock_gettime :: proc(clock_id: u64) -> TimeSpec {
- ts : TimeSpec;
- _unix_clock_gettime(clock_id, &ts);
- return ts;
-}
-
-sleep :: proc(seconds: u64) -> int {
-
- return _unix_sleep(seconds);
-}
-
-nanosleep :: proc(nanoseconds: i64) -> int {
- assert(nanoseconds <= 999999999);
- requested, remaining : TimeSpec;
- requested = TimeSpec{tv_nsec = nanoseconds};
-
- return _unix_nanosleep(&requested, &remaining);
-}
-
current_thread_id :: proc "contextless" () -> int {
return syscall(SYS_GETTID);
}
@@ -393,6 +456,16 @@ dlerror :: proc() -> string {
return string(_unix_dlerror());
}
+get_page_size :: proc() -> int {
+ // NOTE(tetra): The page size never changes, so why do anything complicated
+ // if we don't have to.
+ @static page_size := -1;
+ if page_size != -1 do return page_size;
+
+ page_size = int(_unix_getpagesize());
+ return page_size;
+}
+
_alloc_command_line_arguments :: proc() -> []string {
res := make([]string, len(runtime.args__));
diff --git a/core/os/os_windows.odin b/core/os/os_windows.odin
index e45cf9f5f..f433a2517 100644
--- a/core/os/os_windows.odin
+++ b/core/os/os_windows.odin
@@ -210,7 +210,6 @@ get_std_handle :: proc(h: int) -> Handle {
-
last_write_time :: proc(fd: Handle) -> (File_Time, Errno) {
file_info: win32.By_Handle_File_Information;
if !win32.get_file_information_by_handle(win32.Handle(fd), &file_info) {
@@ -253,6 +252,18 @@ heap_free :: proc(ptr: rawptr) {
win32.heap_free(win32.get_process_heap(), 0, ptr);
}
+get_page_size :: proc() -> int {
+ // NOTE(tetra): The page size never changes, so why do anything complicated
+ // if we don't have to.
+ @static page_size := -1;
+ if page_size != -1 do return page_size;
+
+ info: win32.System_Info;
+ win32.get_system_info(&info);
+ page_size = int(info.page_size);
+ return page_size;
+}
+
exit :: proc(code: int) -> ! {
win32.exit_process(u32(code));