spall_unix.odin 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. //+private
  2. //+build darwin, freebsd, openbsd
  3. package spall
  4. // Only for types.
  5. import "core:os"
  6. when ODIN_OS == .Darwin {
  7. foreign import libc "system:System.framework"
  8. } else {
  9. foreign import libc "system:c"
  10. }
  11. timespec :: struct {
  12. tv_sec: i64, // seconds
  13. tv_nsec: i64, // nanoseconds
  14. }
  15. foreign libc {
  16. __error :: proc() -> ^i32 ---
  17. @(link_name="write") _unix_write :: proc(handle: os.Handle, buffer: rawptr, count: uint) -> int ---
  18. @(link_name="clock_gettime") _unix_clock_gettime :: proc(clock_id: u64, timespec: ^timespec) -> i32 ---
  19. }
  20. @(no_instrumentation)
  21. get_last_error :: proc "contextless" () -> int {
  22. return int(__error()^)
  23. }
  24. MAX_RW :: 0x7fffffff
  25. @(no_instrumentation)
  26. _write :: proc "contextless" (fd: os.Handle, data: []byte) -> (n: int, err: os.Errno) #no_bounds_check /* bounds check would segfault instrumentation */ {
  27. if len(data) == 0 {
  28. return 0, os.ERROR_NONE
  29. }
  30. for n < len(data) {
  31. chunk := data[:min(len(data), MAX_RW)]
  32. written := _unix_write(fd, raw_data(chunk), len(chunk))
  33. if written < 0 {
  34. return n, os.Errno(get_last_error())
  35. }
  36. n += written
  37. }
  38. return n, os.ERROR_NONE
  39. }
  40. CLOCK_MONOTONIC_RAW :: 4 // NOTE(tetra): "RAW" means: Not adjusted by NTP.
  41. @(no_instrumentation)
  42. _tick_now :: proc "contextless" () -> (ns: i64) {
  43. t: timespec
  44. _unix_clock_gettime(CLOCK_MONOTONIC_RAW, &t)
  45. return t.tv_sec*1e9 + t.tv_nsec
  46. }