diff options
| author | gingerBill <gingerBill@users.noreply.github.com> | 2019-12-01 11:33:23 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-12-01 11:33:23 +0000 |
| commit | 3fd5c3cd851d8f4dfd441141ca7e96889f069933 (patch) | |
| tree | 67f47e79f5c5bb80a3ed1b1e9d79a61c08c0a29d /core/os | |
| parent | 0c0c83ee295fe8787a4bdc8b826a5432abba2ca9 (diff) | |
| parent | 99121d6ff2b02f3d16b791eb103bb9f9e8b96475 (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.odin | 51 | ||||
| -rw-r--r-- | core/os/os_darwin.odin | 147 | ||||
| -rw-r--r-- | core/os/os_linux.odin | 213 | ||||
| -rw-r--r-- | core/os/os_windows.odin | 13 |
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)); |