vq / vlib / builtin / closure / closure_nix.c.v
108 lines · 96 sloc · 2.25 KB · 1a2d0e5b70d6dd1baaa60290f2446e9ece4324bf
Raw
1module closure
2
3$if !freestanding && !vinix {
4 #include <sys/mman.h>
5 #insert "@VEXEROOT/vlib/builtin/closure/closure_once_nix.h"
6
7 fn C.v_closure_init_once(ClosureInitFn)
8}
9
10struct ClosureMutex {
11 closure_mtx [128]u8
12}
13
14@[inline]
15fn closure_mtx_ptr_platform() voidptr {
16 return unsafe { voidptr(&g_closure.closure_mtx[0]) }
17}
18
19@[inline]
20fn closure_alloc_platform() &u8 {
21 mut p := &u8(unsafe { nil })
22 $if freestanding {
23 // Freestanding environments (no OS) use simple malloc
24 p = unsafe { malloc(g_closure.v_page_size * 2) }
25 if isnil(p) {
26 return unsafe { nil }
27 }
28 } $else {
29 // Main OS environments use mmap to get aligned pages
30 p = unsafe {
31 C.mmap(0, g_closure.v_page_size * 2, C.PROT_READ | C.PROT_WRITE,
32 C.MAP_ANONYMOUS | C.MAP_PRIVATE, -1, 0)
33 }
34 if p == &u8(C.MAP_FAILED) {
35 return unsafe { nil }
36 }
37 }
38 return p
39}
40
41@[inline]
42fn closure_memory_protect_platform(ptr voidptr, size isize, attr MemoryProtectAtrr) {
43 $if freestanding {
44 // No memory protection in freestanding mode
45 } $else {
46 match attr {
47 .read_exec {
48 unsafe { C.mprotect(ptr, size, C.PROT_READ | C.PROT_EXEC) }
49 }
50 .read_write {
51 unsafe { C.mprotect(ptr, size, C.PROT_READ | C.PROT_WRITE) }
52 }
53 }
54 }
55}
56
57@[inline]
58fn get_page_size_platform() int {
59 // Determine system page size
60 mut page_size := 0x4000
61 $if !freestanding {
62 // Query actual page size in OS environments
63 page_size = unsafe { int(C.sysconf(C._SC_PAGESIZE)) }
64 }
65 // Calculate required allocation size
66 page_size = page_size * (((assumed_page_size - 1) / page_size) + 1)
67 return page_size
68}
69
70@[inline]
71fn closure_mtx_lock_init_platform() {
72 $if !freestanding || vinix {
73 C.pthread_mutex_init(closure_mtx_ptr_platform(), 0)
74 }
75}
76
77@[inline]
78fn closure_mtx_lock_platform() {
79 $if !freestanding || vinix {
80 C.pthread_mutex_lock(closure_mtx_ptr_platform())
81 }
82}
83
84@[inline]
85fn closure_mtx_unlock_platform() {
86 $if !freestanding || vinix {
87 C.pthread_mutex_unlock(closure_mtx_ptr_platform())
88 }
89}
90
91@[inline]
92fn closure_current_thread_id_platform() u64 {
93 $if !freestanding {
94 return u64(C.pthread_self())
95 }
96 return u64(0)
97}
98
99@[inline]
100fn closure_init_once_platform() {
101 $if freestanding || vinix {
102 if isnil(g_closure.closure_ptr) {
103 closure_init_body()
104 }
105 } $else {
106 C.v_closure_init_once(closure_init_body)
107 }
108}
109