nlib
Platform.h
Go to the documentation of this file.
1 
2 #pragma once
3 #ifndef INCLUDE_NN_NLIB_PLATFORM_H_
4 #define INCLUDE_NN_NLIB_PLATFORM_H_
5 
6 #ifdef __ILP64__
7 # error Sorry, ILP64 not supported
8 #endif
9 
10 // Note that the C preprocessor # operator must be able to use.
11 #define NLIB_VERSION_YEAR 2016
12 #define NLIB_VERSION_YEAR_SHORT 16
13 #define NLIB_VERSION_DATE 0920
14 #define NLIB_VERSION 20160920
15 
16 #ifdef __cplusplus
17 # ifndef __STDC_LIMIT_MACROS
18 # ifdef _MSC_VER
19 # pragma message(__FILE__ ": __STDC_LIMIT_MACROS not defined, compile may fail")
20 # elif !defined(NN_PLATFORM_CTR) && !defined(CAFE)
21 # warning __STDC_LIMIT_MACROS not defined, compile may fail
22 # endif
23 # define __STDC_LIMIT_MACROS
24 # endif
25 # ifndef __STDC_CONSTANT_MACROS
26 # ifdef _MSC_VER
27 # pragma message(__FILE__ ": __STDC_CONSTANT_MACROS not defined, compile may fail")
28 # elif !defined(NN_PLATFORM_CTR) && !defined(CAFE)
29 # warning __STDC_CONSTANT_MACROS not defined, compile may fail
30 # endif
31 # define __STDC_CONSTANT_MACROS
32 # endif
33 # ifndef __STDC_FORMAT_MACROS
34 # ifdef _MSC_VER
35 # pragma message(__FILE__ ": __STDC_FORMAT_MACROS not defined, compile may fail")
36 # elif !defined(NN_PLATFORM_CTR) && !defined(CAFE)
37 # warning __STDC_FORMAT_MACROS not defined, compile may fail
38 # endif
39 # define __STDC_FORMAT_MACROS
40 # endif
41 #endif
42 #ifndef __STDC_WANT_LIB_EXT1__
43 # define __STDC_WANT_LIB_EXT1__ 1
44 #endif
45 
46 #ifndef NLIB_UNUSED
47 # define NLIB_UNUSED(x) (void)(x)
48 #endif
49 
50 #ifndef __has_builtin
51 # define __has_builtin(x) 0
52 #endif
53 
54 #ifndef __has_feature
55 # define __has_feature(x) 0
56 #endif
57 
58 #ifndef __has_cpp_attribute
59 # define __has_cpp_attribute(x) 0
60 #endif
61 
62 #ifndef __has_attribute
63 # define __has_attribute(x) 0
64 #endif
65 
66 #ifndef __has_declspec_attribute
67 # define __has_declspec_attribute(x) 0
68 #endif
69 
70 #ifndef __has_include
71 # define __has_include(x) 0
72 #endif
73 
74 #if __has_feature(thread_sanitizer)
75 # define NLIB_NO_TSAN __attribute__((no_sanitize("thread")))
76 #else
77 # define NLIB_NO_TSAN
78 #endif
79 
80 #if __has_feature(address_sanitizer)
81 # define NLIB_NO_ASAN __attribute__((no_sanitize("address")))
82 #else
83 # define NLIB_NO_ASAN
84 #endif
85 
86 #if __has_feature(memory_sanitizer)
87 # define NLIB_NO_MSAN __attribute__((no_sanitize("memory")))
88 #else
89 # define NLIB_NO_MSAN
90 #endif
91 
92 //
93 // thread safety analysis
94 // http://clang.llvm.org/docs/ThreadSafetyAnalysis.html
95 //
96 #if !defined(NLIB_THREAD_AA_) && defined(__clang__) && \
97  (!defined(SWIG)) && __has_attribute(capability)
98 #define NLIB_THREAD_AA_(x) __attribute__((x))
99 #else
100 #ifdef NLIB_THREAD_AA_
101 #undef NLIB_THREAD_AA_
102 #endif
103 #define NLIB_THREAD_AA_(x)
104 #endif
105 
106 #define NLIB_CAPABILITY(x) NLIB_THREAD_AA_(capability(x))
107 #define NLIB_SCOPED_CAPABILITY NLIB_THREAD_AA_(scoped_lockable)
108 #define NLIB_GUARDED_BY(x) NLIB_THREAD_AA_(guarded_by(x))
109 #define NLIB_PT_GUARDED_BY(x) NLIB_THREAD_AA_(pt_guarded_by(x))
110 #define NLIB_ACQUIRED_BEFORE(...) NLIB_THREAD_AA_(acquired_before(__VA_ARGS__))
111 #define NLIB_ACQUIRED_AFTER(...) NLIB_THREAD_AA_(acquired_after(__VA_ARGS__))
112 #define NLIB_REQUIRES(...) NLIB_THREAD_AA_(requires_capability(__VA_ARGS__))
113 #define NLIB_REQUIRES_SHARED(...) NLIB_THREAD_AA_(requires_shared_capability(__VA_ARGS__))
114 #define NLIB_ACQUIRE(...) NLIB_THREAD_AA_(acquire_capability(__VA_ARGS__))
115 #define NLIB_ACQUIRE_SHARED(...) NLIB_THREAD_AA_(acquire_shared_capability(__VA_ARGS__))
116 #define NLIB_RELEASE(...) NLIB_THREAD_AA_(release_capability(__VA_ARGS__))
117 #define NLIB_RELEASE_SHARED(...) NLIB_THREAD_AA_(release_shared_capability(__VA_ARGS__))
118 #define NLIB_TRY_ACQUIRE(...) NLIB_THREAD_AA_(try_acquire_capability(__VA_ARGS__))
119 #define NLIB_TRY_ACQUIRE_SHARED(...) NLIB_THREAD_AA_(try_acquire_shared_capability(__VA_ARGS__))
120 #define NLIB_EXCLUDES(...) NLIB_THREAD_AA_(locks_excluded(__VA_ARGS__))
121 #define NLIB_ASSERT_CAPABILITY(x) NLIB_THREAD_AA_(assert_capability(x))
122 #define NLIB_ASSERT_SHARED_CAPABILITY(x) NLIB_THREAD_AA_(assert_shared_capability(x))
123 #define NLIB_RETURN_CAPABILITY(x) NLIB_THREAD_AA_(lock_returned(x))
124 #define NLIB_NO_THREAD_SAFETY_ANALYSIS NLIB_THREAD_AA_(no_thread_safety_analysis)
125 
126 #include <stddef.h> // for size_t
127 #include <stdio.h> // for SEEK_CUR, SEEK_END, SEEK_SET
128 #include <stdarg.h> // for va_list
129 #include <string.h> // for memcpy, memmove, memset
130 #include <time.h> // for struct timespec
131 
132 #if defined(NLIB_RENAME_CAPI) && !defined(_MSC_VER)
133 #ifndef NLIB_CFUNC_PREFIX
134 # define NLIB_CFUNC_PREFIX mypfx
135 #endif
136 #ifndef NLIB_CAPI
137 # define NLIB_CAPI__(p, q) p ## q
138 # define NLIB_CAPI_(p, q) NLIB_CAPI__(p, q)
139 # define NLIB_CAPI(x) NLIB_CAPI_(NLIB_CFUNC_PREFIX, x)
140 #endif
141 
142 #define nlib_error_string NLIB_CAPI(nlib_error_string)
143 #define nlib_get_native_last_error NLIB_CAPI(nlib_get_native_last_error)
144 #define nlib_getversion NLIB_CAPI(nlib_getversion)
145 #define nlib_compiler_version NLIB_CAPI(nlib_compiler_version)
146 #define nlib_crc32 NLIB_CAPI(nlib_crc32)
147 #define nlib_crc32c NLIB_CAPI(nlib_crc32c)
148 #define nlib_epochtime NLIB_CAPI(nlib_epochtime)
149 #define nlib_ticktime NLIB_CAPI(nlib_ticktime)
150 #define nlib_sleep NLIB_CAPI(nlib_sleep)
151 #define nlib_gen_random NLIB_CAPI(nlib_gen_random)
152 #define nlib_mempagesize NLIB_CAPI(nlib_mempagesize)
153 #define nlib_virtual_alloc NLIB_CAPI(nlib_virtual_alloc)
154 #define nlib_virtual_free NLIB_CAPI(nlib_virtual_free)
155 #define nlib_physical_alloc NLIB_CAPI(nlib_physical_alloc)
156 #define nlib_physical_free NLIB_CAPI(nlib_physical_free)
157 #define nlib_mlock NLIB_CAPI(nlib_mlock)
158 #define nlib_munlock NLIB_CAPI(nlib_munlock)
159 #define nlib_tls_alloc NLIB_CAPI(nlib_tls_alloc)
160 #define nlib_tls_free NLIB_CAPI(nlib_tls_free)
161 #define nlib_tls_setvalue NLIB_CAPI(nlib_tls_setvalue)
162 #define nlib_tls_getvalue NLIB_CAPI(nlib_tls_getvalue)
163 #define nlib_mutex_init NLIB_CAPI(nlib_mutex_init)
164 #define nlib_mutex_recursive_init NLIB_CAPI(nlib_mutex_recursive_init)
165 #define nlib_mutex_recursive_timed_init NLIB_CAPI(nlib_mutex_recursive_timed_init)
166 #define nlib_mutex_lock NLIB_CAPI(nlib_mutex_lock)
167 #define nlib_mutex_trylock NLIB_CAPI(nlib_mutex_trylock)
168 #define nlib_mutex_trylock_for NLIB_CAPI(nlib_mutex_trylock_for)
169 #define nlib_mutex_unlock NLIB_CAPI(nlib_mutex_unlock)
170 #define nlib_mutex_destroy NLIB_CAPI(nlib_mutex_destroy)
171 #define nlib_semaphore_init NLIB_CAPI(nlib_semaphore_init)
172 #define nlib_semaphore_wait NLIB_CAPI(nlib_semaphore_wait)
173 #define nlib_semaphore_trywait NLIB_CAPI(nlib_semaphore_trywait)
174 #define nlib_semaphore_trywait_for NLIB_CAPI(nlib_semaphore_trywait_for)
175 #define nlib_semaphore_post NLIB_CAPI(nlib_semaphore_post)
176 #define nlib_semaphore_post_ex NLIB_CAPI(nlib_semaphore_post_ex)
177 #define nlib_semaphore_destroy NLIB_CAPI(nlib_semaphore_destroy)
178 #define nlib_cond_init NLIB_CAPI(nlib_cond_init)
179 #define nlib_cond_signal NLIB_CAPI(nlib_cond_signal)
180 #define nlib_cond_broadcast NLIB_CAPI(nlib_cond_broadcast)
181 #define nlib_cond_wait NLIB_CAPI(nlib_cond_wait)
182 #define nlib_cond_wait_for NLIB_CAPI(nlib_cond_wait_for)
183 #define nlib_cond_wait_until NLIB_CAPI(nlib_cond_wait_until)
184 #define nlib_cond_destroy NLIB_CAPI(nlib_cond_destroy)
185 #define nlib_rwlock_init NLIB_CAPI(nlib_rwlock_init)
186 #define nlib_rwlock_destroy NLIB_CAPI(nlib_rwlock_destroy)
187 #define nlib_rwlock_rdlock NLIB_CAPI(nlib_rwlock_rdlock)
188 #define nlib_rwlock_tryrdlock NLIB_CAPI(nlib_rwlock_tryrdlock)
189 #define nlib_rwlock_tryrdlock_for NLIB_CAPI(nlib_rwlock_tryrdlock_for)
190 #define nlib_rwlock_tryrdlock_until NLIB_CAPI(nlib_rwlock_tryrdlock_until)
191 #define nlib_rwlock_rdunlock NLIB_CAPI(nlib_rwlock_rdunlock)
192 #define nlib_rwlock_wrlock NLIB_CAPI(nlib_rwlock_wrlock)
193 #define nlib_rwlock_trywrlock NLIB_CAPI(nlib_rwlock_trywrlock)
194 #define nlib_rwlock_trywrlock_for NLIB_CAPI(nlib_rwlock_trywrlock_for)
195 #define nlib_rwlock_trywrlock_until NLIB_CAPI(nlib_rwlock_trywrlock_until)
196 #define nlib_rwlock_wrunlock NLIB_CAPI(nlib_rwlock_wrunlock)
197 #define nlib_condrwlock_init NLIB_CAPI(nlib_condrwlock_init)
198 #define nlib_condrwlock_destroy NLIB_CAPI(nlib_condrwlock_destroy)
199 #define nlib_condrwlock_signal NLIB_CAPI(nlib_condrwlock_signal)
200 #define nlib_condrwlock_broadcast NLIB_CAPI(nlib_condrwlock_broadcast)
201 #define nlib_condrwlock_wait NLIB_CAPI(nlib_condrwlock_wait)
202 #define nlib_condrwlock_wait_for NLIB_CAPI(nlib_condrwlock_wait_for)
203 #define nlib_condrwlock_wait_until NLIB_CAPI(nlib_condrwlock_wait_until)
204 #define nlib_barrier_init NLIB_CAPI(nlib_barrier_init)
205 #define nlib_barrier_destroy NLIB_CAPI(nlib_barrier_destroy)
206 #define nlib_barrier_wait NLIB_CAPI(nlib_barrier_wait)
207 #define nlib_once NLIB_CAPI(nlib_once)
208 #define nlib_tryonce NLIB_CAPI(nlib_tryonce)
209 #define nlib_mq_open NLIB_CAPI(nlib_mq_open)
210 #define nlib_mq_getattr NLIB_CAPI(nlib_mq_getattr)
211 #define nlib_mq_close NLIB_CAPI(nlib_mq_close)
212 #define nlib_mq_readonly NLIB_CAPI(nlib_mq_readonly)
213 #define nlib_mq_send NLIB_CAPI(nlib_mq_send)
214 #define nlib_mq_send_until NLIB_CAPI(nlib_mq_send_until)
215 #define nlib_mq_receive NLIB_CAPI(nlib_mq_receive)
216 #define nlib_mq_receive_until NLIB_CAPI(nlib_mq_receive_until)
217 #define nlib_mq_drop NLIB_CAPI(nlib_mq_drop)
218 #define nlib_yield NLIB_CAPI(nlib_yield)
219 #define nlib_thread_create NLIB_CAPI(nlib_thread_create)
220 #define nlib_thread_join NLIB_CAPI(nlib_thread_join)
221 #define nlib_thread_detach NLIB_CAPI(nlib_thread_detach)
222 #define nlib_thread_self NLIB_CAPI(nlib_thread_self)
223 #define nlib_thread_getconcurrency NLIB_CAPI(nlib_thread_getconcurrency)
224 #define nlib_thread_getid NLIB_CAPI(nlib_thread_getid)
225 #define nlib_thread_equal NLIB_CAPI(nlib_thread_equal)
226 #define nlib_thread_getcpu NLIB_CAPI(nlib_thread_getcpu)
227 #define nlib_thread_setaffinity NLIB_CAPI(nlib_thread_setaffinity)
228 #define nlib_thread_setname NLIB_CAPI(nlib_thread_setname)
229 #define nlib_thread_getname NLIB_CAPI(nlib_thread_getname)
230 #define nlib_thread_attr_init NLIB_CAPI(nlib_thread_attr_init)
231 #define nlib_thread_attr_setint NLIB_CAPI(nlib_thread_attr_setint)
232 #define nlib_thread_attr_getint NLIB_CAPI(nlib_thread_attr_getint)
233 #define nlib_thread_attr_setptr NLIB_CAPI(nlib_thread_attr_setptr)
234 #define nlib_thread_attr_getptr NLIB_CAPI(nlib_thread_attr_getptr)
235 #define nlib_thread_attr_setstack NLIB_CAPI(nlib_thread_attr_setstack)
236 #define nlib_thread_attr_getstack NLIB_CAPI(nlib_thread_attr_getstack)
237 #define nlib_thread_attr_destroy NLIB_CAPI(nlib_thread_attr_destroy)
238 #define nlib_thread_getpriority NLIB_CAPI(nlib_thread_getpriority)
239 #define nlib_thread_setpriority NLIB_CAPI(nlib_thread_setpriority)
240 #define nlib_thread_priority_min NLIB_CAPI(nlib_thread_priority_min)
241 #define nlib_thread_priority_max NLIB_CAPI(nlib_thread_priority_max)
242 #define nlib_thread_priority_default NLIB_CAPI(nlib_thread_priority_default)
243 #define nlib_thread_exit NLIB_CAPI(nlib_thread_exit)
244 #define nlib_thread_exit_cpp NLIB_CAPI(nlib_thread_exit_cpp)
245 #define nlib_thread_cleanup_push_ NLIB_CAPI(nlib_thread_cleanup_push_)
246 #define nlib_thread_cleanup_pop_ NLIB_CAPI(nlib_thread_cleanup_pop_)
247 #define nlib_write_stdout NLIB_CAPI(nlib_write_stdout)
248 #define nlib_write_stderr NLIB_CAPI(nlib_write_stderr)
249 #define nlib_debug_break NLIB_CAPI(nlib_debug_break)
250 #define nlib_debug_backtrace NLIB_CAPI(nlib_debug_backtrace)
251 #define nlib_debug_backtrace_gettext NLIB_CAPI(nlib_debug_backtrace_gettext)
252 #define nlib_getenv NLIB_CAPI(nlib_getenv)
253 #define nlib_log_print NLIB_CAPI(nlib_log_print)
254 #define nlib_log_vprint NLIB_CAPI(nlib_log_vprint)
255 #define nlib_log_attr_setint NLIB_CAPI(nlib_log_attr_setint)
256 #define nlib_fd_open NLIB_CAPI(nlib_fd_open)
257 #define nlib_fd_close NLIB_CAPI(nlib_fd_close)
258 #define nlib_fd_read NLIB_CAPI(nlib_fd_read)
259 #define nlib_fd_write NLIB_CAPI(nlib_fd_write)
260 #define nlib_fd_seek NLIB_CAPI(nlib_fd_seek)
261 #define nlib_fd_pread NLIB_CAPI(nlib_fd_pread)
262 #define nlib_fd_pwrite NLIB_CAPI(nlib_fd_pwrite)
263 #define nlib_fd_truncate NLIB_CAPI(nlib_fd_truncate)
264 #define nlib_fd_getsize NLIB_CAPI(nlib_fd_getsize)
265 #define nlib_fd_flush NLIB_CAPI(nlib_fd_flush)
266 #define nlib_fd_sync NLIB_CAPI(nlib_fd_sync)
267 #define nlib_fd_native_handle NLIB_CAPI(nlib_fd_native_handle)
268 #define nlib_fd_readv NLIB_CAPI(nlib_fd_readv)
269 #define nlib_fd_writev NLIB_CAPI(nlib_fd_writev)
270 #define nlib_fd_preadv NLIB_CAPI(nlib_fd_preadv)
271 #define nlib_fd_pwritev NLIB_CAPI(nlib_fd_pwritev)
272 #define nlib_unlink NLIB_CAPI(nlib_unlink)
273 #define nlib_remove NLIB_CAPI(nlib_remove)
274 #define nlib_mkdir NLIB_CAPI(nlib_mkdir)
275 #define nlib_rmdir NLIB_CAPI(nlib_rmdir)
276 #define nlib_rename NLIB_CAPI(nlib_rename)
277 #define nlib_dir_open NLIB_CAPI(nlib_dir_open)
278 #define nlib_dir_close NLIB_CAPI(nlib_dir_close)
279 #define nlib_dir_read NLIB_CAPI(nlib_dir_read)
280 #define nlib_is_dir NLIB_CAPI(nlib_is_dir)
281 #define nlib_exist_path NLIB_CAPI(nlib_exist_path)
282 #define nlib_disk_freespace NLIB_CAPI(nlib_disk_freespace)
283 #define nlib_basename NLIB_CAPI(nlib_basename)
284 #define nlib_dirname NLIB_CAPI(nlib_dirname)
285 #define nlib_spinlock_lock_ NLIB_CAPI(nlib_spinlock_lock_)
286 #define nlib_spinlock_unlock_ NLIB_CAPI(nlib_spinlock_unlock_)
287 #define nlib_vsnprintf NLIB_CAPI(nlib_vsnprintf)
288 #define nlib_snprintf NLIB_CAPI(nlib_snprintf)
289 #define nlib_vdprintf NLIB_CAPI(nlib_vdprintf)
290 #define nlib_dprintf NLIB_CAPI(nlib_dprintf)
291 #define nlib_printf NLIB_CAPI(nlib_printf)
292 #define nlib_vsnwprintf NLIB_CAPI(nlib_vsnwprintf)
293 #define nlib_snwprintf NLIB_CAPI(nlib_snwprintf)
294 #define nlib_vdwprintf NLIB_CAPI(nlib_vdwprintf)
295 #define nlib_dwprintf NLIB_CAPI(nlib_dwprintf)
296 #define nlib_wprintf NLIB_CAPI(nlib_wprintf)
297 #define nlib_vsnprintf_fallback NLIB_CAPI(nlib_vsnprintf_fallback)
298 #define nlib_snprintf_fallback NLIB_CAPI(nlib_snprintf_fallback)
299 #define nlib_vsnwprintf_fallback NLIB_CAPI(nlib_vsnwprintf_fallback)
300 #define nlib_snwprintf_fallback NLIB_CAPI(nlib_snwprintf_fallback)
301 #define nlib_memcmp NLIB_CAPI(nlib_memcmp)
302 #define nlib_memchr NLIB_CAPI(nlib_memchr)
303 #define nlib_memrchr NLIB_CAPI(nlib_memrchr)
304 #define nlib_memchr_not NLIB_CAPI(nlib_memchr_not)
305 #define nlib_memchr_range_not NLIB_CAPI(nlib_memchr_range_not)
306 #define nlib_memchr_lt NLIB_CAPI(nlib_memchr_lt)
307 #define nlib_memchr_gt NLIB_CAPI(nlib_memchr_gt)
308 #define nlib_memchr_mb NLIB_CAPI(nlib_memchr_mb)
309 #define nlib_memspn NLIB_CAPI(nlib_memspn)
310 #define nlib_memcspn NLIB_CAPI(nlib_memcspn)
311 #define nlib_memccpy NLIB_CAPI(nlib_memccpy)
312 #define nlib_skipws NLIB_CAPI(nlib_skipws)
313 #define nlib_strlen NLIB_CAPI(nlib_strlen)
314 #define nlib_strnlen NLIB_CAPI(nlib_strnlen)
315 #define nlib_strcpy NLIB_CAPI(nlib_strcpy)
316 #define nlib_strncpy NLIB_CAPI(nlib_strncpy)
317 #define nlib_strchr NLIB_CAPI(nlib_strchr)
318 #define nlib_strrchr NLIB_CAPI(nlib_strrchr)
319 #define nlib_strchr_mb NLIB_CAPI(nlib_strchr_mb)
320 #define nlib_wcslen NLIB_CAPI(nlib_wcslen)
321 #define nlib_wcsnlen NLIB_CAPI(nlib_wcsnlen)
322 #define nlib_wcscpy NLIB_CAPI(nlib_wcscpy)
323 #define nlib_wcsncpy NLIB_CAPI(nlib_wcsncpy)
324 #define nlib_strcat NLIB_CAPI(nlib_strcat)
325 #define nlib_strncat NLIB_CAPI(nlib_strncat)
326 #define nlib_wcscat NLIB_CAPI(nlib_wcscat)
327 #define nlib_wcsncat NLIB_CAPI(nlib_wcsncat)
328 #define nlib_strto_int8 NLIB_CAPI(nlib_strto_int8)
329 #define nlib_strto_int16 NLIB_CAPI(nlib_strto_int16)
330 #define nlib_strto_int32 NLIB_CAPI(nlib_strto_int32)
331 #define nlib_strto_int64 NLIB_CAPI(nlib_strto_int64)
332 #define nlib_strto_uint8 NLIB_CAPI(nlib_strto_uint8)
333 #define nlib_strto_uint16 NLIB_CAPI(nlib_strto_uint16)
334 #define nlib_strto_uint32 NLIB_CAPI(nlib_strto_uint32)
335 #define nlib_strto_uint64 NLIB_CAPI(nlib_strto_uint64)
336 #define nlib_strto_double NLIB_CAPI(nlib_strto_double)
337 #define nlib_strto_float NLIB_CAPI(nlib_strto_float)
338 #define nlib_strto_int32_fallback NLIB_CAPI(nlib_strto_int32_fallback)
339 #define nlib_strto_int64_fallback NLIB_CAPI(nlib_strto_int64_fallback)
340 #define nlib_strto_uint32_fallback NLIB_CAPI(nlib_strto_uint32_fallback)
341 #define nlib_strto_uint64_fallback NLIB_CAPI(nlib_strto_uint64_fallback)
342 #define nlib_strto_double_fallback NLIB_CAPI(nlib_strto_double_fallback)
343 #define nlib_strto_float_fallback NLIB_CAPI(nlib_strto_float_fallback)
344 #define nlib_wide_to_utf8 NLIB_CAPI(nlib_wide_to_utf8)
345 #define nlib_utf8_to_wide NLIB_CAPI(nlib_utf8_to_wide)
346 #define nlib_strcplen NLIB_CAPI(nlib_strcplen)
347 #define nlib_memcplen NLIB_CAPI(nlib_memcplen)
348 #define nlib_wcscplen NLIB_CAPI(nlib_wcscplen)
349 #define nlib_swapendian_16 NLIB_CAPI(nlib_swapendian_16)
350 #define nlib_swapendian_32 NLIB_CAPI(nlib_swapendian_32)
351 #define nlib_swapendian_64 NLIB_CAPI(nlib_swapendian_64)
352 #define nlib_malloc NLIB_CAPI(nlib_malloc)
353 #define nlib_free NLIB_CAPI(nlib_free)
354 #define nlib_calloc NLIB_CAPI(nlib_calloc)
355 #define nlib_realloc NLIB_CAPI(nlib_realloc)
356 #define nlib_malloc_size NLIB_CAPI(nlib_malloc_size)
357 #define nlib_free_size NLIB_CAPI(nlib_free_size)
358 #define nlib_memalign NLIB_CAPI(nlib_memalign)
359 
360 #define nlib_utf16cplen_ex_ NLIB_CAPI(nlib_utf16cplen_ex_)
361 #define nlib_utf16cpy_ NLIB_CAPI(nlib_utf16cpy_)
362 #define nlib_utf16len_ NLIB_CAPI(nlib_utf16len_)
363 #define nlib_utf16ncpy_ NLIB_CAPI(nlib_utf16ncpy_)
364 #define nlib_utf16nlen_ NLIB_CAPI(nlib_utf16nlen_)
365 #define nlib_utf16_to_utf32char NLIB_CAPI(nlib_utf16_to_utf32char)
366 #define nlib_utf16_to_utf8 NLIB_CAPI(nlib_utf16_to_utf8)
367 #define nlib_utf32char_to_utf16 NLIB_CAPI(nlib_utf32char_to_utf16)
368 #define nlib_utf32char_to_utf8 NLIB_CAPI(nlib_utf32char_to_utf8)
369 #define nlib_utf32cplen NLIB_CAPI(nlib_utf32cplen)
370 #define nlib_utf32cpy_ NLIB_CAPI(nlib_utf32cpy_)
371 #define nlib_utf32len_ NLIB_CAPI(nlib_utf32len_)
372 #define nlib_utf32ncpy_ NLIB_CAPI(nlib_utf32ncpy_)
373 #define nlib_utf32nlen_ NLIB_CAPI(nlib_utf32nlen_)
374 #define nlib_utf32_to_utf8 NLIB_CAPI(nlib_utf32_to_utf8)
375 #define nlib_utf8_to_utf16 NLIB_CAPI(nlib_utf8_to_utf16)
376 #define nlib_utf8_to_utf32 NLIB_CAPI(nlib_utf8_to_utf32)
377 #define nlib_utf8_to_utf32char NLIB_CAPI(nlib_utf8_to_utf32char)
378 #define nlib_memutf8_to_utf16 NLIB_CAPI(nlib_memutf8_to_utf16)
379 #define nlib_memutf8_to_utf32 NLIB_CAPI(nlib_memutf8_to_utf32)
380 #define nlib_memutf16_to_utf8 NLIB_CAPI(nlib_memutf16_to_utf8)
381 #define nlib_memutf32_to_utf8 NLIB_CAPI(nlib_memutf32_to_utf8)
382 #define nlib_memutf8_to_wide NLIB_CAPI(nlib_memutf8_to_wide)
383 #define nlib_memwide_to_utf8 NLIB_CAPI(nlib_memwide_to_utf8)
384 
385 #define nlib_socket NLIB_CAPI(nlib_socket)
386 #define nlib_bind NLIB_CAPI(nlib_bind)
387 #define nlib_listen NLIB_CAPI(nlib_listen)
388 #define nlib_accept NLIB_CAPI(nlib_accept)
389 #define nlib_accept_for NLIB_CAPI(nlib_accept_for)
390 #define nlib_connect NLIB_CAPI(nlib_connect)
391 #define nlib_connect_for NLIB_CAPI(nlib_connect_for)
392 #define nlib_send NLIB_CAPI(nlib_send)
393 #define nlib_sendto NLIB_CAPI(nlib_sendto)
394 #define nlib_sendmsg NLIB_CAPI(nlib_sendmsg)
395 #define nlib_recv NLIB_CAPI(nlib_recv)
396 #define nlib_recvfrom NLIB_CAPI(nlib_recvfrom)
397 #define nlib_recvmsg NLIB_CAPI(nlib_recvmsg)
398 #define nlib_closesocket NLIB_CAPI(nlib_closesocket)
399 #define nlib_shutdownsocket NLIB_CAPI(nlib_shutdownsocket)
400 #define nlib_inet_pton NLIB_CAPI(nlib_inet_pton)
401 #define nlib_inet_ntop NLIB_CAPI(nlib_inet_ntop)
402 #define nlib_getaddrinfo NLIB_CAPI(nlib_getaddrinfo)
403 #define nlib_freeaddrinfo NLIB_CAPI(nlib_freeaddrinfo)
404 #define nlib_getsockopt NLIB_CAPI(nlib_getsockopt)
405 #define nlib_setsockopt NLIB_CAPI(nlib_setsockopt)
406 #define nlib_select NLIB_CAPI(nlib_select)
407 #define nlib_poll NLIB_CAPI(nlib_poll)
408 
409 
410 // not in the public header
411 #define nlib_utf8_nbytes_table NLIB_CAPI(nlib_utf8_nbytes_table)
412 #define nlib_hex_char_table NLIB_CAPI(nlib_hex_char_table)
413 #define nlib_memcmp_generic NLIB_CAPI(nlib_memcmp_generic)
414 #define nlib_memchr_generic NLIB_CAPI(nlib_memchr_generic)
415 #define nlib_memrchr_generic NLIB_CAPI(nlib_memrchr_generic)
416 #define nlib_memchr_not_generic NLIB_CAPI(nlib_memchr_not_generic)
417 #define nlib_memchr_range_not_generic NLIB_CAPI(nlib_memchr_range_not_generic)
418 #define nlib_memchr_lt_generic NLIB_CAPI(nlib_memchr_lt_generic)
419 #define nlib_memchr_gt_generic NLIB_CAPI(nlib_memchr_gt_generic)
420 #define nlib_memchr_mb_generic NLIB_CAPI(nlib_memchr_mb_generic)
421 #define nlib_strlen_generic NLIB_CAPI(nlib_strlen_generic)
422 #define nlib_skipws_generic NLIB_CAPI(nlib_skipws_generic)
423 #define nlib_strnlen_generic NLIB_CAPI(nlib_strnlen_generic)
424 #define nlib_strchr_generic NLIB_CAPI(nlib_strchr_generic)
425 #define nlib_strrchr_generic NLIB_CAPI(nlib_strrchr_generic)
426 #define nlib_swapendian_16_generic NLIB_CAPI(nlib_swapendian_16_generic)
427 #define nlib_swapendian_32_generic NLIB_CAPI(nlib_swapendian_32_generic)
428 #define nlib_swapendian_64_generic NLIB_CAPI(nlib_swapendian_64_generic)
429 #define nlib_utf16len_generic NLIB_CAPI(nlib_utf16len_generic)
430 #define nlib_utf16nlen_generic NLIB_CAPI(nlib_utf16nlen_generic)
431 #define nlib_utf32len_generic NLIB_CAPI(nlib_utf32len_generic)
432 #define nlib_utf32nlen_generic NLIB_CAPI(nlib_utf32nlen_generic)
433 #define nlib_utf16cplen_ex_generic NLIB_CAPI(nlib_utf16cplen_ex_generic)
434 #define nlib_fd_impl NLIB_CAPI(nlib_fd_impl)
435 
436 #define utf16chr_mb_simd NLIB_CAPI(utf16chr_mb_simd)
437 #define nlib_strchr_simd NLIB_CAPI(nlib_strchr_simd)
438 #define nlib_strrchr_simd NLIB_CAPI(nlib_strrchr_simd)
439 #define nlib_memchr_simd NLIB_CAPI(nlib_memchr_simd)
440 #define nlib_memrchr_simd NLIB_CAPI(nlib_memrchr_simd)
441 #define nlib_memchr_not_simd NLIB_CAPI(nlib_memchr_not_simd)
442 #define nlib_memchr_range_not_simd NLIB_CAPI(nlib_memchr_range_not_simd)
443 #define nlib_memchr_lt_simd NLIB_CAPI(nlib_memchr_lt_simd)
444 #define nlib_memchr_gt_simd NLIB_CAPI(nlib_memchr_gt_simd)
445 #define nlib_memchr_mb_simd NLIB_CAPI(nlib_memchr_mb_simd)
446 #define nlib_skipws_simd NLIB_CAPI(nlib_skipws_simd)
447 #define nlib_strlen_simd NLIB_CAPI(nlib_strlen_simd)
448 #define nlib_strnlen_simd NLIB_CAPI(nlib_strnlen_simd)
449 #define nlib_utf16len_simd NLIB_CAPI(nlib_utf16len_simd)
450 #define nlib_utf16nlen_simd NLIB_CAPI(nlib_utf16nlen_simd)
451 #define nlib_utf16cplen_ex_simd NLIB_CAPI(nlib_utf16cplen_ex_simd)
452 #define nlib_memcmp_simd NLIB_CAPI(nlib_memcmp_simd)
453 #define nlib_swapendian_16_simd NLIB_CAPI(nlib_swapendian_16_simd)
454 #define nlib_swapendian_32_simd NLIB_CAPI(nlib_swapendian_32_simd)
455 #define nlib_swapendian_64_simd NLIB_CAPI(nlib_swapendian_64_simd)
456 
457 #ifdef __NX__
458 #define nlib_mount_host_nx NLIB_CAPI(nlib_mount_host_nx)
459 #endif
460 
461 #endif
462 
463 #define NLIB_STRINGIFY_(s) #s
464 #define NLIB_STRINGIFY(s) NLIB_STRINGIFY_(s)
465 
466 #if defined(_MSC_VER)
467 # include "nn/nlib/Platform_win32.h"
468 #elif defined(__linux__) || \
469  defined(__FreeBSD__) || \
470  defined(__CYGWIN__) || \
471  (defined(__APPLE__) && defined(__MACH__))
472 # ifndef NLIB_UNIX
473 # define NLIB_UNIX
474 # endif
475 # include "nn/nlib/Platform_unix.h"
476 #elif defined(NN_PLATFORM_CTR)
477 # include "nn/nlib/Platform_ctr.h"
478 #elif defined(CAFE)
479 # include "nn/nlib/Platform_cafe.h"
480 #elif defined(__NX__)
481 # include "nn/nlib/Platform_nx.h"
482 #endif
483 
484 #if defined(_MSC_VER) && defined(n_EXPORTS)
485 #undef NLIB_VIS_PUBLIC
486 #define NLIB_VIS_PUBLIC NLIB_WINEXPORT
487 #endif
488 
489 #ifndef __analysis_assume
490 # define __analysis_assume(expr)
491 #endif
492 
493 #ifndef _Printf_format_string_
494 # define _Printf_format_string_
495 #endif
496 
497 #if defined(__ARM_NEON__) || defined(__aarch64__)
498 # ifndef NLIB_NEON
499 # define NLIB_NEON
500 # endif
501 #endif
502 
503 #ifdef __SSE4_1__
504 # ifndef NLIB_SSE41
505 # define NLIB_SSE41
506 # endif
507 #endif
508 
509 #ifdef __SSE4_2__
510 # ifndef NLIB_SSE41
511 # define NLIB_SSE41
512 # endif
513 # ifndef NLIB_SSE42
514 # define NLIB_SSE42
515 # endif
516 #endif
517 
518 #if defined(NLIB_SSE41) || defined(NLIB_NEON)
519 # define NLIB_SIMD
520 # ifdef NLIB_NEON
521 # include <arm_neon.h> // NOLINT
522 # endif
523 # ifdef NLIB_SSE41
524 # include <smmintrin.h> // NOLINT
525 # endif
526 # ifdef NLIB_SSE42
527 # include <nmmintrin.h> // NOLINT
528 # endif
529 #endif
530 
531 #if defined(__ARM_ACLE)
532 #include <arm_acle.h>
533 #endif
534 
535 // https://www.jpcert.or.jp/sc-rules/c-int01-c.html
536 // https://www.securecoding.cert.org/confluence/display/seccode/INT01-C.+Use+rsize_t+or+size_t+for+all+integer+values+representing+the+size+of+an+object
537 #ifndef RSIZE_MAX
538 # ifndef NLIB_64BIT
539 # define RSIZE_MAX 0x7FFFFFFFL
540 # else
541 # define RSIZE_MAX 0x7FFFFFFFFFFFFFFFLL
542 # endif
543 #endif
544 
545 #ifndef NLIB_WARN
546 # define NLIB_WARN(exp) ("WARNING: " exp)
547 // #pragma message NLIB_WARN("your message")
548 #endif
549 
550 // NOTE:
551 // You can use those macros on the environment which printf does not support '%z'
552 // for size_t.
553 // "%"PRIuS, sizet_val
554 // See: https://google-styleguide.googlecode.com/svn/trunk/cppguide.html#64-bit_Portability
555 // In Japanese: http://www.textdrop.net/google-styleguide-ja/cppguide.xml
556 #ifndef __PRIS_PREFIX
557 # define __PRIS_PREFIX "z"
558 #endif
559 
560 #ifndef PRIdS
561 # define PRIdS __PRIS_PREFIX "d"
562 #endif
563 
564 #ifndef PRIxS
565 # define PRIxS __PRIS_PREFIX "x"
566 #endif
567 
568 #ifndef PRIuS
569 # define PRIuS __PRIS_PREFIX "u"
570 #endif
571 
572 #ifndef PRIXS
573 # define PRIXS __PRIS_PREFIX "X"
574 #endif
575 
576 #ifndef PRIoS
577 # define PRIoS __PRIS_PREFIX "o"
578 #endif
579 
580 #ifndef NLIB_ASSUME
581 # define NLIB_ASSUME(cond) switch (0) case 0: default: if (cond) ; else __builtin_unreachable() /* NOLINT */
582 #endif
583 
584 #ifdef NLIB_NONNULL_ENABLED
585 # define NLIB_EINVAL_IFNULL(p)
586 #else
587 # define NLIB_EINVAL_IFNULL(p) if (!p) return EINVAL
588 #endif
589 
590 #ifndef NLIB_C_INLINE
591 # define NLIB_C_INLINE __inline
592 #endif
593 
594 //
595 // Error Type
596 //
597 typedef int errno_t; // TR 24731-1
598 
599 //
600 // stdint
601 //
602 #ifdef NLIB_HAS_STDHEADER_STDINT
603 # include <stdint.h> // NOLINT
604 #endif
605 
606 #ifdef NLIB_HAS_STDHEADER_INTTYPES
607 # include <inttypes.h> // NOLINT
608 #endif
609 
610 #if defined(__LP64__) && __LP64__ == 1
611 // if long, unsinged long are 64 bits long
612 #define NLIB_LP64
613 typedef int64_t nlib_long_compatible_t;
614 typedef uint64_t nlib_ulong_compatible_t;
615 #else
616 typedef int32_t nlib_long_compatible_t;
617 typedef uint32_t nlib_ulong_compatible_t;
618 #endif
619 
620 #ifndef NLIB_VIS_PUBLIC_ALT
621 #define NLIB_VIS_PUBLIC_ALT NLIB_VIS_PUBLIC
622 #endif
623 
624 #ifndef NLIB_EXPIMP_TEMPLATE
625 # define NLIB_EXPIMP_TEMPLATE(x) NLIB_STATIC_ASSERT(sizeof(char) == 1)
626 #endif
627 
628 #ifdef __cplusplus
629 extern "C" {
630 #endif
631 
633 
634 //
635 // Native error
636 //
638 
639 //
640 // Version
641 //
642 
643 // returns NLIB_VERSION
646 
647 // crc32 = 0 at the beginning
648 NLIB_VIS_PUBLIC uint32_t nlib_crc32(uint32_t crc32, const void* p, size_t n);
649 // crc32 = 0 at the beginning
650 NLIB_VIS_PUBLIC uint32_t nlib_crc32c(uint32_t crc32c, const void* p, size_t n);
651 
652 //
653 // Atomic
654 //
655 #if defined(__INTELLISENSE__)
656 #define NLIB_ATOMIC_RELAXED (0)
657 #define NLIB_ATOMIC_ACQUIRE (1)
658 #define NLIB_ATOMIC_RELEASE (2)
659 #define NLIB_ATOMIC_ACQ_REL (3)
660 #define NLIB_ATOMIC_SEQ_CST (7)
661 
662 int32_t nlib_atomic_load32(const int32_t* ptr, int memorder);
663 void nlib_atomic_store32(int32_t* ptr, int32_t val, int memorder);
664 // *target = value, and returns the old value of *target
665 int32_t nlib_atomic_exchange32(int32_t* ptr,
666  int32_t val, int memorder);
667 // *ptr = desired and return non-zero if successful
668 int nlib_atomic_compare_exchange32(int32_t* ptr,
669  int32_t* expected,
670  int32_t desired,
671  int weak,
672  int success_memorder,
673  int failure_memorder);
674 // *ptr += val; return *ptr;
675 int32_t nlib_atomic_add_fetch32(int32_t* ptr, int32_t val, int memorder);
676 // *ptr -= val; return *ptr;
677 int32_t nlib_atomic_sub_fetch32(int32_t* ptr, int32_t val, int memorder);
678 // *ptr &= val; return *ptr;
679 int32_t nlib_atomic_and_fetch32(int32_t* ptr, int32_t val, int memorder);
680 // *ptr ^= val; return *ptr;
681 int32_t nlib_atomic_xor_fetch32(int32_t* ptr, int32_t val, int memorder);
682 // *ptr |= val; return *ptr;
683 int32_t nlib_atomic_or_fetch32(int32_t* ptr, int32_t val, int memorder);
684 // tmp = *ptr; *ptr += val; return tmp;
685 int32_t nlib_atomic_fetch_add32(int32_t* ptr, int32_t val, int memorder);
686 // tmp = *ptr; *ptr -= val; return tmp;
687 int32_t nlib_atomic_fetch_sub32(int32_t* ptr, int32_t val, int memorder);
688 // tmp = *ptr; *ptr &= val; return tmp;
689 int32_t nlib_atomic_fetch_and32(int32_t* ptr, int32_t val, int memorder);
690 // tmp = *ptr; *ptr ^= val; return tmp;
691 int32_t nlib_atomic_fetch_xor32(int32_t* ptr, int32_t val, int memorder);
692 // tmp = *ptr; *ptr |= val; return tmp;
693 int32_t nlib_atomic_fetch_or32(int32_t* ptr, int32_t val, int memorder);
694 
695 int64_t nlib_atomic_load64(const int64_t* ptr, int memorder);
696 void nlib_atomic_store64(int64_t* ptr, int64_t val, int memorder);
697 // *target = value, and returns the old value of *target
698 int64_t nlib_atomic_exchange64(int64_t* ptr, int64_t val, int memorder);
699 // *ptr = desired and return non-zero if successful
700 int nlib_atomic_compare_exchange64(int64_t* ptr, int64_t* expected,
701  int64_t desired, int weak,
702  int success_memorder, int failure_memorder);
703 // *ptr += val; return *ptr;
704 int64_t nlib_atomic_add_fetch64(int64_t* ptr, int64_t val, int memorder);
705 // *ptr -= val; return *ptr;
706 int64_t nlib_atomic_sub_fetch64(int64_t* ptr, int64_t val, int memorder);
707 // *ptr &= val; return *ptr;
708 int64_t nlib_atomic_and_fetch64(int64_t* ptr, int64_t val, int memorder);
709 // *ptr ^= val; return *ptr;
710 int64_t nlib_atomic_xor_fetch64(int64_t* ptr, int64_t val, int memorder);
711 // *ptr |= val; return *ptr;
712 int64_t nlib_atomic_or_fetch64(int64_t* ptr, int64_t val, int memorder);
713 // tmp = *ptr; *ptr += val; return tmp;
714 int64_t nlib_atomic_fetch_add64(int64_t* ptr, int64_t val, int memorder);
715 // tmp = *ptr; *ptr -= val; return tmp;
716 int64_t nlib_atomic_fetch_sub64(int64_t* ptr, int64_t val, int memorder);
717 // tmp = *ptr; *ptr &= val; return tmp;
718 int64_t nlib_atomic_fetch_and64(int64_t* ptr, int64_t val, int memorder);
719 // tmp = *ptr; *ptr ^= val; return tmp;
720 int64_t nlib_atomic_fetch_xor64(int64_t* ptr, int64_t val, int memorder);
721 // tmp = *ptr; *ptr |= val; return tmp;
722 int64_t nlib_atomic_fetch_or64(int64_t* ptr, int64_t val, int memorder);
723 
724 void* nlib_atomic_loadptr(void* const* ptr, int memorder);
725 void nlib_atomic_storeptr(void** ptr, void* val, int memorder);
726 // *ptr = desired and return non-zero if successful
727 int nlib_atomic_compare_exchangeptr(void** ptr, void** expected, void* desired,
728  int weak, int success_memorder, int failure_memorder);
729 
730 void nlib_atomic_thread_fence(int memorder);
731 #endif
732 
733 //
734 // Time, Duration
735 //
736 #ifndef NLIB_TIMESPEC_HAS_NATIVE
737 struct timespec {
738  time_t tv_sec;
739  long tv_nsec; // NOLINT
740 };
741 #endif
742 
743 // 100ns => 1, 1970/01/01 == 0
744 typedef int64_t nlib_time;
745 // 100ns => 1, 1ms => 10000
746 typedef int64_t nlib_duration;
747 
748 // 100ns => 1, 1970/01/01 == 0
750 // 100ns => 1, boot time == 0, msec = *t / 10000
752 // 100ns => 1, sleep 1 msec = nlib_sleep(10000)
753 NLIB_VIS_PUBLIC errno_t nlib_sleep(nlib_duration t);
754 
755 #define NLIB_TO_TIMESPEC(tm, t) \
756  (tm)->tv_sec = (time_t)((t) / (1000 * 10000)); \
757  (tm)->tv_nsec = ((long)((t) % (1000 * 10000)) * 100) // NOLINT
758 
759 #define NLIB_FROM_TIMESPEC(tm, t) \
760  t = (int64_t)((tm)->tv_sec) * (1000 * 10000) + ((tm)->tv_nsec / 100)
761 
762 static NLIB_C_INLINE errno_t nlib_epochtime_timespec(struct timespec* tm) {
763  nlib_time t;
764  errno_t e = nlib_epochtime(&t);
765  if (NLIB_UNLIKELY(e != 0)) return e;
766  NLIB_TO_TIMESPEC(tm, t);
767  return 0;
768 }
769 
770 static NLIB_C_INLINE errno_t nlib_ticktime_timespec(struct timespec* tm) {
771  nlib_duration d;
772  errno_t e = nlib_ticktime(&d);
773  if (NLIB_UNLIKELY(e != 0)) return e;
774  NLIB_TO_TIMESPEC(tm, d);
775  return 0;
776 }
777 
778 static NLIB_C_INLINE errno_t nlib_sleep_timespec(const struct timespec* tm) {
779  nlib_duration d;
780  NLIB_FROM_TIMESPEC(tm, d);
781  return nlib_sleep(d);
782 }
783 
784 //
785 // Random
786 //
787 
788 // Store 'size' bytes of random values on 'buf'
790 
791 //
792 // Virtual Memory, Physical Memory
793 //
795 NLIB_VIS_PUBLIC errno_t nlib_virtual_alloc(void** ptr, size_t size) NLIB_NONNULL;
796 NLIB_VIS_PUBLIC errno_t nlib_virtual_free(void* ptr, size_t size) NLIB_NONNULL;
797 NLIB_VIS_PUBLIC errno_t nlib_physical_alloc(void* ptr, size_t size, int prot) NLIB_NONNULL;
799 NLIB_VIS_PUBLIC errno_t nlib_mlock(void* addr, size_t len) NLIB_NONNULL;
800 NLIB_VIS_PUBLIC errno_t nlib_munlock(void* addr, size_t len) NLIB_NONNULL;
801 
802 #define NLIB_PHYSICAL_ALLOC_PROT_NONE 0
803 #define NLIB_PHYSICAL_ALLOC_PROT_READ 1
804 #define NLIB_PHYSICAL_ALLOC_PROT_WRITE 2
805 #define NLIB_PHYSICAL_ALLOC_PROT_EXEC 4
806 
807 //
808 // TLS
809 //
810 typedef void (*nlib_tls_destructor)(void* tls_value);
811 
812 #ifdef NLIB_PTHREAD_nlib_tls_alloc
813 static
814 #else
816 #endif
817 // code snippets:
818 // # map tls_key on thread local storage
819 // nlib_tls tls_key;
820 // e = nlib_tls_alloc(&tls_key, NULL); # no dtor invoked if destr is NULL
821 // if (e != 0) { error ... }
822 // # unmap tls_key
823 // nlib_tls_free(tls_key);
824 // # access from a thread
825 // void* thread_local_value;
826 // nlib_tls_getvalue(tls_key, &thread_local_value);
827 // # use and update thread_local_value
828 // nlib_tls_setvalue(tls_key, thread_local_value);
831 #ifdef NLIB_PTHREAD_nlib_tls_alloc
832 static NLIB_C_INLINE errno_t nlib_tls_alloc(nlib_tls* tls, nlib_tls_destructor destr) {
833  return pthread_key_create(tls, destr);
834 }
835 #endif
836 #ifdef NLIB_PTHREAD_nlib_tls_free
837 static NLIB_C_INLINE errno_t nlib_tls_free(nlib_tls tls) {
838  return pthread_key_delete(tls);
839 }
840 #else
842 #endif
843 #ifdef NLIB_PTHREAD_nlib_tls_setvalue
844 static
845 #else
847 #endif
848 errno_t nlib_tls_setvalue(nlib_tls tls, const void* value);
849 #ifdef NLIB_PTHREAD_nlib_tls_setvalue
850 static NLIB_C_INLINE errno_t nlib_tls_setvalue(nlib_tls tls, const void* value) {
851  return pthread_setspecific(tls, value);
852 }
853 #endif
854 
855 #ifdef NLIB_PTHREAD_nlib_tls_getvalue
856 static
857 #else
859 #endif
860 
862 #ifdef NLIB_PTHREAD_nlib_tls_getvalue
863 static NLIB_C_INLINE errno_t nlib_tls_getvalue(nlib_tls tls, void** value) {
864  *value = pthread_getspecific(tls);
865  return 0;
866 }
867 #endif
868 
869 //
870 // Mutex
871 //
872 
873 #ifdef NLIB_PTHREAD_nlib_mutex_init
874 static
875 #else
877 #endif
878 
879 // you can use NLIB_MUTEX_INITIALIZER static initializer
880 errno_t nlib_mutex_init(nlib_mutex* mutex) NLIB_NONNULL NLIB_EXCLUDES(*mutex);
881 #ifdef NLIB_PTHREAD_nlib_mutex_init
882 static NLIB_C_INLINE errno_t nlib_mutex_init(nlib_mutex* mutex) NLIB_NO_THREAD_SAFETY_ANALYSIS {
883  return pthread_mutex_init(mutex, NULL);
884 }
885 #endif
886 
887 // you can use NLIB_RECURSIVE_MUTEX_INITIALIZER static initializer
889  NLIB_NONNULL NLIB_EXCLUDES(*mutex);
890 // you can use NLIB_RECURSIVE_TIMED_MUTEX_INITIALIZER static initializer
892  NLIB_NONNULL NLIB_EXCLUDES(*mutex);
893 
894 #ifdef NLIB_PTHREAD_nlib_mutex_lock
895 static
896 #else
898 #endif
899 // code snippets:
900 // nlib_mutex m;
901 // if (nlib_mutex_init(&m) != 0) { ... } # always returns 0 on almost all platforms?
902 // nlib_mutex_lock(&m);
903 // ....
904 // nlib_mutex_unlock(&m);
905 // nlib_mutex_destroy(&m);
906 errno_t nlib_mutex_lock(nlib_mutex* mutex) NLIB_NONNULL NLIB_ACQUIRE(*mutex);
907 #ifdef NLIB_PTHREAD_nlib_mutex_lock
908 static NLIB_C_INLINE errno_t nlib_mutex_lock(nlib_mutex* mutex) NLIB_NO_THREAD_SAFETY_ANALYSIS {
909  return pthread_mutex_lock(mutex);
910 }
911 #endif
912 
913 // returns EBUSY if a lock cannot be acquired
914 #ifdef NLIB_PTHREAD_nlib_mutex_trylock
915 static
916 #else
918 #endif
920 errno_t nlib_mutex_trylock(nlib_mutex* mutex) NLIB_NONNULL NLIB_TRY_ACQUIRE(0, *mutex);
921 #ifdef NLIB_PTHREAD_nlib_mutex_trylock
922 static NLIB_C_INLINE errno_t nlib_mutex_trylock(nlib_mutex* mutex) NLIB_TRY_ACQUIRE(0, *mutex) {
923  return pthread_mutex_trylock(mutex);
924 }
925 #endif
926 // returns ETIMEDOUT if timeout
929  nlib_duration delta) NLIB_NONNULL NLIB_TRY_ACQUIRE(0, *mutex);
930 #ifdef NLIB_PTHREAD_nlib_mutex_unlock
931 static
932 #else
934 #endif
935 errno_t nlib_mutex_unlock(nlib_mutex* mutex) NLIB_NONNULL NLIB_RELEASE(*mutex);
936 #ifdef NLIB_PTHREAD_nlib_mutex_unlock
937 static NLIB_C_INLINE errno_t nlib_mutex_unlock(nlib_mutex* mutex) NLIB_NO_THREAD_SAFETY_ANALYSIS {
938  return pthread_mutex_unlock(mutex);
939 }
940 #endif
941 
942 #ifdef NLIB_PTHREAD_nlib_mutex_destroy
943 static
944 #else
946 #endif
947 // don't forget to write this, some platforms require this called.
948 errno_t nlib_mutex_destroy(nlib_mutex* mutex) NLIB_NONNULL NLIB_EXCLUDES(*mutex);
949 #ifdef NLIB_PTHREAD_nlib_mutex_destroy
950 static NLIB_C_INLINE errno_t nlib_mutex_destroy(nlib_mutex* mutex) NLIB_NO_THREAD_SAFETY_ANALYSIS {
951  return pthread_mutex_destroy(mutex);
952 }
953 #endif
954 
955 static NLIB_C_INLINE errno_t nlib_mutex_trylock_for_timespec(nlib_mutex* mutex,
956  const struct timespec* tm)
957  NLIB_TRY_ACQUIRE(0, *mutex) {
958  nlib_duration delta;
959  NLIB_FROM_TIMESPEC(tm, delta);
960  return nlib_mutex_trylock_for(mutex, delta);
961 }
962 
963 //
964 // Semaphore
965 //
966 
969 // returns EAGAIN if semaphore cannot be acquired
971 // returns ETIMEDOUT if timeout
973  nlib_semaphore* sem, nlib_duration duration) NLIB_NONNULL;
975  int* __restrict previous_count) NLIB_NONNULL_1;
976 NLIB_VIS_PUBLIC errno_t nlib_semaphore_post_ex(nlib_semaphore* __restrict sem, int release_count,
977  int* __restrict previous_count) NLIB_NONNULL_1;
979 
981  nlib_semaphore* sem, const struct timespec* tm) {
982  nlib_duration duration;
983  NLIB_FROM_TIMESPEC(tm, duration);
984  return nlib_semaphore_trywait_for(sem, duration);
985 }
986 
987 //
988 // Condition Variable
989 //
990 
991 #ifdef NLIB_PTHREAD_nlib_cond_init
992 static
993 #else
995 #endif
996 
997 // you can use NLIB_COND_INITIALIZER for static initializer
999 #ifdef NLIB_PTHREAD_nlib_cond_init
1000 static NLIB_C_INLINE errno_t nlib_cond_init(nlib_cond* cond) {
1001  return pthread_cond_init(cond, NULL);
1002 }
1003 #endif
1004 
1005 #ifdef NLIB_PTHREAD_nlib_cond_signal
1006 static
1007 #else
1009 #endif
1011 #ifdef NLIB_PTHREAD_nlib_cond_signal
1012 static NLIB_C_INLINE errno_t nlib_cond_signal(nlib_cond* cond) {
1013  return pthread_cond_signal(cond);
1014 }
1015 #endif
1016 
1017 #ifdef NLIB_PTHREAD_nlib_cond_broadcast
1018 static
1019 #else
1021 #endif
1023 #ifdef NLIB_PTHREAD_nlib_cond_broadcast
1024 static NLIB_C_INLINE errno_t nlib_cond_broadcast(nlib_cond* cond) {
1025  return pthread_cond_broadcast(cond);
1026 }
1027 #endif
1028 
1029 #ifdef NLIB_PTHREAD_nlib_cond_wait
1030 static
1031 #else
1033 #endif
1034 // code snippets:
1035 // Initialization:
1036 // bool flag = false;
1037 // nlib_mutex m;
1038 // nlib_cond cond;
1039 // nlib_mutex_init(&m);
1040 // nlib_cond_init(&cond);
1041 // Thread1:
1042 // nlib_mutex_lock(&m);
1043 // while (!flag)
1044 // e = nlib_cond_wait(&cond, &m); # m to be unlocked in nlib_cond_wait
1045 // # note that nlib_cond_wait may return without signal notified
1046 // if (e != 0) { error .... }
1047 // # do job and reset flag
1048 // flag = false;
1049 // nlib_mutex_unlock(&m);
1050 // Thread2:
1051 // nlib_mutex_lock(&m);
1052 // flag = true;
1053 // nlib_cond_broadcast(&cond);
1054 // nlib_mutex_unlock(&m);
1055 errno_t nlib_cond_wait(nlib_cond* __restrict cond, nlib_mutex* __restrict mutex)
1056  NLIB_NONNULL NLIB_REQUIRES(*mutex);
1057 #ifdef NLIB_PTHREAD_nlib_cond_wait
1058 static NLIB_C_INLINE
1059 errno_t nlib_cond_wait(nlib_cond* __restrict cond, nlib_mutex* __restrict mutex) {
1060  return pthread_cond_wait(cond, mutex);
1061 }
1062 #endif
1063 
1064 // returns ETIMEDOUT if timeout, and see baloon for nlib_cond_wait()
1066 errno_t nlib_cond_wait_for(nlib_cond* __restrict cond,
1067  nlib_mutex* __restrict mutex,
1068  nlib_duration duration) NLIB_NONNULL NLIB_REQUIRES(*mutex);
1069 // returns ETIMEDOUT if timeout, and see baloon for nlib_cond_wait()
1071 errno_t nlib_cond_wait_until(nlib_cond* __restrict cond,
1072  nlib_mutex* __restrict mutex,
1073  nlib_time abstime) NLIB_NONNULL NLIB_REQUIRES(*mutex);
1074 
1075 #ifdef NLIB_PTHREAD_nlib_cond_destroy
1076 static
1077 #else
1079 #endif
1081 #ifdef NLIB_PTHREAD_nlib_cond_destroy
1082 static NLIB_C_INLINE errno_t nlib_cond_destroy(nlib_cond* cond) {
1083  return pthread_cond_destroy(cond);
1084 }
1085 #endif
1086 
1087 static NLIB_C_INLINE
1088 errno_t nlib_cond_wait_for_timespec(nlib_cond* cond, nlib_mutex* mutex, const struct timespec* tm)
1089  NLIB_REQUIRES(*mutex) {
1090  nlib_duration d;
1091  NLIB_FROM_TIMESPEC(tm, d);
1092  return nlib_cond_wait_for(cond, mutex, d);
1093 }
1094 
1095 static NLIB_C_INLINE
1097  const struct timespec* tm) NLIB_REQUIRES(*mutex) {
1098  nlib_duration d;
1099  NLIB_FROM_TIMESPEC(tm, d);
1100  return nlib_cond_wait_until(cond, mutex, d);
1101 }
1102 
1103 //
1104 // Read/Write lock
1105 //
1106 #ifndef NLIB_RWLOCK_HAS_NATIVE
1107 struct nlib_rwlock_ {
1108  int32_t _0[3];
1109  nlib_mutex _1[2];
1110  nlib_cond _2;
1111 };
1112 NLIB_CAPABILITY("mutex")
1113 typedef struct nlib_rwlock_ nlib_rwlock;
1114 
1115 #define NLIB_RWLOCK_INITIALIZER { \
1116  { 0, 0, 0 }, \
1117  { NLIB_RECURSIVE_TIMED_MUTEX_INITIALIZER, NLIB_RECURSIVE_TIMED_MUTEX_INITIALIZER }, \
1118  NLIB_COND_INITIALIZER }
1119 #endif
1120 
1121 #ifdef NLIB_PTHREAD_nlib_rwlock_init
1122 static
1123 #else
1125 #endif
1126 
1127 errno_t nlib_rwlock_init(nlib_rwlock* rwlock) NLIB_NONNULL NLIB_EXCLUDES(*rwlock);
1128 #ifdef NLIB_PTHREAD_nlib_rwlock_init
1129 static NLIB_C_INLINE errno_t nlib_rwlock_init(nlib_rwlock* rwlock) {
1130  return pthread_rwlock_init(rwlock, NULL);
1131 }
1132 #endif
1133 
1134 #ifdef NLIB_PTHREAD_nlib_rwlock_destroy
1135 static
1136 #else
1138 #endif
1139 errno_t nlib_rwlock_destroy(nlib_rwlock* rwlock) NLIB_NONNULL NLIB_EXCLUDES(*rwlock);
1140 #ifdef NLIB_PTHREAD_nlib_rwlock_destroy
1141 static NLIB_C_INLINE errno_t nlib_rwlock_destroy(nlib_rwlock* rwlock) {
1142  return pthread_rwlock_destroy(rwlock);
1143 }
1144 #endif
1145 
1146 #ifdef NLIB_PTHREAD_nlib_rwlock_rdlock
1147 static
1148 #else
1150 #endif
1151 errno_t nlib_rwlock_rdlock(nlib_rwlock* rwlock) NLIB_NONNULL NLIB_ACQUIRE_SHARED(*rwlock);
1152 #ifdef NLIB_PTHREAD_nlib_rwlock_rdlock
1153 static NLIB_C_INLINE errno_t nlib_rwlock_rdlock(nlib_rwlock* rwlock)
1154  NLIB_NO_THREAD_SAFETY_ANALYSIS {
1155  return pthread_rwlock_rdlock(rwlock);
1156 }
1157 #endif
1158 
1159 #ifdef NLIB_PTHREAD_nlib_rwlock_tryrdlock
1160 static
1161 #else
1163 #endif
1164 errno_t nlib_rwlock_tryrdlock(nlib_rwlock* rwlock)
1165  NLIB_NONNULL NLIB_TRY_ACQUIRE_SHARED(0, *rwlock);
1166 #ifdef NLIB_PTHREAD_nlib_rwlock_tryrdlock
1167 static NLIB_C_INLINE errno_t nlib_rwlock_tryrdlock(nlib_rwlock* rwlock)
1168  NLIB_NO_THREAD_SAFETY_ANALYSIS {
1169  return pthread_rwlock_tryrdlock(rwlock);
1170 }
1171 #endif
1172 
1174 errno_t nlib_rwlock_tryrdlock_for(nlib_rwlock* rwlock, nlib_duration duration)
1175  NLIB_NONNULL NLIB_TRY_ACQUIRE_SHARED(0, *rwlock);
1177 errno_t nlib_rwlock_tryrdlock_until(nlib_rwlock* rwlock, nlib_time abstime)
1178  NLIB_NONNULL NLIB_TRY_ACQUIRE_SHARED(0, *rwlock);
1179 
1180 #ifdef NLIB_PTHREAD_nlib_rwlock_rdunlock
1181 static
1182 #else
1184 #endif
1185 errno_t nlib_rwlock_rdunlock(nlib_rwlock* rwlock)
1186  NLIB_NONNULL NLIB_RELEASE_SHARED(*rwlock);
1187 #ifdef NLIB_PTHREAD_nlib_rwlock_rdunlock
1188 static NLIB_C_INLINE errno_t nlib_rwlock_rdunlock(nlib_rwlock* rwlock)
1189  NLIB_NO_THREAD_SAFETY_ANALYSIS {
1190  return pthread_rwlock_unlock(rwlock);
1191 }
1192 #endif
1193 
1194 #ifdef NLIB_PTHREAD_nlib_rwlock_wrlock
1195 static
1196 #else
1198 #endif
1199 errno_t nlib_rwlock_wrlock(nlib_rwlock* rwlock) NLIB_NONNULL NLIB_ACQUIRE(*rwlock);
1200 #ifdef NLIB_PTHREAD_nlib_rwlock_wrlock
1201 static NLIB_C_INLINE errno_t nlib_rwlock_wrlock(nlib_rwlock* rwlock)
1202  NLIB_NO_THREAD_SAFETY_ANALYSIS {
1203  return pthread_rwlock_wrlock(rwlock);
1204 }
1205 #endif
1206 
1207 #ifdef NLIB_PTHREAD_nlib_rwlock_trywrlock
1208 static
1209 #else
1211 #endif
1212 errno_t nlib_rwlock_trywrlock(nlib_rwlock* rwlock) NLIB_NONNULL NLIB_TRY_ACQUIRE(0, *rwlock);
1213 #ifdef NLIB_PTHREAD_nlib_rwlock_trywrlock
1214 static NLIB_C_INLINE errno_t nlib_rwlock_trywrlock(nlib_rwlock* rwlock)
1215  NLIB_NO_THREAD_SAFETY_ANALYSIS {
1216  return pthread_rwlock_trywrlock(rwlock);
1217 }
1218 #endif
1219 
1221 errno_t nlib_rwlock_trywrlock_for(nlib_rwlock* rwlock, nlib_duration duration)
1222  NLIB_NONNULL NLIB_TRY_ACQUIRE(0, *rwlock);
1224 errno_t nlib_rwlock_trywrlock_until(nlib_rwlock* rwlock, nlib_time abstime)
1225  NLIB_NONNULL NLIB_TRY_ACQUIRE(0, *rwlock);
1226 
1227 #ifdef NLIB_PTHREAD_nlib_rwlock_wrunlock
1228 static
1229 #else
1231 #endif
1232 errno_t nlib_rwlock_wrunlock(nlib_rwlock* rwlock) NLIB_NONNULL NLIB_RELEASE(*rwlock);
1233 #ifdef NLIB_PTHREAD_nlib_rwlock_wrunlock
1234 static NLIB_C_INLINE errno_t nlib_rwlock_wrunlock(nlib_rwlock* rwlock)
1235  NLIB_NO_THREAD_SAFETY_ANALYSIS {
1236  return pthread_rwlock_unlock(rwlock);
1237 }
1238 #endif
1239 
1240 static NLIB_C_INLINE
1241 errno_t nlib_rwlock_tryrdlock_for_timespec(nlib_rwlock* rwlock, const struct timespec* tm)
1242  NLIB_TRY_ACQUIRE_SHARED(0, *rwlock) {
1243  nlib_duration d;
1244  NLIB_FROM_TIMESPEC(tm, d);
1245  return nlib_rwlock_tryrdlock_for(rwlock, d);
1246 }
1247 
1248 static NLIB_C_INLINE
1249 errno_t nlib_rwlock_tryrdlock_until_timespec(nlib_rwlock* rwlock, const struct timespec* tm)
1250  NLIB_TRY_ACQUIRE_SHARED(0, *rwlock) {
1251  nlib_duration d;
1252  NLIB_FROM_TIMESPEC(tm, d);
1253  return nlib_rwlock_tryrdlock_until(rwlock, d);
1254 }
1255 
1256 static NLIB_C_INLINE
1257 errno_t nlib_rwlock_trywrlock_for_timespec(nlib_rwlock* rwlock, const struct timespec* tm)
1258  NLIB_TRY_ACQUIRE(0, *rwlock) {
1259  nlib_duration d;
1260  NLIB_FROM_TIMESPEC(tm, d);
1261  return nlib_rwlock_trywrlock_for(rwlock, d);
1262 }
1263 
1264 static NLIB_C_INLINE
1265 errno_t nlib_rwlock_trywrlock_until_timespec(nlib_rwlock* rwlock, const struct timespec* tm)
1266  NLIB_TRY_ACQUIRE(0, *rwlock) {
1267  nlib_duration d;
1268  NLIB_FROM_TIMESPEC(tm, d);
1269  return nlib_rwlock_trywrlock_until(rwlock, d);
1270 }
1271 
1272 
1273 #if defined(_MSC_VER) && defined(NLIB_RWLOCK_HAS_NATIVE)
1274 typedef struct nlib_condrwlock_ {
1275  CONDITION_VARIABLE cond;
1276 } nlib_condrwlock;
1277 #define NLIB_CONDRWLOCK_INITIALIZER { CONDITION_VARIABLE_INIT }
1278 #else
1279 typedef struct nlib_condrwlock_ {
1280  nlib_cond cond;
1281  nlib_mutex mutex;
1282 } nlib_condrwlock;
1283 #define NLIB_CONDRWLOCK_INITIALIZER { NLIB_COND_INITIALIZER, NLIB_MUTEX_INITIALIZER }
1284 #endif
1285 
1291  nlib_rwlock* __restrict rwlock,
1292  int rdlock) NLIB_NONNULL;
1294  nlib_rwlock* __restrict rwlock,
1295  nlib_duration duration,
1296  int rdlock) NLIB_NONNULL;
1298  nlib_rwlock* __restrict rwlock,
1299  nlib_time abstime,
1300  int rdlock) NLIB_NONNULL;
1301 
1303  nlib_rwlock* rwlock,
1304  const struct timespec* tm,
1305  int rdlock) {
1306  nlib_duration d;
1307  NLIB_FROM_TIMESPEC(tm, d);
1308  return nlib_condrwlock_wait_for(cond, rwlock, d, rdlock);
1309 }
1310 
1312  nlib_rwlock* rwlock,
1313  const struct timespec* tm,
1314  int rdlock) {
1315  nlib_duration d;
1316  NLIB_FROM_TIMESPEC(tm, d);
1317  return nlib_condrwlock_wait_until(cond, rwlock, d, rdlock);
1318 }
1319 
1320 //
1321 // Barrier
1322 //
1323 #ifndef NLIB_BARRIER_HAS_NATIVE
1324 struct nlib_barrier_ {
1325  nlib_mutex _0;
1326  nlib_cond _1;
1327  unsigned int _2[3];
1328 };
1329 typedef struct nlib_barrier_ nlib_barrier;
1330 #endif
1331 
1332 #ifdef NLIB_PTHREAD_nlib_barrier_init
1333 static
1334 #else
1336 #endif
1337 errno_t nlib_barrier_init(nlib_barrier* barrier, unsigned int count) NLIB_NONNULL;
1338 #ifdef NLIB_PTHREAD_nlib_barrier_init
1339 static NLIB_C_INLINE errno_t nlib_barrier_init(nlib_barrier* barrier, unsigned int count) {
1340  return pthread_barrier_init(barrier, NULL, count);
1341 }
1342 #endif
1343 
1344 #ifdef NLIB_PTHREAD_nlib_barrier_destroy
1345 static
1346 #else
1348 #endif
1350 #ifdef NLIB_PTHREAD_nlib_barrier_destroy
1351 static NLIB_C_INLINE errno_t nlib_barrier_destroy(nlib_barrier* barrier) {
1352  return pthread_barrier_destroy(barrier);
1353 }
1354 #endif
1355 
1357 
1358 //
1359 // Once
1360 //
1361 struct nlib_onceflag_ {
1362  int status;
1363 };
1364 typedef struct nlib_onceflag_ nlib_onceflag;
1365 #define NLIB_ONCE_INIT { 0 }
1366 typedef void (*nlib_oncefunc)(void);
1367 
1368 // code snippets
1369 // void OnceFunc() { .... }
1370 // nlib_onceflag flag = NLIB_ONCE_INIT; // should be static initialized
1371 // nlib_once(&flag, OnceFunc); // OnceFunc executes only once
1374 // returns EBUSY immedidately if an other thread is executing 'func'
1377 
1378 //
1379 // Message Queue
1380 //
1381 #ifdef NLIB_DOXYGEN
1382 typedef int32_t nlib_mq;
1383 #else
1384 typedef struct nlib_mq_ {
1385  int32_t raw_handle; // 0 for invalid handle
1386 } nlib_mq;
1387 #endif
1388 typedef void* nlib_mq_msg;
1389 
1390 #define NLIB_MQ_BLOCK 0
1391 #define NLIB_MQ_NONBLOCK 1
1392 #define NLIB_MQ_LOCKFREE 2
1393 
1395 #ifdef NLIB_DOXYGEN
1397  int32_t flag;
1398  int32_t max_msg;
1399  int32_t cur_msg;
1401 };
1402 #else
1403 typedef struct nlib_mq_attr_ {
1404  int32_t flag; // NLIB_MQ_BLOCK / NLIB_MQ_NONBLOCK
1405  int32_t max_msg; // 0 for 128
1406  int32_t cur_msg; // blocking mode only
1407  nlib_mq_msg_destructor destructor;
1408 } nlib_mq_attr;
1409 #endif
1410 
1412 errno_t nlib_mq_open(nlib_mq* mq, const nlib_mq_attr* attr) NLIB_NONNULL;
1417 NLIB_VIS_PUBLIC NLIB_CHECK_RESULT errno_t nlib_mq_send(nlib_mq mq, nlib_mq_msg msg, int prio);
1419 errno_t nlib_mq_send_until(nlib_mq mq, nlib_mq_msg msg, int prio, nlib_time abstime);
1421 errno_t nlib_mq_receive(nlib_mq mq, nlib_mq_msg* msg, int* prio) NLIB_NONNULL_2;
1423 errno_t nlib_mq_receive_until(nlib_mq mq, nlib_mq_msg* msg, int* prio, nlib_time abstime)
1426 errno_t nlib_mq_drop(nlib_mq mq, nlib_mq_msg* msg, int* prio) NLIB_NONNULL_2;
1427 
1428 //
1429 // Thread
1430 //
1432 #define NLIB_THREAD_INVALID (nlib_thread)(0) // NOLINT
1433 
1434 #ifndef NLIB_SPINLOCK_HAS_NATIVE
1435 typedef int32_t nlib_spinlock;
1436 #endif
1437 
1438 #ifndef NLIB_THREAD_ATTR_HAS_NATIVE
1439 struct nlib_thread_attr_ {
1440  nlib_spinlock spin;
1441  int detach_state;
1442  int explicit_sched;
1443  int priority;
1444  uint32_t affinity;
1445  void* stack_addr;
1446  size_t stack_size;
1447 };
1448 typedef struct nlib_thread_attr_ nlib_thread_attr;
1449 #else
1450 struct nlib_thread_attr_ {
1451  pthread_attr_t attr;
1452  uint32_t affinity;
1453 };
1454 typedef struct nlib_thread_attr_ nlib_thread_attr;
1455 #endif
1456 typedef void (*nlib_thread_func)(void* arg);
1457 // -1 for invalid
1458 typedef int nlib_thread_id;
1459 
1460 // code snippets:
1461 // nlib_thread th;
1462 // if ((e = nlib_thread_create(&th, NULL, myfunc, myarg)) != 0) { error ... }
1463 // nlib_thread_join(th); # or nlib_thread_detach(th);
1465 errno_t nlib_thread_create(nlib_thread* __restrict thread, const nlib_thread_attr* __restrict attr,
1466  nlib_thread_func func, void* __restrict arg)
1467  NLIB_NONNULL_1 NLIB_NONNULL_3;
1468 #ifdef NLIB_PTHREAD_nlib_thread_join
1469 static
1470 #else
1472 #endif
1474 #ifdef NLIB_PTHREAD_nlib_thread_join
1475 static NLIB_C_INLINE errno_t nlib_thread_join(nlib_thread thread) {
1476  return pthread_join(thread, NULL);
1477 }
1478 #endif
1479 
1480 #ifdef NLIB_PTHREAD_nlib_thread_detach
1481 static
1482 #else
1484 #endif
1486 #ifdef NLIB_PTHREAD_nlib_thread_detach
1487 static NLIB_C_INLINE errno_t nlib_thread_detach(nlib_thread thread) {
1488  return pthread_detach(thread);
1489 }
1490 #endif
1491 
1492 #ifdef NLIB_PTHREAD_nlib_thread_self
1493 static
1494 #else
1496 #endif
1498 #ifdef NLIB_PTHREAD_nlib_thread_self
1499 static NLIB_C_INLINE errno_t nlib_thread_self(nlib_thread* thread) {
1500  *thread = pthread_self();
1501  return 0;
1502 }
1503 #endif
1504 
1507 
1508 #ifdef NLIB_PTHREAD_nlib_thread_equal
1509 static
1510 #else
1512 #endif
1514 #ifdef NLIB_PTHREAD_nlib_thread_equal
1515 static NLIB_C_INLINE int nlib_thread_equal(nlib_thread th1, nlib_thread th2) {
1516  return pthread_equal(th1, th2);
1517 }
1518 #endif
1519 
1521 NLIB_VIS_PUBLIC errno_t nlib_thread_setaffinity(nlib_thread thread, uint32_t affinity);
1523 
1524 #ifdef NLIB_PTHREAD_nlib_thread_getname
1525 static
1526 #else
1528 #endif
1529 errno_t nlib_thread_getname(nlib_thread thread, char* name, size_t len) NLIB_NONNULL;
1530 #ifdef NLIB_PTHREAD_nlib_thread_getname
1531 static NLIB_C_INLINE errno_t nlib_thread_getname(nlib_thread thread, char* name, size_t len) {
1532  return pthread_getname_np(thread, name, len);
1533 }
1534 #endif
1535 
1536 // NOTE:
1537 // win32 does not have GetThreadAffinityMask()
1538 // errno_t nlib_thread_get_affinify(nlib_thread thread, uint32_t* affinity);
1539 
1544 errno_t nlib_thread_attr_getint(const nlib_thread_attr* __restrict attr, int key,
1545  int* __restrict value) NLIB_NONNULL;
1547 errno_t nlib_thread_attr_setptr(nlib_thread_attr* __restrict attr, int key,
1548  void* __restrict value) NLIB_NONNULL_1;
1550 errno_t nlib_thread_attr_getptr(const nlib_thread_attr* __restrict attr, int key,
1551  void** __restrict value) NLIB_NONNULL;
1553 errno_t nlib_thread_attr_setstack(nlib_thread_attr* __restrict attr, void* __restrict stack_addr,
1554  size_t stack_size) NLIB_NONNULL;
1556 errno_t nlib_thread_attr_getstack(const nlib_thread_attr* __restrict attr,
1557  void** __restrict stack_addr, size_t* __restrict stack_size)
1558  NLIB_NONNULL;
1560 
1561 #define NLIB_THREAD_ATTR_KEY_DETACHSTATE (1)
1562 #define NLIB_THREAD_ATTR_KEY_STACKSIZE (2)
1563 #define NLIB_THREAD_ATTR_KEY_PRIORITY (4)
1564 #define NLIB_THREAD_ATTR_KEY_AFFINITY (5)
1565 #define NLIB_THREAD_ATTR_KEY_EXPLICIT_SCHED (6)
1566 
1572 
1573 #ifndef NN_PLATFORM_CTR
1574 // See also nlib_thread_exit_cpp();
1576 #endif
1577 
1578 #ifdef NLIB_DOXYGEN
1579 void nlib_thread_cleanup_push(void (*fn)(void*), void* arg);
1580 void nlib_thread_cleanup_pop(int exec);
1581 #elif defined(pthread_cleanup_push)
1582 # define nlib_thread_cleanup_push(fn, arg) pthread_cleanup_push(fn, arg)
1583 # define nlib_thread_cleanup_pop(exec) pthread_cleanup_pop(exec)
1584 #elif !defined(NN_PLATFORM_CTR)
1585 struct nlib_thread_cleanup_handler_ {
1586  void (*func)(void*);
1587  void* arg;
1588  struct nlib_thread_cleanup_handler_* next;
1589 };
1590 #define nlib_thread_cleanup_push(fn, arg) switch (0) case 0: default: { \
1591  struct nlib_thread_cleanup_handler_ _thread_cleanup_handler = { fn, arg, NULL }; \
1592  nlib_thread_cleanup_push_(&_thread_cleanup_handler)
1593 #define nlib_thread_cleanup_pop(exec) nlib_thread_cleanup_pop_(exec); }
1594 
1595 NLIB_VIS_PUBLIC void nlib_thread_cleanup_push_(struct nlib_thread_cleanup_handler_* handler);
1596 NLIB_VIS_PUBLIC void nlib_thread_cleanup_pop_(int exec);
1597 #endif
1598 
1599 //
1600 // Console/Debug
1601 //
1602 
1603 // note that buf is not null terminated
1605 errno_t nlib_write_stdout(size_t* __restrict result, const void* __restrict buf, size_t count)
1606  NLIB_NONNULL;
1607 // note that buf is not null terminated
1609 errno_t nlib_write_stderr(size_t* __restrict result, const void* __restrict buf, size_t count)
1610  NLIB_NONNULL;
1613 errno_t nlib_debug_backtrace(size_t* __restrict result, void** __restrict buffer, size_t count)
1614  NLIB_NONNULL;
1616 errno_t nlib_debug_backtrace_gettext(char* __restrict str, size_t strbufsize,
1617  void* const* __restrict buf, size_t count) NLIB_NONNULL;
1619 errno_t nlib_getenv(size_t* __restrict result, char* __restrict buf, size_t bufsize,
1620  const char* __restrict varname) NLIB_NONNULL_1 NLIB_NONNULL_4;
1621 
1622 typedef enum nlib_log_priority {
1623  NLIB_LOG_UNKNOWN = 0,
1624  NLIB_LOG_DEAFULT,
1631  NLIB_LOG_SILENT,
1636 
1637 typedef enum nlib_log_key {
1638  NLIB_LOG_ATTR_UNKNOWN = 0,
1639  NLIB_LOG_ATTR_STDOUT,
1640  NLIB_LOG_ATTR_STDERR,
1641  NLIB_LOG_ATTR_MSVC_TRACE,
1642  NLIB_LOG_ATTR_SYSLOG,
1643  NLIB_LOG_ATTR_NLIB_FD,
1644  NLIB_LOG_ATTR_MAX
1645 } nlib_log_key;
1646 
1647 #ifndef NLIB_ATTRIBUTE_PRINTF
1648 # define NLIB_ATTRIBUTE_PRINTF(x, y) __attribute__((format(printf, x, y)))
1649 #endif
1650 
1651 NLIB_VIS_PUBLIC int nlib_log_print(int prio, _Printf_format_string_ const char* __restrict tag,
1652  const char* __restrict fmt, ...)
1653  NLIB_ATTRIBUTE_PRINTF(3, 4) NLIB_NONNULL;
1654 NLIB_VIS_PUBLIC int nlib_log_vprint(int prio, _Printf_format_string_ const char* __restrict tag,
1655  const char* __restrict fmt, va_list ap) NLIB_NONNULL;
1656 NLIB_VIS_PUBLIC errno_t nlib_log_attr_setint(int prio, int key, int value);
1657 
1658 //
1659 // File Access
1660 //
1661 #ifndef NLIB_FD_O_RDONLY
1662 # ifndef O_RDONLY
1663 # error
1664 # endif
1665 # define NLIB_FD_O_RDONLY O_RDONLY
1666 #endif
1667 
1668 #ifndef NLIB_FD_O_WRONLY
1669 # ifndef O_WRONLY
1670 # error
1671 # endif
1672 # define NLIB_FD_O_WRONLY O_WRONLY
1673 #endif
1674 
1675 #ifndef NLIB_FD_O_RDWR
1676 # ifndef O_RDWR
1677 # error
1678 # endif
1679 # define NLIB_FD_O_RDWR O_RDWR
1680 #endif
1681 
1682 #ifndef NLIB_FD_O_APPEND
1683 # ifndef O_APPEND
1684 # error
1685 # endif
1686 # define NLIB_FD_O_APPEND O_APPEND
1687 #endif
1688 
1689 #ifndef NLIB_FD_O_CREAT
1690 # ifndef O_CREAT
1691 # error
1692 # endif
1693 # define NLIB_FD_O_CREAT O_CREAT
1694 #endif
1695 
1696 #ifndef NLIB_FD_O_TRUNC
1697 # ifndef O_TRUNC
1698 # error
1699 # endif
1700 # define NLIB_FD_O_TRUNC O_TRUNC
1701 #endif
1702 
1703 #ifndef NLIB_FD_O_EXCL
1704 # ifndef O_EXCL
1705 # error
1706 # endif
1707 # define NLIB_FD_O_EXCL O_EXCL
1708 #endif
1709 
1710 #ifndef NLIB_SEEK_SET
1711 # ifndef SEEK_SET
1712 # error
1713 # endif
1714 # define NLIB_SEEK_SET SEEK_SET
1715 #endif
1716 
1717 #ifndef NLIB_SEEK_CUR
1718 # ifndef SEEK_CUR
1719 # error
1720 # endif
1721 # define NLIB_SEEK_CUR SEEK_CUR
1722 #endif
1723 
1724 // NOTE:
1725 // SEEK_END not supported(because of FIO19-C)
1726 
1727 typedef int64_t nlib_offset;
1728 typedef int nlib_fd;
1729 #define NLIB_FD_INVALID (-1)
1730 
1731 #ifdef NLIB_DOXYGEN
1732 errno_t nlib_fd_open(nlib_fd* fd, const char* native_path, unsigned int flags);
1733 errno_t nlib_fd_open(nlib_fd* fd, const char* native_path, unsigned int flags, int mode);
1734 #else
1736 errno_t nlib_fd_open(nlib_fd* fd, const char* native_path, unsigned int flags, ...) NLIB_NONNULL_1;
1737 #endif
1738 NLIB_CHECK_RESULT static NLIB_C_INLINE
1739 errno_t nlib_fd_creat(nlib_fd* fd, const char* native_path, int mode) {
1740  return nlib_fd_open(fd, native_path,
1742 }
1745 errno_t nlib_fd_read(size_t* __restrict result, nlib_fd fd, void* __restrict buf, size_t count)
1748 errno_t nlib_fd_write(size_t* __restrict result, nlib_fd fd, const void* __restrict buf,
1749  size_t count) NLIB_NONNULL_1;
1751 errno_t nlib_fd_seek(nlib_offset* result, nlib_fd fd, nlib_offset offset, int whence)
1754 errno_t nlib_fd_pread(size_t* __restrict result, nlib_fd fd, void* __restrict buf,
1755  size_t count, nlib_offset offset) NLIB_NONNULL_1;
1757 errno_t nlib_fd_pwrite(size_t* __restrict result, nlib_fd fd, const void* __restrict buf,
1758  size_t count, nlib_offset offset) NLIB_NONNULL_1;
1759 NLIB_VIS_PUBLIC NLIB_CHECK_RESULT errno_t nlib_fd_truncate(nlib_fd fd, nlib_offset length);
1760 
1762 errno_t nlib_fd_getsize(nlib_offset* size, nlib_fd fd) NLIB_NONNULL;
1765 NLIB_VIS_PUBLIC errno_t nlib_fd_native_handle(void** native_handle, nlib_fd fd) NLIB_NONNULL;
1766 // errno_t nlib_fd_fcntl_getflag(unsigned int* flags, nlib_fd fd);
1767 // errno_t nlib_fd_fcntl_setflag(nlib_fd fd, unsigned int flags);
1768 
1769 // Scatter/Gather buffer
1770 #if !defined(NLIB_IOVEC_HAS_NATIVE)
1771 struct nlib_fd_iovec_ {
1772  void* iov_base;
1773  size_t iov_len;
1774 };
1775 typedef struct nlib_fd_iovec_ nlib_fd_iovec;
1776 #else
1777 typedef struct iovec nlib_fd_iovec;
1778 #endif
1780 errno_t nlib_fd_readv(size_t* __restrict result, nlib_fd fd, const nlib_fd_iovec* __restrict iov,
1781  int iovcnt) NLIB_NONNULL;
1783 errno_t nlib_fd_writev(size_t* __restrict result, nlib_fd fd, const nlib_fd_iovec* __restrict iov,
1784  int iovcnt) NLIB_NONNULL;
1786 errno_t nlib_fd_preadv(size_t* __restrict result, nlib_fd fd, const nlib_fd_iovec* __restrict iov,
1787  int iovcnt, nlib_offset offset) NLIB_NONNULL;
1789 errno_t nlib_fd_pwritev(size_t* __restrict result, nlib_fd fd, const nlib_fd_iovec* __restrict iov,
1790  int iovcnt, nlib_offset offset) NLIB_NONNULL;
1791 // errno_t nlib_fd_stat(stat* stat, nlib_fd fd);
1792 
1793 NLIB_VIS_PUBLIC NLIB_CHECK_RESULT errno_t nlib_unlink(const char* native_path);
1794 NLIB_VIS_PUBLIC NLIB_CHECK_RESULT errno_t nlib_mkdir(const char* native_path,
1795  unsigned int flags);
1796 NLIB_VIS_PUBLIC NLIB_CHECK_RESULT errno_t nlib_rmdir(const char* native_path);
1797 NLIB_VIS_PUBLIC NLIB_CHECK_RESULT errno_t nlib_remove(const char* native_path);
1799 errno_t nlib_rename(const char* __restrict old_path, const char* __restrict new_path);
1800 
1801 struct nlib_dir_ {
1802  void* ptr;
1803 };
1804 typedef struct nlib_dir_ nlib_dir;
1805 typedef struct nlib_dirent_ {
1806  uint32_t flags; // 0: file, 1: directory
1807  char name[768];
1808 } nlib_dirent;
1810 errno_t nlib_dir_open(nlib_dir* __restrict dir, const char* __restrict native_path) NLIB_NONNULL_1;
1811 NLIB_VIS_PUBLIC errno_t nlib_dir_close(nlib_dir dir);
1813 errno_t nlib_dir_read(nlib_dirent* ent, nlib_dir dir) NLIB_NONNULL;
1814 
1815 // CTR does not have getcwd.....
1816 // errno_t nlib_getcwd(char* buf, size_t bufsize);
1817 // errno_t nlib_chdir(const char* path);
1818 
1820 errno_t nlib_is_dir(int* __restrict result, const char* __restrict native_path) NLIB_NONNULL_1;
1821 // *result != 0 if exists
1823 errno_t nlib_exist_path(int* __restrict result, const char* __restrict native_path) NLIB_NONNULL_1;
1825 errno_t nlib_disk_freespace(const char* __restrict native_path,
1826  uint64_t* __restrict free_bytes_available,
1827  uint64_t* __restrict total_bytes,
1828  uint64_t* __restrict total_free_bytes);
1829 
1830 NLIB_VIS_PUBLIC const char* nlib_basename(const char* path) NLIB_NONNULL;
1831 NLIB_VIS_PUBLIC const char* nlib_dirname(size_t* len, const char* path) NLIB_NONNULL;
1832 
1833 //
1834 // Socket(Win32/Linux/Cygwin only)
1835 //
1836 #if defined(_MSC_VER) || defined(NLIB_UNIX)
1837 #define NLIB_SOCKET_ENABLED
1838 
1839 // sizeof(SOCKET) is 8 on Win64, but it's safe because the upper 32bit of SOCKET is always 0.
1840 // https://stackoverflow.com/questions/1953639/is-it-safe-to-cast-socket-to-int-under-win64
1841 typedef int nlib_sock;
1842 #define NLIB_SOCKET_INVALID (nlib_sock)(-1) // NOLINT
1843 
1844 #if defined(_MSC_VER)
1845 #define NLIB_SOCK_NONBLOCK 0x8000
1846 #elif defined(SOCK_NONBLOCK)
1847 #define NLIB_SOCK_NONBLOCK SOCK_NONBLOCK
1848 #else
1849 #define NLIB_SOCK_NONBLOCK O_NONBLOCK
1850 #endif
1851 
1852 NLIB_VIS_PUBLIC errno_t nlib_socket(nlib_sock* sockfd, int af, int type, int protocol);
1853 
1854 typedef struct sockaddr nlib_sockaddr;
1855 typedef struct sockaddr_in nlib_sockaddr_in;
1856 typedef struct sockaddr_in6 nlib_sockaddr_in6;
1857 #ifdef _MSC_VER
1858 struct nlib_msghdr_ {
1859  void* msg_name;
1860  uint32_t msg_namelen;
1861  nlib_fd_iovec* msg_iov;
1862  size_t msg_iovlen;
1863  void* msg_control;
1864  size_t msg_controllen;
1865  int msg_flags;
1866 };
1867 typedef struct nlib_msghdr_ nlib_msghdr;
1868 #define NLIB_CMSG_FIRSTHDR(msgh) \
1869  ((msgh)->msg_controllen >= sizeof(WSACMSGHDR) ? \
1870  (LPWSACMSGHDR)(msgh)->msg_control : (LPWSACMSGHDR)NULL)
1871 #define NLIB_CMSG_NXTHDR(msg, cmsg) \
1872  ( ((cmsg) == NULL) ? NLIB_CMSG_FIRSTHDR(msg) \
1873  : ( ( ((PUCHAR)(cmsg) + \
1874  WSA_CMSGHDR_ALIGN((cmsg)->cmsg_len) + \
1875  sizeof(WSACMSGHDR) ) > \
1876  (PUCHAR)((msg)->msg_control) + \
1877  (msg)->msg_controllen) \
1878  ? (LPWSACMSGHDR)NULL \
1879  : (LPWSACMSGHDR)((PUCHAR)(cmsg) + \
1880  WSA_CMSGHDR_ALIGN((cmsg)->cmsg_len)) ) )
1881 #define NLIB_CMSG_SPACE(length) WSA_CMSG_SPACE(length)
1882 #define NLIB_CMSG_LEN(length) WSA_CMSG_LEN(length)
1883 #define NLIB_CMSG_DATA(cmsg) WSA_CMSG_DATA(cmsg)
1884 #else
1885 typedef struct msghdr nlib_msghdr;
1886 #define NLIB_CMSG_FIRSTHDR(msgh) CMSG_FIRSTHDR(msgh)
1887 #define NLIB_CMSG_NXTHDR(msgh, cmsg) CMSG_NXTHDR(msgh, cmsg)
1888 // #define NLIB_CMSG_ALIGN(length) CMSG_ALIGN(length)
1889 #define NLIB_CMSG_SPACE(length) CMSG_SPACE(length)
1890 #define NLIB_CMSG_LEN(length) CMSG_LEN(length)
1891 #define NLIB_CMSG_DATA(cmsg) CMSG_DATA(cmsg)
1892 #endif
1893 typedef struct cmsghdr nlib_cmsghdr;
1894 NLIB_VIS_PUBLIC errno_t nlib_bind(nlib_sock sockfd, const nlib_sockaddr* addr, uint32_t namelen);
1895 NLIB_VIS_PUBLIC errno_t nlib_listen(nlib_sock sockfd, int backlog);
1897 errno_t nlib_accept(nlib_sock* __restrict s, nlib_sock sockfd, nlib_sockaddr* __restrict addr,
1898  uint32_t* __restrict addrlen, int flags);
1900 errno_t nlib_accept_for(nlib_sock* __restrict s, nlib_sock sockfd, nlib_sockaddr* __restrict addr,
1901  uint32_t* __restrict addrlen, int flags, nlib_duration timeout);
1903 errno_t nlib_connect(nlib_sock sockfd, const nlib_sockaddr* addr, uint32_t addrlen);
1905 errno_t nlib_connect_for(nlib_sock sockfd, const nlib_sockaddr* addr, uint32_t addrlen,
1906  int flags, nlib_duration timeout);
1907 
1909 errno_t nlib_sendto(size_t* __restrict size, nlib_sock sockfd, const void* __restrict buf,
1910  size_t len, int flags, const nlib_sockaddr* __restrict dest_addr,
1911  uint32_t addrlen);
1913 errno_t nlib_sendmsg(size_t* __restrict size, nlib_sock sockfd, const nlib_msghdr* msg, int flags);
1914 static NLIB_C_INLINE
1915 errno_t nlib_send(size_t* __restrict size, nlib_sock sockfd, const void* __restrict buf,
1916  size_t len, int flags) {
1917  return nlib_sendto(size, sockfd, buf, len, flags, NULL, 0);
1918 }
1919 
1921 errno_t nlib_recvfrom(size_t* __restrict size, nlib_sock sockfd,
1922  void* __restrict buf, size_t len, int flags,
1923  nlib_sockaddr* __restrict dest_addr,
1924  uint32_t* __restrict addrlen);
1926 errno_t nlib_recvmsg(size_t* __restrict size, nlib_sock sockfd, nlib_msghdr* msg, int flags);
1927 static NLIB_C_INLINE
1928 errno_t nlib_recv(size_t* __restrict size, nlib_sock sockfd, void* __restrict buf, size_t len,
1929  int flags) {
1930  return nlib_recvfrom(size, sockfd, buf, len, flags, NULL, NULL);
1931 }
1932 
1933 NLIB_VIS_PUBLIC errno_t nlib_closesocket(nlib_sock sockfd);
1934 
1935 #ifdef _MSC_VER
1936 # define SHUT_RD SD_RECEIVE
1937 # define SHUT_WR SD_SEND
1938 # define SHUT_RDWR SD_BOTH
1939 #endif
1940 
1941 NLIB_VIS_PUBLIC errno_t nlib_shutdownsocket(nlib_sock sockfd, int how);
1942 
1943 #ifndef NLIB_LITTLE_ENDIAN
1944 static NLIB_C_INLINE uint32_t nlib_htonl(uint32_t hostlong) { return hostlong; }
1945 static NLIB_C_INLINE uint16_t nlib_htons(uint16_t hostshort) { return hostshort; }
1946 static NLIB_C_INLINE uint32_t nlib_ntohl(uint32_t netlong) { return netlong; }
1947 static NLIB_C_INLINE uint16_t nlib_ntohs(uint16_t netshort) { return netshort; }
1948 #else
1949 static NLIB_C_INLINE uint32_t nlib_htonl(uint32_t hostlong) {
1950 #ifdef _MSC_VER
1951  return _byteswap_ulong(hostlong);
1952 #else
1953  return __builtin_bswap32(hostlong);
1954 #endif
1955 }
1956 static NLIB_C_INLINE uint16_t nlib_htons(uint16_t hostshort) {
1957 #ifdef _MSC_VER
1958  return _byteswap_ushort(hostshort);
1959 #else
1960  return ((hostshort & 0xFF) << 8) | ((hostshort >> 8) & 0xFF);
1961 #endif
1962 }
1963 static NLIB_C_INLINE uint32_t nlib_ntohl(uint32_t netlong) {
1964 #ifdef _MSC_VER
1965  return _byteswap_ulong(netlong);
1966 #else
1967  return __builtin_bswap32(netlong);
1968 #endif
1969 }
1970 static NLIB_C_INLINE uint16_t nlib_ntohs(uint16_t netshort) {
1971 #ifdef _MSC_VER
1972  return _byteswap_ushort(netshort);
1973 #else
1974  return ((netshort & 0xFF) << 8) | ((netshort >> 8) & 0xFF);
1975 #endif
1976 }
1977 #endif
1978 
1979 typedef struct in_addr nlib_in_addr;
1980 typedef struct in6_addr nlib_in6_addr;
1981 NLIB_VIS_PUBLIC errno_t nlib_inet_pton(int af, const char* __restrict src, void* __restrict dst);
1982 NLIB_VIS_PUBLIC errno_t nlib_inet_ntop(int af, const void* __restrict src, char* __restrict dst,
1983  uint32_t dst_size);
1984 
1985 /*
1986 # define EAI_ADDRFAMILY 1
1987 # define EAI_AGAIN 2
1988 # define EAI_BADFLAGS 3
1989 # define EAI_FAIL 4
1990 # define EAI_FAMILY 5
1991 # define EAI_MEMORY 6
1992 # define EAI_NODATA 7
1993 # define EAI_NONAME 8
1994 # define EAI_SERVICE 9
1995 # define EAI_SOCKTYPE 10
1996 # define EAI_SYSTEM 11
1997 # define EAI_BADHINTS 12
1998 # define EAI_PROTOCOL 13
1999 # define EAI_OVERFLOW 14
2000 */
2001 
2002 // for EAI_ADDRFAMILY, EAI_AGAIN, ... etc.
2003 typedef int eai_error_t;
2004 typedef struct addrinfo nlib_addrinfo;
2006 eai_error_t nlib_getaddrinfo(const char* __restrict node, const char* __restrict service,
2007  const nlib_addrinfo* __restrict hints,
2008  nlib_addrinfo** __restrict res);
2010 eai_error_t nlib_getnameinfo(const nlib_sockaddr* __restrict sa, uint32_t salen,
2011  char* __restrict host, uint32_t hostlen,
2012  char* __restrict serv, uint32_t servlen, int flags);
2013 NLIB_VIS_PUBLIC void nlib_freeaddrinfo(nlib_addrinfo* res);
2014 
2016 errno_t nlib_getsockopt(nlib_sock sockfd, int level, int optname, void* __restrict optval,
2017  uint32_t* __restrict optlen);
2019 errno_t nlib_setsockopt(nlib_sock sockfd, int level, int optname, const void* optval,
2020  uint32_t optlen);
2021 
2022 typedef fd_set nlib_fd_set;
2024 errno_t nlib_select(size_t* __restrict n, int nfds, nlib_fd_set* __restrict readfds,
2025  nlib_fd_set* __restrict writefds,
2026  nlib_fd_set* __restrict exceptfds, nlib_duration timeout);
2027 
2028 #define NLIB_FD_CLR FD_CLR
2029 #define NLIB_FD_ISSET FD_ISSET
2030 #ifdef _MSC_VER
2031 #define NLIB_FD_SET(fd, set) FD_SET((SOCKET)fd, set)
2032 #else
2033 #define NLIB_FD_SET FD_SET
2034 #endif
2035 #define NLIB_FD_ZERO FD_ZERO
2036 
2037 #if defined(_MSC_VER)
2038 struct nlib_pollfd_ {
2039  nlib_sock fd;
2040  int16_t events;
2041  int16_t revents;
2042 };
2043 typedef struct nlib_pollfd_ nlib_pollfd;
2044 #else
2045 typedef struct pollfd nlib_pollfd;
2046 #endif
2048 errno_t nlib_poll(size_t* __restrict n, nlib_pollfd* __restrict fds, uint32_t nfds,
2049  nlib_duration timeout);
2050 
2051 #ifdef _MSC_VER
2052 #define NLIB_MSG_DONTWAIT (0x4000)
2053 #else
2054 #define NLIB_MSG_DONTWAIT MSG_DONTWAIT
2055 #endif
2056 
2057 // NLIB_VIS_PUBLIC errno_t nlib_sockatmark(int* is_marked, nlib_sock sockfd);
2059 errno_t nlib_getsockname(nlib_sock sockfd, nlib_sockaddr* __restrict addr,
2060  uint32_t* __restrict addrlen);
2062 errno_t nlib_getpeername(nlib_sock sockfd, nlib_sockaddr* __restrict addr,
2063  uint32_t* __restrict addrlen);
2064 NLIB_VIS_PUBLIC errno_t nlib_setnonblocking(nlib_sock sockfd, int nonblock);
2065 
2066 #endif
2067 
2068 //
2069 // errno workaround
2070 //
2071 
2072 // PLEASE DO NOT DEFINE POSIX.1-2008 errno macros in your code
2073 // http://pubs.opengroup.org/onlinepubs/9699919799/
2074 #ifdef _MSC_VER
2075 # ifdef EDQUOT
2076 # warning Do not define EDQUOT. nlib may not work correctly.
2077 # endif
2078 #endif
2079 
2080 /*
2081 #ifdef NN_PLATFORM_CTR
2082 // socket_User.autogen.h defines POSIX.1-2008 errno macros as enum values.
2083 # ifdef NN_SOCKET_SOCKET_USER_AUTOGEN_H_
2084 # warning DO NOT INCLUDE socket_User.autogen.h in CTR socket library, Compile may fail.
2085 # define NLIB_SKIP_ERRNO_DEFINE
2086 # ifdef __errno_h
2087 # warning DO NOT INCLUDE errno.h when you include socket_User.autogen.h, you may not be able to handle errors of CTR socket library correctly. // NOLINT
2088 # endif
2089 # endif
2090 #endif
2091 */
2092 
2093 #ifndef NLIB_SKIP_ERRNO_DEFINE
2094 #include <errno.h> // NOLINT, for POSIX error values
2095 #define NLIB_E_BASE 2000
2096 
2097 // if boost/cerrno.hpp has definitions on errno values,
2098 // nlib defines the same values which boost/cerrno.hpp defines.
2099 
2100 // [E2BIG]
2101 // Argument list too long.
2102 #ifndef E2BIG
2103 # define E2BIG 9946
2104 #endif
2105 
2106 // [EACCES]
2107 // Permission denied.
2108 #ifndef EACCES
2109 # define EACCES 9973
2110 #endif
2111 
2112 // [EADDRINUSE]
2113 // Address in use.
2114 #ifndef EADDRINUSE
2115 # define EADDRINUSE 9902
2116 #endif
2117 
2118 // [EADDRNOTAVAIL]
2119 // Address not available.
2120 #ifndef EADDRNOTAVAIL
2121 # define EADDRNOTAVAIL 9903
2122 #endif
2123 
2124 // [EAFNOSUPPORT]
2125 // Address family not supported.
2126 #ifndef EAFNOSUPPORT
2127 # define EAFNOSUPPORT 9901
2128 #endif
2129 
2130 // [EAGAIN]
2131 // Resource unavailable, try again (may be the same value as [EWOULDBLOCK]).
2132 #ifndef EAGAIN
2133 # define EAGAIN 9976
2134 #endif
2135 
2136 // [EALREADY]
2137 // Connection already in progress.
2138 #ifndef EALREADY
2139 # define EALREADY 9907
2140 #endif
2141 
2142 // [EBADF]
2143 // Bad file descriptor.
2144 #ifndef EBADF
2145 # define EBADF 9949
2146 #endif
2147 
2148 // [EBADMSG]
2149 // Bad message.
2150 #ifndef EBADMSG
2151 # define EBADMSG 9905
2152 #endif
2153 
2154 // [EBUSY]
2155 // Device or resource busy.
2156 #ifndef EBUSY
2157 # define EBUSY 9952
2158 #endif
2159 
2160 // [ECANCELED]
2161 // Operation canceled.
2162 #ifndef ECANCELED
2163 # define ECANCELED 9927
2164 #endif
2165 
2166 // [ECHILD]
2167 // No child processes.
2168 #ifndef ECHILD
2169 # define ECHILD 9963
2170 #endif
2171 
2172 // [ECONNABORTED]
2173 // Connection aborted.
2174 #ifndef ECONNABORTED
2175 # define ECONNABORTED 9906
2176 #endif
2177 
2178 // [ECONNREFUSED]
2179 // Connection refused.
2180 #ifndef ECONNREFUSED
2181 # define ECONNREFUSED 9908
2182 #endif
2183 
2184 // [ECONNRESET]
2185 // Connection reset.
2186 #ifndef ECONNRESET
2187 # define ECONNRESET 9909
2188 #endif
2189 
2190 // [EDEADLK]
2191 // Resource deadlock would occur.
2192 #ifndef EDEADLK
2193 # define EDEADLK 9975
2194 #endif
2195 
2196 // [EDESTADDRREQ]
2197 // Destination address required.
2198 #ifndef EDESTADDRREQ
2199 # define EDESTADDRREQ 9910
2200 #endif
2201 
2202 // [EDOM]
2203 // Mathematics argument out of domain of function.
2204 #ifndef EDOM
2205 # define EDOM 9947
2206 #endif
2207 
2208 // [EDQUOT]
2209 // Reserved.
2210 #ifndef EDQUOT
2211 # define EDQUOT (NLIB_E_BASE + 19)
2212 #endif
2213 
2214 // [EEXIST]
2215 // File exists.
2216 #ifndef EEXIST
2217 # define EEXIST 9955
2218 #endif
2219 
2220 // [EFAULT]
2221 // Bad address.
2222 #ifndef EFAULT
2223 # define EFAULT 9948
2224 #endif
2225 
2226 // [EFBIG]
2227 // File too large.
2228 #ifndef EFBIG
2229 # define EFBIG 9956
2230 #endif
2231 
2232 // [EHOSTUNREACH]
2233 // Host is unreachable.
2234 #ifndef EHOSTUNREACH
2235 # define EHOSTUNREACH 9911
2236 #endif
2237 
2238 // [EIDRM]
2239 // Identifier removed.
2240 #ifndef EIDRM
2241 # define EIDRM 9912
2242 #endif
2243 
2244 // [EILSEQ]
2245 // Illegal byte sequence.
2246 #ifndef EILSEQ
2247 # define EILSEQ 9945
2248 #endif
2249 
2250 // [EINPROGRESS]
2251 // Operation in progress.
2252 #ifndef EINPROGRESS
2253 # define EINPROGRESS 9928
2254 #endif
2255 
2256 // [EINTR]
2257 // Interrupted function.
2258 #ifndef EINTR
2259 # define EINTR 9959
2260 #endif
2261 
2262 // [EINVAL]
2263 // Invalid argument.
2264 #ifndef EINVAL
2265 # define EINVAL 9943
2266 #endif
2267 
2268 // [EIO]
2269 // I/O error.
2270 #ifndef EIO
2271 # define EIO 9961
2272 #endif
2273 
2274 // [EISCONN]
2275 // Socket is connected.
2276 #ifndef EISCONN
2277 # define EISCONN 9904
2278 #endif
2279 
2280 // [EISDIR]
2281 // Is a directory.
2282 #ifndef EISDIR
2283 # define EISDIR 9962
2284 #endif
2285 
2286 // [ELOOP]
2287 // Too many levels of symbolic links.
2288 #ifndef ELOOP
2289 # define ELOOP 9939
2290 #endif
2291 
2292 // [EMFILE]
2293 // File descriptor value too large.
2294 #ifndef EMFILE
2295 # define EMFILE 9978
2296 #endif
2297 
2298 // [EMLINK]
2299 // Too many links.
2300 #ifndef EMLINK
2301 # define EMLINK 9979
2302 #endif
2303 
2304 // [EMSGSIZE]
2305 // Message too large.
2306 #ifndef EMSGSIZE
2307 # define EMSGSIZE 9913
2308 #endif
2309 
2310 // [EMULTIHOP]
2311 // Reserved.
2312 #ifndef EMULTIHOP
2313 # define EMULTIHOP (NLIB_E_BASE + 36)
2314 #endif
2315 
2316 // [ENAMETOOLONG]
2317 // Filename too long.
2318 #ifndef ENAMETOOLONG
2319 # define ENAMETOOLONG 9957
2320 #endif
2321 
2322 // [ENETDOWN]
2323 // Network is down.
2324 #ifndef ENETDOWN
2325 # define ENETDOWN 9914
2326 #endif
2327 
2328 // [ENETRESET]
2329 // Connection aborted by network.
2330 #ifndef ENETRESET
2331 # define ENETRESET 9915
2332 #endif
2333 
2334 // [ENETUNREACH]
2335 // Network unreachable.
2336 #ifndef ENETUNREACH
2337 # define ENETUNREACH 9916
2338 #endif
2339 
2340 // [ENFILE]
2341 // Too many files open in system.
2342 #ifndef ENFILE
2343 # define ENFILE 9977
2344 #endif
2345 
2346 // [ENOBUFS]
2347 // No buffer space available.
2348 #ifndef ENOBUFS
2349 # define ENOBUFS 9917
2350 #endif
2351 
2352 // [ENODATA]
2353 // [OB XSR] [Option Start] No message is available on the STREAM head read queue. [Option End]
2354 #ifndef ENODATA
2355 # define ENODATA 9919
2356 #endif
2357 
2358 // [ENODEV]
2359 // No such device.
2360 #ifndef ENODEV
2361 # define ENODEV 9967
2362 #endif
2363 
2364 // [ENOENT]
2365 // No such file or directory.
2366 #ifndef ENOENT
2367 # define ENOENT 9968
2368 #endif
2369 
2370 // [ENOEXEC]
2371 // Executable file format error.
2372 #ifndef ENOEXEC
2373 # define ENOEXEC 9954
2374 #endif
2375 
2376 // [ENOLCK]
2377 // No locks available.
2378 #ifndef ENOLCK
2379 # define ENOLCK 9964
2380 #endif
2381 
2382 // [ENOLINK]
2383 // Reserved.
2384 #ifndef ENOLINK
2385 # define ENOLINK 9918
2386 #endif
2387 
2388 // [ENOMEM]
2389 // Not enough space.
2390 #ifndef ENOMEM
2391 # define ENOMEM 9971
2392 #endif
2393 
2394 // [ENOMSG]
2395 // No message of the desired type.
2396 #ifndef ENOMSG
2397 # define ENOMSG 9920
2398 #endif
2399 
2400 // [ENOPROTOOPT]
2401 // Protocol not available.
2402 #ifndef ENOPROTOOPT
2403 # define ENOPROTOOPT 9921
2404 #endif
2405 
2406 // [ENOSPC]
2407 // No space left on device.
2408 #ifndef ENOSPC
2409 # define ENOSPC 9965
2410 #endif
2411 
2412 // [ENOSR]
2413 // [OB XSR] [Option Start] No STREAM resources. [Option End]
2414 #ifndef ENOSR
2415 # define ENOSR 9922
2416 #endif
2417 
2418 // [ENOSTR]
2419 // [OB XSR] [Option Start] Not a STREAM. [Option End]
2420 #ifndef ENOSTR
2421 # define ENOSTR 9924
2422 #endif
2423 
2424 // [ENOSYS]
2425 // Function not supported.
2426 #ifndef ENOSYS
2427 # define ENOSYS 9942
2428 #endif
2429 
2430 // [ENOTCONN]
2431 // The socket is not connected.
2432 #ifndef ENOTCONN
2433 # define ENOTCONN 9925
2434 #endif
2435 
2436 // [ENOTDIR]
2437 // Not a directory or a symbolic link to a directory.
2438 #ifndef ENOTDIR
2439 # define ENOTDIR 9970
2440 #endif
2441 
2442 // [ENOTEMPTY]
2443 // Directory not empty.
2444 #ifndef ENOTEMPTY
2445 # define ENOTEMPTY 9953
2446 #endif
2447 
2448 // [ENOTRECOVERABLE]
2449 // State not recoverable.
2450 #ifndef ENOTRECOVERABLE
2451 # define ENOTRECOVERABLE 9934
2452 #endif
2453 
2454 // [ENOTSOCK]
2455 // Not a socket.
2456 #ifndef ENOTSOCK
2457 # define ENOTSOCK 9923
2458 #endif
2459 
2460 // [ENOTSUP]
2461 // Not supported (may be the same value as [EOPNOTSUPP]).
2462 #ifndef ENOTSUP
2463 # define ENOTSUP 9926
2464 #endif
2465 
2466 // [ENOTTY]
2467 // Inappropriate I/O control operation.
2468 #ifndef ENOTTY
2469 # define ENOTTY 9958
2470 #endif
2471 
2472 // [ENXIO]
2473 // No such device or address.
2474 #ifndef ENXIO
2475 # define ENXIO 9966
2476 #endif
2477 
2478 // [EOPNOTSUPP]
2479 // Operation not supported on socket (may be the same value as [ENOTSUP]).
2480 #ifndef EOPNOTSUPP
2481 # define EOPNOTSUPP 9929
2482 #endif
2483 
2484 // [EOVERFLOW]
2485 // Value too large to be stored in data type.
2486 #ifndef EOVERFLOW
2487 # define EOVERFLOW 9940
2488 #endif
2489 
2490 // [EOWNERDEAD]
2491 // Previous owner died.
2492 #ifndef EOWNERDEAD
2493 # define EOWNERDEAD 9931
2494 #endif
2495 
2496 // [EPERM]
2497 // Operation not permitted.
2498 #ifndef EPERM
2499 # define EPERM 9972
2500 #endif
2501 
2502 // [EPIPE]
2503 // Broken pipe.
2504 #ifndef EPIPE
2505 # define EPIPE 9950
2506 #endif
2507 
2508 // [EPROTO]
2509 // Protocol error.
2510 #ifndef EPROTO
2511 # define EPROTO 9932
2512 #endif
2513 
2514 // [EPROTONOSUPPORT]
2515 // Protocol not supported.
2516 #ifndef EPROTONOSUPPORT
2517 # define EPROTONOSUPPORT 9933
2518 #endif
2519 
2520 // [EPROTOTYPE]
2521 // Protocol wrong type for socket.
2522 #ifndef EPROTOTYPE
2523 # define EPROTOTYPE 9941
2524 #endif
2525 
2526 // [ERANGE]
2527 // Result too large.
2528 #ifndef ERANGE
2529 # define ERANGE 9944
2530 #endif
2531 
2532 // [EROFS]
2533 // Read-only file system.
2534 #ifndef EROFS
2535 # define EROFS 9974
2536 #endif
2537 
2538 // [ESPIPE]
2539 // Invalid seek.
2540 #ifndef ESPIPE
2541 # define ESPIPE 9960
2542 #endif
2543 
2544 // [ESRCH]
2545 // No such process.
2546 #ifndef ESRCH
2547 # define ESRCH 9969
2548 #endif
2549 
2550 // [ESTALE]
2551 // Reserved.
2552 #ifndef ESTALE
2553 # define ESTALE (NLIB_E_BASE + 75)
2554 #endif
2555 
2556 // [ETIME]
2557 // [OB XSR] [Option Start] Stream ioctl() timeout. [Option End]
2558 #ifndef ETIME
2559 # define ETIME 9935
2560 #endif
2561 
2562 // [ETIMEDOUT]
2563 // Connection timed out.
2564 #ifndef ETIMEDOUT
2565 # define ETIMEDOUT 9938
2566 #endif
2567 
2568 // [ETXTBSY]
2569 // Text file busy.
2570 #ifndef ETXTBSY
2571 # define ETXTBSY 9936
2572 #endif
2573 
2574 // [EWOULDBLOCK]
2575 // Operation would block (may be the same value as [EAGAIN]).
2576 #ifndef EWOULDBLOCK
2577 # define EWOULDBLOCK 9930
2578 #endif
2579 
2580 // [EXDEV]
2581 // Cross-device link.
2582 #ifndef EXDEV
2583 # define EXDEV 9951
2584 #endif
2585 #endif // NLIB_SKIP_ERRNO_DEFINE
2586 
2587 //
2588 // nlib_spinlock
2589 //
2590 #ifndef NLIB_SPINLOCK_HAS_NATIVE
2591 #define NLIB_SPINLOCK_INITIALIZER (0)
2592 NLIB_VIS_PUBLIC void nlib_spinlock_lock_(nlib_spinlock* lock) NLIB_NONNULL;
2593 #ifndef NN_PLATFORM_CTR
2594 NLIB_VIS_PUBLIC void nlib_spinlock_unlock_(nlib_spinlock* lock) NLIB_NONNULL;
2595 #endif
2596 
2597 static void nlib_spinlock_init(nlib_spinlock* lock) NLIB_NONNULL;
2598 static void nlib_spinlock_lock(nlib_spinlock* lock) NLIB_NONNULL;
2599 static errno_t nlib_spinlock_trylock(nlib_spinlock* lock) NLIB_NONNULL;
2600 static void nlib_spinlock_unlock(nlib_spinlock* lock) NLIB_NONNULL;
2601 
2602 static NLIB_ALWAYS_INLINE void nlib_spinlock_init(nlib_spinlock* lock) {
2603  *lock = 0;
2604 }
2605 static NLIB_ALWAYS_INLINE void nlib_spinlock_lock(nlib_spinlock* lock) {
2606 #if defined(__arm__)
2607 #if __has_builtin(__builtin_arm_ldrex)
2608  int R5 = __builtin_arm_ldrex(lock);
2609 #else
2610  int R5 = __ldrex(lock);
2611 #endif
2612  if (R5 == 0) {
2613 #if __has_builtin(__builtin_arm_strex)
2614  if (__builtin_arm_strex(1, lock) == 0) {
2615 #else
2616  if (__strex(1, lock) == 0) {
2617 #endif
2618 #if !defined(NN_PLATFORM_CTR)
2619  __dmb(0xf);
2620 #else
2621  nlib_ctr_barrier();
2622 #endif
2623  }
2624  return;
2625  }
2626  nlib_spinlock_lock_(lock);
2627 #else
2628  int32_t expected = 0;
2629  if (!nlib_atomic_compare_exchange32(lock, &expected, 1, 1,
2631  nlib_spinlock_lock_(lock);
2632  }
2633 #endif
2634 }
2635 static NLIB_ALWAYS_INLINE errno_t nlib_spinlock_trylock(nlib_spinlock* lock) {
2636 #if defined(__arm__)
2637 #if __has_builtin(__builtin_arm_ldrex)
2638  int R5 = __builtin_arm_ldrex(lock);
2639 #else
2640  int R5 = __ldrex(lock);
2641 #endif
2642  if (R5 == 0) {
2643 #if __has_builtin(__builtin_arm_strex)
2644  if (__builtin_arm_strex(1, lock) == 0) {
2645 #else
2646  if (__strex(1, lock) == 0) {
2647 #endif
2648 #if !defined(NN_PLATFORM_CTR)
2649  __dmb(0xf);
2650 #else
2651  nlib_ctr_barrier();
2652 #endif
2653  return 0;
2654  }
2655  }
2656  return EBUSY;
2657 #else
2658  int32_t expected = 0;
2659  if (nlib_atomic_compare_exchange32(lock, &expected, 1, 0,
2661  return 0;
2662  else
2663  return EBUSY;
2664 #endif
2665 }
2666 static NLIB_ALWAYS_INLINE void nlib_spinlock_unlock(nlib_spinlock* lock) {
2667 #if defined(NN_PLATFORM_CTR)
2669 #else
2670  int32_t expected = 1;
2671  if (!nlib_atomic_compare_exchange32(lock, &expected, 0, 0,
2673  NLIB_ASSUME(expected == 2);
2674  nlib_spinlock_unlock_(lock);
2675  }
2676 #if defined(__arm__)
2677  __sev();
2678 #endif
2679 #endif
2680 }
2681 #endif
2682 
2683 //
2684 // Utilities(Safer style functions)
2685 //
2687 errno_t nlib_vsnprintf(size_t* __restrict count, char* __restrict buf, size_t size,
2688  _Printf_format_string_ const char* __restrict fmt, va_list args)
2691 errno_t nlib_snprintf(size_t* __restrict count, char* __restrict buf, size_t size,
2692  _Printf_format_string_ const char* __restrict fmt, ...)
2693  NLIB_ATTRIBUTE_PRINTF(4, 5) NLIB_NONNULL_4;
2695 errno_t nlib_vdprintf(nlib_fd fd, size_t* __restrict count,
2696  _Printf_format_string_ const char* __restrict fmt, va_list args)
2699 errno_t nlib_dprintf(nlib_fd fd, size_t* __restrict count,
2700  _Printf_format_string_ const char* __restrict fmt, ...)
2701  NLIB_ATTRIBUTE_PRINTF(3, 4) NLIB_NONNULL_3;
2702 // fmt and string must be in UTF-8 even if you use Visual Studio
2704 int nlib_printf(_Printf_format_string_ const char* fmt, ...)
2705  NLIB_ATTRIBUTE_PRINTF(1, 2) NLIB_NONNULL_1;
2706 
2708 errno_t nlib_vsnwprintf(size_t* __restrict count, wchar_t* __restrict buf, size_t size,
2709  _Printf_format_string_ const wchar_t* __restrict fmt, va_list args)
2712 errno_t nlib_snwprintf(size_t* __restrict count, wchar_t* __restrict buf, size_t size,
2713  _Printf_format_string_ const wchar_t* __restrict fmt, ...)
2716 errno_t nlib_vdwprintf(nlib_fd fd, size_t* __restrict count,
2717  _Printf_format_string_ const wchar_t* __restrict fmt, va_list args)
2720 errno_t nlib_dwprintf(nlib_fd fd, size_t* __restrict count,
2721  _Printf_format_string_ const wchar_t* __restrict fmt, ...) NLIB_NONNULL_3;
2723 int nlib_wprintf(_Printf_format_string_ const wchar_t* fmt, ...) NLIB_NONNULL_1;
2724 
2726 errno_t nlib_vsnprintf_fallback(size_t* __restrict count, char* __restrict buf, size_t size,
2727  _Printf_format_string_ const char* __restrict fmt, va_list args)
2730 errno_t nlib_snprintf_fallback(size_t* __restrict count, char* __restrict buf,
2731  size_t size, _Printf_format_string_ const char* __restrict fmt, ...)
2732  NLIB_ATTRIBUTE_PRINTF(4, 5) NLIB_NONNULL_4;
2734 errno_t nlib_vsnwprintf_fallback(size_t* __restrict count, wchar_t* __restrict buf, size_t size,
2735  _Printf_format_string_ const wchar_t* __restrict fmt, va_list args)
2738 errno_t nlib_snwprintf_fallback(size_t* __restrict count, wchar_t* __restrict buf, size_t size,
2739  _Printf_format_string_ const wchar_t* __restrict fmt, ...)
2741 
2742 // http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1078.pdf
2743 // http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1079.htm
2744 // a bit different from Microsoft's strcpy_s or etc.
2745 // returns ERANGE instead of EINVAL
2746 
2747 static errno_t nlib_memcpy(void* __restrict s1, size_t s1max, const void* __restrict s2, size_t n)
2748  NLIB_NONNULL;
2749 static errno_t nlib_memmove(void* s1, size_t s1max, const void* s2, size_t n) NLIB_NONNULL;
2750 static errno_t nlib_memset(void* buf, int ch, size_t n) NLIB_NONNULL;
2752 void* nlib_memccpy(void* __restrict dest, size_t dest_size, const void* __restrict src,
2753  size_t src_size, int c) NLIB_NONNULL;
2754 
2755 #ifdef NLIB_LIBC_nlib_memcmp
2756 static
2757 #else
2758 NLIB_VIS_PUBLIC_ALT
2759 #endif
2760 int nlib_memcmp(const void* buf1, const void* buf2, size_t n) NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
2761 #ifdef NLIB_LIBC_nlib_memcmp
2762 static NLIB_C_INLINE int nlib_memcmp(const void* buf1, const void* buf2, size_t n) {
2763  return memcmp(buf1, buf2, n);
2764 }
2765 #endif
2766 
2767 NLIB_VIS_PUBLIC_ALT const void* nlib_memchr(const void* s, int c, size_t n)
2768  NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
2769 NLIB_VIS_PUBLIC_ALT const void* nlib_memrchr(const void* s, int c, size_t n)
2770  NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
2771 NLIB_VIS_PUBLIC_ALT const void* nlib_memchr_not(const void* s, int c, size_t n)
2772  NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
2773 NLIB_VIS_PUBLIC_ALT
2774 const void* nlib_memchr_range_not(const void* __restrict s, const char* __restrict range,
2775  size_t n) NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
2776 NLIB_VIS_PUBLIC_ALT const void* nlib_memchr_lt(const void* s, int c, size_t n)
2777  NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
2778 NLIB_VIS_PUBLIC_ALT const void* nlib_memchr_gt(const void* s, int c, size_t n)
2779  NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
2780 // find (c & 0x80) != 0
2781 NLIB_VIS_PUBLIC_ALT const void* nlib_memchr_mb(const void* s, size_t n)
2782  NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
2783 NLIB_VIS_PUBLIC size_t nlib_memspn(const void* __restrict buf, size_t len,
2784  const char* __restrict set, size_t n)
2785  NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
2786 NLIB_VIS_PUBLIC size_t nlib_memcspn(const void* __restrict buf, size_t len,
2787  const char* __restrict set, size_t n)
2788  NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
2789 
2790 // ' ', CR, LF, HT are skipped
2791 NLIB_VIS_PUBLIC_ALT
2792 const char* nlib_skipws(size_t* __restrict cnt_lf, const char** __restrict last_lf,
2793  const char* __restrict s, size_t n) NLIB_NONNULL_2;
2794 
2795 #ifdef NLIB_LIBC_nlib_strlen
2796 static
2797 #else
2798 NLIB_VIS_PUBLIC_ALT
2799 #endif
2800 size_t nlib_strlen(const char* s) NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
2801 #ifdef NLIB_LIBC_nlib_strlen
2802 static NLIB_C_INLINE size_t nlib_strlen(const char* s) { return strlen(s); }
2803 #endif
2804 
2805 #ifdef NLIB_LIBC_nlib_strnlen
2806 static
2807 #else
2808 NLIB_VIS_PUBLIC_ALT
2809 #endif
2810 size_t nlib_strnlen(const char* s, size_t maxsize) NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
2811 #ifdef NLIB_LIBC_nlib_strnlen
2812 static NLIB_C_INLINE size_t nlib_strnlen(const char* s, size_t maxsize) {
2813 #if defined(_MSC_VER) || defined(__STDC_LIB_EXT1__)
2814  return strnlen_s(s, maxsize);
2815 #else
2816  return strnlen(s, maxsize);
2817 #endif
2818 }
2819 #endif
2820 
2821 #ifdef NLIB_LIBC_nlib_strcpy
2822 static
2823 #else
2825 #endif
2826 errno_t nlib_strcpy(char* __restrict s1, size_t s1max, const char* __restrict s2) NLIB_NONNULL;
2827 #ifdef NLIB_LIBC_nlib_strcpy
2828 static NLIB_C_INLINE
2829 errno_t nlib_strcpy(char* __restrict s1, size_t s1max, const char* __restrict s2) {
2830 #if defined(_MSC_VER) || defined(__STDC_LIB_EXT1__)
2831  return strcpy_s(s1, s1max, s2);
2832 #else
2833 # error
2834 #endif
2835 }
2836 #endif
2837 
2838 #ifdef NLIB_LIBC_nlib_strncpy
2839 static
2840 #else
2842 #endif
2843 errno_t nlib_strncpy(char* __restrict s1, size_t s1max, const char* __restrict s2, size_t n)
2844  NLIB_NONNULL;
2845 #ifdef NLIB_LIBC_nlib_strncpy
2846 static NLIB_C_INLINE
2847 errno_t nlib_strncpy(char* __restrict s1, size_t s1max, const char* __restrict s2, size_t n) {
2848 #if defined(_MSC_VER) || defined(__STDC_LIB_EXT1__)
2849  return strncpy_s(s1, s1max, s2, n);
2850 #else
2851 # error
2852 #endif
2853 }
2854 #endif
2855 
2856 #ifdef NLIB_LIBC_nlib_strchr
2857 static
2858 #else
2859 NLIB_VIS_PUBLIC_ALT
2860 #endif
2861 const char* nlib_strchr(const char* s, int c) NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
2862 #ifdef NLIB_LIBC_nlib_strchr
2863 static NLIB_C_INLINE const char* nlib_strchr(const char* s, int c) { return strchr(s, c); }
2864 #endif
2865 
2866 #ifdef NLIB_LIBC_nlib_strrchr
2867 static
2868 #else
2869 NLIB_VIS_PUBLIC_ALT
2870 #endif
2871 const char* nlib_strrchr(const char* s, int c) NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
2872 #ifdef NLIB_LIBC_nlib_strrchr
2873 static NLIB_C_INLINE const char* nlib_strrchr(const char* s, int c) { return strrchr(s, c); }
2874 #endif
2875 
2876 // find (c & 0x80) != 0, used for skipping ASCII chars
2877 static const char* nlib_strchr_mb(const char* s) NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
2878 static NLIB_C_INLINE const char* nlib_strchr_mb(const char* s) {
2879  size_t n = nlib_strlen(s);
2880  const void* p = nlib_memchr_mb(s, n);
2881  if (p) {
2882  return (const char*)p; // NOLINT
2883  } else {
2884  return s + n;
2885  }
2886 }
2887 
2888 #ifdef NLIB_LIBC_nlib_wcslen
2889 static
2890 #else
2892 #endif
2893 size_t nlib_wcslen(const wchar_t* s) NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
2894 #ifdef NLIB_LIBC_nlib_wcslen
2895 static NLIB_C_INLINE size_t nlib_wcslen(const wchar_t* s) { return wcslen(s); }
2896 #endif
2897 
2898 #ifdef NLIB_LIBC_nlib_wcsnlen
2899 static
2900 #else
2902 #endif
2903 size_t nlib_wcsnlen(const wchar_t* s, size_t maxsize) NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
2904 #ifdef NLIB_LIBC_nlib_wcsnlen
2905 static NLIB_C_INLINE size_t nlib_wcsnlen(const wchar_t* s, size_t maxsize) {
2906 #if defined(_MSC_VER) || defined(__STDC_LIB_EXT1__)
2907  return wcsnlen_s(s, maxsize);
2908 #else
2909  return wcsnlen(s, maxsize);
2910 #endif
2911 }
2912 #endif
2913 
2914 #ifdef NLIB_LIBC_nlib_wcscpy
2915 static
2916 #else
2918 #endif
2919 errno_t nlib_wcscpy(wchar_t* __restrict s1, size_t s1max, const wchar_t* __restrict s2)
2920  NLIB_NONNULL;
2921 #ifdef NLIB_LIBC_nlib_wcscpy
2922 static NLIB_C_INLINE
2923 errno_t nlib_wcscpy(wchar_t* __restrict s1, size_t s1max, const wchar_t* __restrict s2) {
2924 #if defined(_MSC_VER) || defined(__STDC_LIB_EXT1__)
2925  return wcscpy_s(s1, s1max, s2);
2926 #else
2927 # error
2928 #endif
2929 }
2930 #endif
2931 
2932 #ifdef NLIB_LIBC_nlib_wcsncpy
2933 static
2934 #else
2936 #endif
2937 errno_t nlib_wcsncpy(wchar_t* __restrict s1, size_t s1max, const wchar_t* __restrict s2, size_t n)
2938  NLIB_NONNULL;
2939 #ifdef NLIB_LIBC_nlib_wcsncpy
2940 static NLIB_C_INLINE
2941 errno_t nlib_wcsncpy(wchar_t* __restrict s1, size_t s1max, const wchar_t* __restrict s2, size_t n) {
2942 #if defined(_MSC_VER) || defined(__STDC_LIB_EXT1__)
2943  return wcsncpy_s(s1, s1max, s2, n);
2944 #else
2945 # error
2946 #endif
2947 }
2948 #endif
2949 
2951 errno_t nlib_strto_int32(int32_t* result, const char* nptr, char** endptr, int base)
2952  NLIB_NONNULL_1 NLIB_NONNULL_2;
2954 errno_t nlib_strto_int64(int64_t* result, const char* nptr, char** endptr, int base)
2955  NLIB_NONNULL_1 NLIB_NONNULL_2;
2957 errno_t nlib_strto_uint32(uint32_t* result, const char* nptr, char** endptr, int base)
2958  NLIB_NONNULL_1 NLIB_NONNULL_2;
2960 errno_t nlib_strto_uint64(uint64_t* result, const char* nptr, char** endptr, int base)
2961  NLIB_NONNULL_1 NLIB_NONNULL_2;
2963 errno_t nlib_strto_double(double* result, const char* nptr, char** endptr)
2964  NLIB_NONNULL_1 NLIB_NONNULL_2;
2966 errno_t nlib_strto_float(float* result, const char* nptr, char** endptr)
2967  NLIB_NONNULL_1 NLIB_NONNULL_2;
2969 errno_t nlib_strto_int32_fallback(int32_t* result, const char* nptr, char** endptr, int base)
2970  NLIB_NONNULL_1 NLIB_NONNULL_2;
2972 errno_t nlib_strto_int64_fallback(int64_t* result, const char* nptr, char** endptr, int base)
2973  NLIB_NONNULL_1 NLIB_NONNULL_2;
2975 errno_t nlib_strto_uint32_fallback(uint32_t* result, const char* nptr, char** endptr, int base)
2976  NLIB_NONNULL_1 NLIB_NONNULL_2;
2978 errno_t nlib_strto_uint64_fallback(uint64_t* result, const char* nptr, char** endptr, int base)
2979  NLIB_NONNULL_1 NLIB_NONNULL_2;
2981 errno_t nlib_strto_double_fallback(double* result, const char* nptr, char** endptr)
2982  NLIB_NONNULL_1 NLIB_NONNULL_2;
2984 errno_t nlib_strto_float_fallback(float* result, const char* nptr, char** endptr)
2985  NLIB_NONNULL_1 NLIB_NONNULL_2;
2986 static NLIB_C_INLINE
2987 errno_t nlib_strto_int8(int8_t* result, const char* nptr, char** endptr, int base) {
2988  int32_t tmp;
2989  errno_t e;
2990  e = nlib_strto_int32(&tmp, nptr, endptr, base);
2991  if (e != 0 && e != ERANGE) return e;
2992  if (tmp > 127 || tmp < -128) {
2993  *result = tmp < 0 ? -128 : 127;
2994  return ERANGE;
2995  }
2996  *result = (int8_t)tmp; // NOLINT
2997  return e;
2998 }
2999 static NLIB_C_INLINE
3000 errno_t nlib_strto_int16(int16_t* result, const char* nptr, char** endptr, int base) {
3001  int32_t tmp;
3002  errno_t e;
3003  e = nlib_strto_int32(&tmp, nptr, endptr, base);
3004  if (e != 0 && e != ERANGE) return e;
3005  if (tmp > 32767 || tmp < -32768) {
3006  *result = tmp < 0 ? -32768 : 32767;
3007  return ERANGE;
3008  }
3009  *result = (int16_t)tmp; // NOLINT
3010  return e;
3011 }
3012 static NLIB_C_INLINE
3013 errno_t nlib_strto_uint8(uint8_t* result, const char* nptr, char** endptr, int base) {
3014  uint32_t tmp;
3015  errno_t e;
3016  e = nlib_strto_uint32(&tmp, nptr, endptr, base);
3017  if (e != 0 && e != ERANGE) return e;
3018  if (tmp > 255) {
3019  *result = 255;
3020  return ERANGE;
3021  }
3022  *result = (uint8_t)tmp; // NOLINT
3023  return e;
3024 }
3025 static NLIB_C_INLINE
3026 errno_t nlib_strto_uint16(uint16_t* result, const char* nptr, char** endptr, int base) {
3027  uint32_t tmp;
3028  errno_t e;
3029  e = nlib_strto_uint32(&tmp, nptr, endptr, base);
3030  if (e != 0 && e != ERANGE) return e;
3031  if (tmp > 65535) {
3032  *result = 65535;
3033  return ERANGE;
3034  }
3035  *result = (uint16_t)tmp; // NOLINT
3036  return e;
3037 }
3038 
3040 errno_t nlib_wide_to_utf8(size_t* __restrict utf8count, char* __restrict utf8,
3041  size_t buflen, const wchar_t* __restrict wcstr) NLIB_NONNULL_4;
3043 errno_t nlib_utf8_to_wide(size_t* __restrict wccount, wchar_t* __restrict wcstr,
3044  size_t buflen, const char* __restrict utf8) NLIB_NONNULL_4;
3046 errno_t nlib_memwide_to_utf8(size_t* __restrict to_count, size_t* __restrict from_count,
3047  char* __restrict to, size_t to_size,
3048  const wchar_t* __restrict from, size_t from_size)
3049  NLIB_NONNULL_1 NLIB_NONNULL_2 NLIB_NONNULL_5;
3051 errno_t nlib_memutf8_to_wide(size_t* __restrict to_count, size_t* __restrict from_count,
3052  wchar_t* __restrict to, size_t to_size,
3053  const char* __restrict from, size_t from_size)
3054  NLIB_NONNULL_1 NLIB_NONNULL_2 NLIB_NONNULL_5;
3055 
3057 errno_t nlib_wcscplen(size_t* __restrict count, const wchar_t* __restrict str) NLIB_NONNULL_2;
3059 errno_t nlib_strcplen(size_t* __restrict codepoint_count,
3060  size_t* __restrict supplementary_codepoint_count,
3061  size_t* __restrict len,
3062  const char* __restrict str) NLIB_NONNULL_4;
3063 #define nlib_strcplen2 nlib_strcplen
3065 errno_t nlib_memcplen(size_t* __restrict codepoint_count,
3066  size_t* __restrict supplementary_codepoint_count,
3067  size_t* __restrict from_read,
3068  const char* __restrict from,
3069  size_t from_size) NLIB_NONNULL_3 NLIB_NONNULL_4;
3070 
3071 // for (0..count) { swapendian(p[count]); }
3072 NLIB_VIS_PUBLIC_ALT errno_t nlib_swapendian_16(uint16_t* p, size_t count) NLIB_NONNULL;
3073 // for (0..count) { swapendian(p[count]); }
3074 NLIB_VIS_PUBLIC_ALT errno_t nlib_swapendian_32(uint32_t* p, size_t count) NLIB_NONNULL;
3075 // for (0..count) { swapendian(p[count]); }
3076 NLIB_VIS_PUBLIC_ALT errno_t nlib_swapendian_64(uint64_t* p, size_t count) NLIB_NONNULL;
3077 
3078 //
3079 // malloc functions which nlib uses
3080 // You can redefine them.
3081 // See sample replace_malloc.cpp of nlibnx_heap.a library.
3082 //
3083 
3084 // weak function
3085 NLIB_VIS_PUBLIC_ALT NLIB_CHECK_RESULT
3086 void* nlib_malloc(size_t size) NLIB_ATTRIBUTE_MALLOC NLIB_ATTRIBUTE_ALLOC_SIZE1(1);
3087 
3088 // weak function
3089 NLIB_VIS_PUBLIC_ALT void nlib_free(void* ptr);
3090 
3091 // weak function
3092 NLIB_VIS_PUBLIC_ALT NLIB_CHECK_RESULT
3093 void* nlib_calloc(size_t nmemb, size_t size)
3094  NLIB_ATTRIBUTE_MALLOC NLIB_ATTRIBUTE_ALLOC_SIZE2(1, 2);
3095 
3096 // weak function
3097 NLIB_VIS_PUBLIC_ALT NLIB_CHECK_RESULT
3098 void* nlib_realloc(void* ptr, size_t size) NLIB_ATTRIBUTE_MALLOC NLIB_ATTRIBUTE_ALLOC_SIZE1(2);
3099 
3100 // weak function, not defined if CAFE or CTR
3101 NLIB_VIS_PUBLIC size_t nlib_malloc_size(const void* ptr) NLIB_NONNULL;
3102 
3103 // weak function(calls nlib_free(ptr) by default)
3104 NLIB_VIS_PUBLIC_ALT void nlib_free_size(void* ptr, size_t size);
3105 
3106 // weak function, not defined if WIN32 or CTR
3107 NLIB_VIS_PUBLIC_ALT NLIB_CHECK_RESULT
3108 void* nlib_memalign(size_t alignment, size_t size)
3109  NLIB_ATTRIBUTE_MALLOC NLIB_ATTRIBUTE_ALLOC_SIZE1(2) NLIB_ATTRIBUTE_ALLOC_ALIGN(1);
3110 
3111 #ifndef NLIB_MEMCPY
3112 # define NLIB_MEMCPY(a, b, c) memcpy((a), (b), (c))
3113 #endif
3114 
3115 #ifndef NLIB_MEMMOVE
3116 # define NLIB_MEMMOVE(a, b, c) memmove((a), (b), (c))
3117 #endif
3118 
3119 #ifndef NLIB_MEMSET
3120 # define NLIB_MEMSET(a, b, c) memset((a), (b), (c))
3121 #endif
3122 
3123 // ctype.h without locale
3124 static int nlib_isalnum(int ch) NLIB_ATTRIBUTE_CONST;
3125 static int nlib_isalpha(int ch) NLIB_ATTRIBUTE_CONST;
3126 static int nlib_isblank(int ch) NLIB_ATTRIBUTE_CONST;
3127 static int nlib_iscntrl(int ch) NLIB_ATTRIBUTE_CONST;
3128 static int nlib_isdigit(int ch) NLIB_ATTRIBUTE_CONST;
3129 static int nlib_isgraph(int ch) NLIB_ATTRIBUTE_CONST;
3130 static int nlib_islower(int ch) NLIB_ATTRIBUTE_CONST;
3131 static int nlib_isprint(int ch) NLIB_ATTRIBUTE_CONST;
3132 static int nlib_ispunct(int ch) NLIB_ATTRIBUTE_CONST;
3133 static int nlib_isspace(int ch) NLIB_ATTRIBUTE_CONST;
3134 static int nlib_isupper(int ch) NLIB_ATTRIBUTE_CONST;
3135 static int nlib_isxdigit(int ch) NLIB_ATTRIBUTE_CONST;
3136 static int nlib_tolower(int ch) NLIB_ATTRIBUTE_CONST;
3137 static int nlib_toupper(int ch) NLIB_ATTRIBUTE_CONST;
3138 
3139 static NLIB_C_INLINE int nlib_isalnum(int ch) {
3140  return ('0' <= ch && ch <= '9') || ('A' <= ch && ch <= 'Z') || ('a' <= ch && ch <= 'z');
3141 }
3142 static NLIB_C_INLINE int nlib_isalpha(int ch) {
3143  return ('A' <= ch && ch <= 'Z') || ('a' <= ch && ch <= 'z');
3144 }
3145 static NLIB_C_INLINE int nlib_isblank(int ch) { return ch == ' ' || ch == '\t'; }
3146 static NLIB_C_INLINE int nlib_iscntrl(int ch) { return (ch >= 0 && ch <= 0x1F) || ch == 0x7F; }
3147 static NLIB_C_INLINE int nlib_isdigit(int ch) { return ('0' <= ch && ch <= '9'); }
3148 static NLIB_C_INLINE int nlib_isgraph(int ch) { return ch >= 0x21 && ch <= 0x7E; }
3149 static NLIB_C_INLINE int nlib_islower(int ch) { return (ch >= 'a' && ch <= 'z'); }
3150 static NLIB_C_INLINE int nlib_isprint(int ch) { return ch >= 0x20 && ch <= 0x7E; }
3151 static NLIB_C_INLINE int nlib_ispunct(int ch) { return (ch >= 0x00 && ch <= 0x20) || ch == 0x7F; }
3152 static NLIB_C_INLINE int nlib_isspace(int ch) {
3153  return ((ch) == ' ' || (ch) == '\t' || (ch) == '\n');
3154 }
3155 static NLIB_C_INLINE int nlib_isupper(int ch) { return (ch >= 'A' && ch <= 'Z'); }
3156 static NLIB_C_INLINE int nlib_isxdigit(int ch) {
3157  return (unsigned int)(ch - '0') < 10u ||
3158  (unsigned int)((ch | 0x20) - 'a') < 6u;
3159 }
3160 static NLIB_C_INLINE int nlib_tolower(int ch) {
3161  return (ch >= 'A' && ch <= 'Z') ? ch + ('a' - 'A') : ch;
3162 }
3163 static NLIB_C_INLINE int nlib_toupper(int ch) {
3164  return (ch >= 'a' && ch <= 'z') ? ch - ('a' - 'A') : ch;
3165 }
3166 // no isascii, toascii
3167 
3168 // memcpy_s
3169 static NLIB_C_INLINE
3170 errno_t nlib_memcpy(void* __restrict s1, size_t s1max, const void* __restrict s2, size_t n) {
3171 #if defined(_MSC_VER) || defined(__STDC_LIB_EXT1__)
3172  return memcpy_s(s1, s1max, s2, n);
3173 #else
3174 #ifndef NLIB_NONNULL_ENABLED
3175  if (!s1 || !s2) return ERANGE;
3176 #endif
3177  if (s1max < n) {
3178  NLIB_MEMSET(s1, 0, s1max);
3179  return ERANGE;
3180  }
3181  NLIB_MEMCPY(s1, s2, n);
3182  return 0;
3183 #endif
3184 }
3185 
3186 // memmove_s
3187 static NLIB_C_INLINE
3188 errno_t nlib_memmove(void* s1, size_t s1max, const void* s2, size_t n) {
3189 #if defined(_MSC_VER) || defined(__STDC_LIB_EXT1__)
3190  return memmove_s(s1, s1max, s2, n);
3191 #else
3192 #ifndef NLIB_NONNULL_ENABLED
3193  if (!s1 || !s2) return ERANGE;
3194 #endif
3195  if (s1max < n) return ERANGE;
3196  NLIB_MEMMOVE(s1, s2, n);
3197  return 0;
3198 #endif
3199 }
3200 
3201 static NLIB_C_INLINE
3202 errno_t nlib_memset(void* buf, int ch, size_t n) {
3203  NLIB_EINVAL_IFNULL(buf);
3204  NLIB_MEMSET(buf, ch, n);
3205  return 0;
3206 }
3207 
3208 static int nlib_popcnt16(uint16_t x) NLIB_ATTRIBUTE_CONST;
3209 static int nlib_popcnt32(uint32_t x) NLIB_ATTRIBUTE_CONST;
3210 static int nlib_popcnt64(uint64_t x) NLIB_ATTRIBUTE_CONST;
3211 #if defined(NLIB_SSE42)
3212 static NLIB_ALWAYS_INLINE int nlib_popcnt16(uint16_t x) {
3213  return _mm_popcnt_u32(x);
3214 }
3215 static NLIB_ALWAYS_INLINE int nlib_popcnt32(uint32_t x) {
3216  return _mm_popcnt_u32(x);
3217 }
3218 static NLIB_ALWAYS_INLINE int nlib_popcnt64(uint64_t x) {
3219 #ifdef NLIB_64BIT
3220  return (int)_mm_popcnt_u64(x); // NOLINT
3221 #else
3222  uint32_t lo = (uint32_t)(x & 0xFFFFFFFFU); // NOLINT
3223  uint32_t hi = (uint32_t)((x >> 32) & 0xFFFFFFFFU); // NOLINT
3224  return _mm_popcnt_u32(lo) + _mm_popcnt_u32(hi); // NOLINT
3225 #endif
3226 }
3227 #elif defined(NLIB_NEON)
3228 static NLIB_ALWAYS_INLINE int nlib_popcnt16(uint16_t x) {
3229  uint8x8_t x0 = vcnt_u8(vreinterpret_u8_u64(vcreate_u64(x)));
3230 #ifdef __aarch64__
3231  return vaddv_u8(x0);
3232 #else
3233  uint8x8_t x1 = vpadd_u8(x0, x0);
3234  return vget_lane_u8(x1, 0);
3235 #endif
3236 }
3237 static NLIB_ALWAYS_INLINE int nlib_popcnt32(uint32_t x) {
3238  uint8x8_t x0 = vcnt_u8(vreinterpret_u8_u64(vcreate_u64(x)));
3239 #ifdef __aarch64__
3240  return vaddv_u8(x0);
3241 #else
3242  uint8x8_t x1 = vpadd_u8(x0, x0);
3243  uint8x8_t x2 = vpadd_u8(x1, x1);
3244  return vget_lane_u8(x2, 0);
3245 #endif
3246 }
3247 static NLIB_ALWAYS_INLINE int nlib_popcnt64(uint64_t x) {
3248  uint8x8_t x0 = vcnt_u8(vreinterpret_u8_u64(vcreate_u64(x)));
3249 #ifdef __aarch64__
3250  return vaddv_u8(x0);
3251 #else
3252  uint8x8_t x1 = vpadd_u8(x0, x0);
3253  uint8x8_t x2 = vpadd_u8(x1, x1);
3254  uint8x8_t x3 = vpadd_u8(x2, x2);
3255  return vget_lane_u8(x3, 0);
3256 #endif
3257 }
3258 #else
3259 extern NLIB_VIS_PUBLIC const unsigned char _nlib_popcnt_array[];
3260 static NLIB_ALWAYS_INLINE int nlib_popcnt32(uint32_t x) {
3261  return _nlib_popcnt_array[(x >> 24) & 0xFF] + _nlib_popcnt_array[(x >> 16) & 0xFF] +
3262  _nlib_popcnt_array[(x >> 8) & 0xFF] + _nlib_popcnt_array[(x)& 0xFF];
3263 }
3264 static NLIB_ALWAYS_INLINE int nlib_popcnt64(uint64_t x) {
3265  return _nlib_popcnt_array[(x >> 56) & 0xFF] + _nlib_popcnt_array[(x >> 48) & 0xFF] +
3266  _nlib_popcnt_array[(x >> 40) & 0xFF] + _nlib_popcnt_array[(x >> 32) & 0xFF] +
3267  _nlib_popcnt_array[(x >> 24) & 0xFF] + _nlib_popcnt_array[(x >> 16) & 0xFF] +
3268  _nlib_popcnt_array[(x >> 8) & 0xFF] + _nlib_popcnt_array[(x)& 0xFF];
3269 }
3270 static NLIB_ALWAYS_INLINE int nlib_popcnt16(uint16_t x) {
3271  return _nlib_popcnt_array[(x >> 8) & 0xFF] + _nlib_popcnt_array[(x)& 0xFF];
3272 }
3273 #endif
3274 #define nlib_popcnt(x) nlib_popcnt32(x)
3275 
3276 // nlib_clz32(0x80000000) -> 0, nlib_clz32(1) -> 31
3277 static int nlib_clz32(uint32_t x) NLIB_ATTRIBUTE_CONST;
3278 // nlib_ctz32(0x80000000) -> 31, nlib_ctz32(1) -> 0
3279 static int nlib_ctz32(uint32_t x) NLIB_ATTRIBUTE_CONST;
3280 // nlib_clz64(INT64_MIN) -> 0, nlib_clz64(1) -> 63
3281 static int nlib_clz64(uint64_t x) NLIB_ATTRIBUTE_CONST;
3282 // nlib_ctz64(INT64_MIN) -> 63, nlib_ctz64(1) -> 0
3283 static int nlib_ctz64(uint64_t x) NLIB_ATTRIBUTE_CONST;
3284 #if defined(_MSC_VER)
3285 static NLIB_ALWAYS_INLINE int nlib_clz32(uint32_t x) {
3286  DWORD cnt;
3287  return _BitScanReverse(&cnt, x) ? (int)(31 - cnt) : 32; // NOLINT
3288  // return (int)(__lzcnt(x)); // needs haswell+
3289 }
3290 static NLIB_ALWAYS_INLINE int nlib_ctz32(uint32_t x) {
3291  DWORD cnt;
3292  return _BitScanForward(&cnt, x) ? cnt : 32;
3293 }
3294 static NLIB_ALWAYS_INLINE int nlib_clz64(uint64_t x) {
3295 #ifdef NLIB_64BIT
3296  DWORD cnt;
3297  return _BitScanReverse64(&cnt, x) ? (int)(63 - cnt) : 64; // NOLINT
3298  // return (int)(__lzcnt64(x)); // needs haswell+
3299 #else
3300  DWORD cnt;
3301  DWORD dw = (DWORD)(x >> 32);
3302  if (_BitScanReverse(&cnt, dw)) {
3303  return (int)(31 - cnt); // NOLINT
3304  } else {
3305  dw = (DWORD)(x);
3306  return _BitScanReverse(&cnt, dw) ?
3307  (int)(63 - cnt) : 64; // NOLINT
3308  }
3309 #endif
3310 }
3311 static NLIB_ALWAYS_INLINE int nlib_ctz64(uint64_t x) {
3312 #ifdef NLIB_64BIT
3313  DWORD cnt;
3314  return _BitScanForward64(&cnt, x) ? cnt : 64;
3315 #else
3316  DWORD cnt;
3317  DWORD dw = (DWORD)(x);
3318  if (_BitScanForward(&cnt, dw)) {
3319  return (int)(cnt); // NOLINT
3320  } else {
3321  dw = (DWORD)(x >> 32);
3322  return _BitScanForward(&cnt, dw) ?
3323  (int)(32 + cnt) : 64; // NOLINT
3324  }
3325 #endif
3326 }
3327 #elif defined(CAFE)
3328 static NLIB_ALWAYS_INLINE int nlib_clz32(uint32_t x) { return __CLZ32(x); }
3329 static NLIB_ALWAYS_INLINE int nlib_ctz32(uint32_t x) { return 32 - nlib_clz32(~x & (x - 1)); }
3330 static NLIB_ALWAYS_INLINE int nlib_clz64(uint64_t x) {
3331  int cnt;
3332  unsigned int dw = (unsigned int)(x >> 32); // NOLINT
3333  cnt = __CLZ32(dw);
3334  if (cnt < 32) {
3335  return cnt;
3336  } else {
3337  dw = (unsigned int)(x); // NOLINT
3338  cnt = __CLZ32(dw);
3339  return 32 + cnt;
3340  }
3341 }
3342 static NLIB_ALWAYS_INLINE int nlib_ctz64(uint64_t x) { return 64 - nlib_clz64(~x & (x - 1)); }
3343 #elif defined(NN_PLATFORM_CTR)
3344 static NLIB_ALWAYS_INLINE int nlib_clz32(uint32_t x) { return x != 0 ? __builtin_clz(x) : 32; }
3345 static NLIB_ALWAYS_INLINE int nlib_ctz32(uint32_t x) { return 32 - nlib_clz32(~x & (x - 1)); }
3346 static NLIB_ALWAYS_INLINE int nlib_clz64(uint64_t x) { return x != 0 ? __builtin_clzll(x) : 64; }
3347 static NLIB_ALWAYS_INLINE int nlib_ctz64(uint64_t x) { return 64 - nlib_clz64(~x & (x - 1)); }
3348 #else
3349 static NLIB_ALWAYS_INLINE int nlib_clz32(uint32_t x) { return x != 0 ? __builtin_clz(x) : 32; }
3350 static NLIB_ALWAYS_INLINE int nlib_ctz32(uint32_t x) { return x != 0 ? __builtin_ctz(x) : 32; }
3351 static NLIB_ALWAYS_INLINE int nlib_clz64(uint64_t x) { return x != 0 ? __builtin_clzll(x) : 64; }
3352 static NLIB_ALWAYS_INLINE int nlib_ctz64(uint64_t x) { return x != 0 ? __builtin_ctzll(x) : 64; }
3353 #endif
3354 #define nlib_clz(x) nlib_clz32(x)
3355 #define nlib_ctz(x) nlib_ctz32(x)
3356 
3357 static size_t nlib_strlcpy(char* __restrict s1, const char* __restrict s2, size_t s1max)
3358  NLIB_NONNULL;
3359 static NLIB_C_INLINE
3360 size_t nlib_strlcpy(char* __restrict s1, const char* __restrict s2, size_t s1max) {
3361 #if defined(__FreeBSD__)
3362  return strlcpy(s1, s2, s1max);
3363 #else
3364  size_t len = nlib_strlen(s2);
3365  if (NLIB_LIKELY(len < s1max)) {
3366  NLIB_MEMCPY(s1, s2, len + 1);
3367  } else if (NLIB_LIKELY(s1max > 0)) {
3368  NLIB_MEMCPY(s1, s2, s1max - 1);
3369  s1[s1max - 1] = '\0';
3370  }
3371  return len;
3372 #endif
3373 }
3374 
3375 static uint32_t nlib_bitreverse32(uint32_t x) NLIB_ATTRIBUTE_CONST;
3376 static uint64_t nlib_bitreverse64(uint64_t x) NLIB_ATTRIBUTE_CONST;
3377 
3378 static NLIB_ALWAYS_INLINE uint32_t nlib_bitreverse32(uint32_t x) {
3379 #if __has_builtin(__builtin_bitreverse32)
3380  return __builtin_bitreverse32(x);
3381 #elif __has_builtin(__builtin_arm_rbit)
3382  return __builtin_arm_rbit(x);
3383 #elif defined(__arm__) && !defined(NN_PLATFORM_CTR)
3384  return __rbit(x);
3385 #else
3386  x = ((x & 0x55555555UL) << 1) | ((x >> 1) & 0x55555555UL);
3387  x = ((x & 0x33333333UL) << 2) | ((x >> 2) & 0x33333333UL);
3388  x = ((x & 0x0F0F0F0FUL) << 4) | ((x >> 4) & 0x0F0F0F0FUL);
3389 #ifdef _MSC_VER
3390  x = _byteswap_ulong(x);
3391 #elif defined(CAFE) || defined(NN_PLATFORM_CTR)
3392  x = (x << 24) | ((x & 0xFF00) << 8) |
3393  ((x >> 8) & 0xFF00) | (x >> 24);
3394 #else
3395  x = __builtin_bswap32(x);
3396 #endif
3397  return x;
3398 #endif
3399 }
3400 
3401 static NLIB_ALWAYS_INLINE uint64_t nlib_bitreverse64(uint64_t x) {
3402 #if __has_builtin(__builtin_bitreverse64)
3403  return __builtin_bitreverse64(x);
3404 #elif __has_builtin(__builtin_arm_rbit64)
3405  return __builtin_arm_rbit64(x);
3406 #elif __has_builtin(__builtin_arm_rbit)
3407  return __builtin_arm_rbit(x >> 32) |
3408  (((uint64_t)__builtin_arm_rbit(x)) << 32);
3409 #elif defined(__arm__) && !defined(NN_PLATFORM_CTR)
3410  return __rbit(x >> 32) |
3411  (((uint64_t)__rbit(x)) << 32);
3412 #else
3413  x = ((x & 0x5555555555555555ULL) << 1) | ((x >> 1) & 0x5555555555555555ULL);
3414  x = ((x & 0x3333333333333333ULL) << 2) | ((x >> 2) & 0x3333333333333333ULL);
3415  x = ((x & 0x0F0F0F0F0F0F0F0FULL) << 4) | ((x >> 4) & 0x0F0F0F0F0F0F0F0FULL);
3416 #ifdef _MSC_VER
3417  x = _byteswap_uint64(x);
3418 #elif defined(CAFE) || defined(NN_PLATFORM_CTR)
3419  x =
3420  (x << 56) |
3421  ((x & 0xFF00U) << 40) |
3422  ((x & 0xFF0000U) << 24) |
3423  ((x & 0xFF000000U) << 8) |
3424  ((x >> 8) & 0xFF000000U) |
3425  ((x >> 24) & 0xFF0000U) |
3426  ((x >> 40) & 0xFF00U) |
3427  (x >> 56);
3428 #else
3429  x = __builtin_bswap64(x);
3430 #endif
3431  return x;
3432 #endif
3433 }
3434 
3435 #undef NLIB_MEMCPY
3436 #undef NLIB_MEMMOVE
3437 #undef NLIB_MEMSET
3438 
3439 #ifdef __cplusplus
3440 }
3441 #endif
3442 
3443 #if defined(_MSC_VER)
3444 #if defined(n_EXPORTS)
3445 #undef NLIB_VIS_PUBLIC
3446 #define NLIB_VIS_PUBLIC NLIB_WINIMPORT
3447 #elif defined(nx_misc_EXPORTS)
3448 # undef NLIB_VIS_PUBLIC
3449 # define NLIB_VIS_PUBLIC NLIB_WINEXPORT
3450 #endif
3451 #endif
3452 
3453 #endif // INCLUDE_NN_NLIB_PLATFORM_H_
errno_t nlib_rwlock_rdunlock(nlib_rwlock *rwlock) NLIB_RELEASE_SHARED(*rwlock)
Releases the read lock.
int32_t nlib_atomic_xor_fetch32(int32_t *ptr, int32_t val, int memorder)
Calculates XOR of atomic values. Its behavior is similar to the one for __atomic_xor_fetch() of gcc...
errno_t nlib_debug_backtrace_gettext(char *str, size_t strbufsize, void *const *buf, size_t count)
Creates string information from the data obtained using the nlib_debug_backtrace function.
errno_t nlib_thread_priority_max(int *priority)
Gets the largest numerical value that can be specified for the execution priority.
errno_t nlib_log_attr_setint(int prio, int key, int value)
Specifies where to output the log for each level of priority.
errno_t nlib_strto_uint64_fallback(uint64_t *result, const char *nptr, char **endptr, int base)
Converts a string to the uint64_t type without using a standard C function. For details, see nlib_strto_int32().
int64_t nlib_atomic_fetch_and64(int64_t *ptr, int64_t val, int memorder)
Calculates AND of atomic values. Its behavior is similar to the one for __atomic_fetch_and() of gcc...
const char * nlib_strrchr(const char *s, int c)
Searches for a character from the end of a string.
errno_t nlib_strto_double_fallback(double *result, const char *nptr, char **endptr)
Converts a string to the double type without using a standard C function. For details, see nlib_strto_int32().
int nlib_thread_equal(nlib_thread th1, nlib_thread th2)
Checks whether two threads point to the same thread.
static void nlib_spinlock_unlock(nlib_spinlock *lock)
Unlocks the spinlock.
Definition: Platform.h:2666
#define NLIB_NORETURN
Indicates that the process will not return from functions.
Definition: Platform_unix.h:75
errno_t nlib_semaphore_post_ex(nlib_semaphore *sem, int release_count, int *previous_count)
Increments the semaphore count by the amount specified by releaseCount.
#define NLIB_ATTRIBUTE_MALLOC
Defines __attribute__((malloc)) if it is available for use.
Definition: Platform_unix.h:83
errno_t nlib_condrwlock_wait(nlib_condrwlock *cond, nlib_rwlock *rwlock, int rdlock)
Unlocks rwlock and waits for a conditional variable. It then locks rwlock again after the execution r...
NLIB_CHECK_RESULT errno_t nlib_wcscplen(size_t *count, const wchar_t *str)
Gets the number of code points in the string.
Uses a bitwise OR to output levels at and above the specified level. Can be used with the nlib_log_at...
Definition: Platform.h:1632
NLIB_CHECK_RESULT errno_t nlib_fd_write(size_t *result, nlib_fd fd, const void *buf, size_t count)
Writes (up to) count bytes from buf to the file descriptor.
int nlib_atomic_compare_exchangeptr(void **ptr, void **expected, void *desired, int weak, int success_memorder, int failure_memorder)
Compares and swaps atomic values. Its behavior is similar to the one for __atomic_compare_exchange_n(...
int32_t nlib_atomic_load32(const int32_t *ptr, int memorder)
Loads a value in an atomic operation. Its behavior is similar to the one for __atomic_load_n() of gcc...
errno_t nlib_virtual_alloc(void **ptr, size_t size)
Allocates virtual memory address space.
errno_t nlib_dir_close(nlib_dir dir)
Closes a directory.
void * nlib_memccpy(void *dest, size_t dest_size, const void *src, size_t src_size, int c)
Continues copying until c is found. Stops copying when it is found.
static int nlib_isupper(int ch)
If ch is an ASCII character &#39;A&#39;-&#39;Z&#39;, the function returns non-zero. Otherwise, the function returns 0...
Definition: Platform.h:3155
errno_t nlib_vdwprintf(nlib_fd fd, size_t *count, const wchar_t *fmt, va_list args)
The version of the vsnwprintf function that outputs to a file descriptor.
static NLIB_CHECK_RESULT errno_t nlib_fd_creat(nlib_fd *fd, const char *native_path, int mode)
Equivalent to nlib_fd_open(fd, native_path, NLIB_FD_O_CREAT | NLIB_FD_O_WRONLY | NLIB_FD_O_EXCL, mode). Note that it fails if the file already exists.
Definition: Platform.h:1739
errno_t nlib_rwlock_tryrdlock(nlib_rwlock *rwlock) NLIB_TRY_ACQUIRE_SHARED(0
Gets the read lock, and attempts to enter the critical section.
static errno_t nlib_memset(void *buf, int ch, size_t n)
Makes a function call corresponding to memset(buf, ch, n).
Definition: Platform.h:3202
NLIB_CHECK_RESULT errno_t nlib_fd_preadv(size_t *result, nlib_fd fd, const nlib_fd_iovec *iov, int iovcnt, nlib_offset offset)
Same as the nlib_fd_readv function except when the pread or nlib_fd_pread function is used internally...
NLIB_CHECK_RESULT void * nlib_calloc(size_t nmemb, size_t size)
A weak function that calls the C standard function calloc. nlib calls calloc via this function...
#define NLIB_ALWAYS_INLINE
Indicates that the compiler is forced to perform inline expansion of functions.
Definition: Platform_unix.h:69
int nlib_wprintf(const wchar_t *fmt,...)
The substitute for the wprintf function.
errno_t nlib_condrwlock_wait_until(nlib_condrwlock *cond, nlib_rwlock *rwlock, nlib_time abstime, int rdlock)
Unlocks rwlock and waits for a conditional variable. It then locks rwlock again after the execution r...
errno_t nlib_strto_double(double *result, const char *nptr, char **endptr)
Converts a string to the double type. For details, see nlib_strto_int32().
int64_t nlib_atomic_fetch_add64(int64_t *ptr, int64_t val, int memorder)
Adds atomic values. Its behavior is similar to the one for __atomic_fetch_add() of gcc...
static errno_t nlib_sleep_timespec(const struct timespec *tm)
A version taking the timespec structure as the argument of nlib_sleep().
Definition: Platform.h:778
const void * nlib_memchr_lt(const void *s, int c, size_t n)
Searches the n bytes from the start of memory region (s, s + n) and returns a pointer to data having ...
struct nlib_rwlock_ nlib_rwlock
The type for a read-write lock object.
Definition: Platform.h:1113
errno_t nlib_vdprintf(nlib_fd fd, size_t *count, const char *fmt, va_list args)
The version of the vsnprintf function that outputs to a file descriptor.
errno_t nlib_cond_signal(nlib_cond *cond)
Resumes the execution of one thread that is waiting for condition variable cond.
errno_t nlib_thread_priority_default(int *priority)
Gets the default numerical value that can be specified for the execution priority.
nlib_mq_msg_destructor destructor
A destructor function for a message taken from a message queue can be set or obtained.
Definition: Platform.h:1400
errno_t nlib_vsnprintf(size_t *count, char *buf, size_t size, const char *fmt, va_list args)
A safer form of vsnprintf, with some differences from standard vsnprintf behavior.
errno_t nlib_mq_close(nlib_mq mq)
Closes the message queue indicated with a handle.
static int nlib_isalpha(int ch)
If ch is an ASCII character &#39;A&#39;-&#39;Z&#39; or &#39;a&#39;-&#39;z&#39;, the function returns non-zero. Othewise, the function returns 0.
Definition: Platform.h:3142
errno_t nlib_thread_getname(nlib_thread thread, char *name, size_t len)
Gets the thread name.
errno_t nlib_wcscpy(wchar_t *s1, size_t s1max, const wchar_t *s2)
An implementation corresponding to N1078 wcscpy_s.
errno_t nlib_ticktime(nlib_duration *t)
Gets the elapsed time since the system was last started.
NLIB_CHECK_RESULT void * nlib_memalign(size_t alignment, size_t size)
A weak function that calls the C standard function memalign. nlib calls memalign via this function...
#define NLIB_FD_O_CREAT
Used for the flags parameter of the nlib_fd_open function.
Definition: Platform.h:1693
NLIB_CHECK_RESULT errno_t nlib_mq_receive(nlib_mq mq, nlib_mq_msg *msg, int *prio)
Receives a message from a queue. It is the user&#39;s responsibility to delete the received messages usin...
errno_t nlib_strto_float(float *result, const char *nptr, char **endptr)
Converts a string to the float type. For details, see nlib_strto_int32().
#define NLIB_NONNULL_1
Indicates that you cannot specify NULL for the first argument.
Definition: Platform_unix.h:77
errno_t nlib_strto_int32(int32_t *result, const char *nptr, char **endptr, int base)
Converts a string to the int32_t type.
Uses a bitwise OR to output levels at and below the specified level. Can be used with the nlib_log_at...
Definition: Platform.h:1633
sem_t nlib_semaphore
The type for a semaphore object.
errno_t nlib_mutex_recursive_timed_init(nlib_mutex *mutex) NLIB_EXCLUDES(*mutex)
Initializes a mutex that is recursive and can time out.
NLIB_CHECK_RESULT errno_t nlib_fd_readv(size_t *result, nlib_fd fd, const nlib_fd_iovec *iov, int iovcnt)
Loads multiple non-continuous buffers from the file associated with fd.
errno_t nlib_mlock(void *addr, size_t len)
The specified memory region is not swapped out.
NLIB_CHECK_RESULT errno_t nlib_semaphore_trywait_for(nlib_semaphore *sem, nlib_duration duration)
Decrements the semaphore count by 1 if the count is not 0. If 0, waits for the period specified by du...
size_t nlib_strnlen(const char *s, size_t maxsize)
An implementation corresponding to N1078 strnlen_s.
errno_t nlib_barrier_destroy(nlib_barrier *barrier)
Destroys a barrier object.
errno_t nlib_mutex_unlock(nlib_mutex *mutex) NLIB_RELEASE(*mutex)
Unlocks the specified mutex.
int nlib_memcmp(const void *buf1, const void *buf2, size_t n)
Compares the n bytes from the starts of buf1 and buf2 as unsigned char data.
nlib_log_priority
Defines the priority (level category) for output.
Definition: Platform.h:1622
#define NLIB_ATOMIC_RELEASE
Similar to __ATOMIC_RELEASE of gcc or std::memory_order_release of C++11.
errno_t nlib_exist_path(int *result, const char *native_path)
Checks whether the path exists.
errno_t nlib_cond_broadcast(nlib_cond *cond)
Resumes the execution of all threads that are waiting for the conditional variable cond...
errno_t nlib_virtual_free(void *ptr, size_t size)
Frees the allocated virtual memory address space.
const void * nlib_memchr_not(const void *s, int c, size_t n)
Searches the n bytes from the start of memory region(s, s + n) and returns a pointer that does not po...
errno_t nlib_thread_setaffinity(nlib_thread thread, uint32_t affinity)
Sets a processor affinity mask for the specified thread.
int32_t nlib_atomic_or_fetch32(int32_t *ptr, int32_t val, int memorder)
Calculates OR of atomic values. Its behavior is similar to the one for __atomic_or_fetch() of gcc...
#define NLIB_CHECK_RESULT
Indicates that the caller of the function must check the returned value.
Definition: Platform_unix.h:74
NLIB_CHECK_RESULT errno_t nlib_dir_open(nlib_dir *dir, const char *native_path)
Opens a directory.
static int nlib_isprint(int ch)
If ch is an ASCII character &#39;32&#39;-&#39;126&#39;, the function returns non-zero. Otherwise, the function return...
Definition: Platform.h:3150
const char * nlib_skipws(size_t *cnt_lf, const char **last_lf, const char *s, size_t n)
Searches a string made up of n characters and returns the pointer to the first character found that i...
errno_t nlib_cond_init(nlib_cond *cond)
Initializes a condition variable.
static int nlib_toupper(int ch)
If ch is an ASCII character &#39;a&#39;-&#39;z&#39;, the function returns its uppercase letter. Otherwise, the function returns ch.
Definition: Platform.h:3163
struct nlib_thread_attr_ nlib_thread_attr
The thread attribute to apply to a newly created thread.
Definition: Platform.h:1448
static int nlib_isxdigit(int ch)
If ch is an ASCII character &#39;0&#39;-&#39;9&#39;, &#39;A&#39;-&#39;F&#39;, or &#39;a&#39;-&#39;f&#39;, the function returns non-zero. Otherwise, the function returns 0.
Definition: Platform.h:3156
static int nlib_popcnt64(uint64_t x)
Returns the number of bits that are 1.
Definition: Platform.h:3218
int64_t nlib_atomic_fetch_sub64(int64_t *ptr, int64_t val, int memorder)
Subtracts atomic values. Its behavior is similar to the one for __atomic_fetch_sub() of gcc...
errno_t nlib_thread_self(nlib_thread *thread)
Stores the nlib_thread value corresponding to the executing thread.
void nlib_thread_cleanup_push(void(*fn)(void *), void *arg)
Pushes fn to a dedicated stack.
Specifies the output of error-level messages.
Definition: Platform.h:1629
#define NLIB_UNLIKELY(x)
Indicates to the compiler that condition x is likely to be false.
Definition: Platform_unix.h:72
void nlib_free_size(void *ptr, size_t size)
Frees memory of a specified size. The default action is to call the nlib_free function.
NLIB_CHECK_RESULT errno_t nlib_mq_receive_until(nlib_mq mq, nlib_mq_msg *msg, int *prio, nlib_time abstime)
Receives a message with a time-out set from a queue. It is the user&#39;s responsibility to delete the re...
NLIB_CHECK_RESULT errno_t nlib_rename(const char *old_path, const char *new_path)
Renames a file.
NLIB_CHECK_RESULT errno_t nlib_fd_getsize(nlib_offset *size, nlib_fd fd)
Gets the file size.
const char * nlib_dirname(size_t *len, const char *path)
errno_t nlib_thread_priority_min(int *priority)
Gets the smallest numerical value that can be specified for the execution priority.
errno_t nlib_rwlock_wrlock(nlib_rwlock *rwlock) NLIB_ACQUIRE(*rwlock)
Gets a write lock, and enters the critical section. Blocks until it can get a lock.
NLIB_CHECK_RESULT errno_t nlib_dir_read(nlib_dirent *ent, nlib_dir dir)
Reads one directory entry, if there are any.
uint32_t nlib_ulong_compatible_t
Defines an integer type that is compatible with unsigned long using typedef.
Definition: Platform.h:617
errno_t nlib_thread_getid(nlib_thread_id *id)
Stores a unique integer value corresponding to the executing thread.
int64_t nlib_atomic_and_fetch64(int64_t *ptr, int64_t val, int memorder)
Calculates AND of atomic values. Its behavior is similar to the one for __atomic_and_fetch() of gcc...
NLIB_CHECK_RESULT errno_t nlib_mq_open(nlib_mq *mq, const nlib_mq_attr *attr)
Creates a message queue to be used to exchange messages across threads.
errno_t nlib_once(nlib_onceflag *flag, nlib_oncefunc func)
Ensures that func is executed only one time at most.
int64_t nlib_time
The type expressing the time in increments of 100 ns from the zero starting point of 1970-01-01...
Definition: Platform.h:744
errno_t nlib_rwlock_destroy(nlib_rwlock *rwlock) NLIB_EXCLUDES(*rwlock)
Destroys a read-write lock object.
errno_t nlib_condrwlock_wait_for(nlib_condrwlock *cond, nlib_rwlock *rwlock, nlib_duration duration, int rdlock)
Unlocks rwlock and waits for a conditional variable. It then locks rwlock again after the execution r...
errno_t nlib_condrwlock_signal(nlib_condrwlock *cond)
Resumes the execution of one thread that is waiting for the read-write lock conditional variable cond...
void nlib_debug_break(void)
A breakpoint.
static errno_t nlib_ticktime_timespec(struct timespec *tm)
A version taking the timespec structure as the argument of nlib_ticktime().
Definition: Platform.h:770
NLIB_CHECK_RESULT errno_t nlib_fd_close(nlib_fd fd)
Closes a file. The file descriptor will be released even if an error is returned. ...
errno_t nlib_thread_attr_setint(nlib_thread_attr *attr, int key, int value)
Sets an integer corresponding to the key of the thread attribute object.
int nlib_atomic_compare_exchange64(int64_t *ptr, int64_t *expected, int64_t desired, int weak, int success_memorder, int failure_memorder)
Compares and swaps atomic values. Its behavior is similar to the one for __atomic_compare_exchange_n(...
static int nlib_clz32(uint32_t x)
Returns the number of consecutive zero bits, with respect to the most significant bit (MSB)...
Definition: Platform.h:3349
errno_t nlib_mutex_init(nlib_mutex *mutex) NLIB_EXCLUDES(*mutex)
Initializes a mutex.
static errno_t nlib_cond_wait_for_timespec(nlib_cond *cond, nlib_mutex *mutex, const struct timespec *tm) NLIB_REQUIRES(*mutex)
A version taking the timespec structure as the argument of nlib_cond_wait_for().
Definition: Platform.h:1088
errno_t nlib_strto_uint32_fallback(uint32_t *result, const char *nptr, char **endptr, int base)
Converts a string to the uint32_t type without using a standard C function. For details, see nlib_strto_int32().
errno_t nlib_tryonce(nlib_onceflag *flag, nlib_oncefunc func)
Basically the same as nlib_once, but returns EBUSY if func is running on another thread.
void(* nlib_oncefunc)(void)
The type for functions to execute with nlib_once.
Definition: Platform.h:1366
errno_t nlib_physical_free(void *ptr, size_t size)
Frees the allocated physical memory.
#define NLIB_ATTRIBUTE_CONST
Defines __attribute__((const)) if it is available for use.
Definition: Platform_unix.h:85
#define NLIB_VIS_PUBLIC
Symbols for functions and classes are made available outside of the library.
Definition: Platform_unix.h:61
void nlib_thread_cleanup_pop(int exec)
Deletes the handler at the top of the stack storing the cleanup handler.
const char * nlib_strchr(const char *s, int c)
Searches for a character from the start of a string.
size_t nlib_memspn(const void *buf, size_t len, const char *set, size_t n)
Returns the length of the set of sub-bytes from the beginning of buf. The set of sub-bytes consists o...
errno_t nlib_tls_setvalue(nlib_tls tls, const void *value)
Stores a value in a TLS slot.
errno_t nlib_thread_getconcurrency(unsigned int *num_cpu)
Gets the number of hardware threads.
static errno_t nlib_epochtime_timespec(struct timespec *tm)
A version taking the timespec structure as the argument of nlib_epochtime().
Definition: Platform.h:762
NLIB_CHECK_RESULT errno_t nlib_mq_drop(nlib_mq mq, nlib_mq_msg *msg, int *prio)
Receives a message with the lowest priority from a queue. It is the user&#39;s responsibility to delete t...
#define NLIB_ATTRIBUTE_PURE
Defines __attribute__((pure)) if it is available for use.
Definition: Platform_unix.h:84
NLIB_CHECK_RESULT errno_t nlib_gen_random(void *buf, size_t size)
Generates a random value of size bytes and stores it in buf.
NLIB_CHECK_RESULT errno_t nlib_remove(const char *native_path)
Deletes a file or directory. Calls nlib_unlink() for a file, or nlib_rmdir() for a directory...
int64_t nlib_atomic_fetch_or64(int64_t *ptr, int64_t val, int memorder)
Calculates OR of atomic values. Its behavior is similar to the one for __atomic_fetch_or() of gcc...
NLIB_CHECK_RESULT errno_t nlib_fd_flush(nlib_fd fd)
Flushes the write to the file descriptor.
int32_t max_msg
When creating a message queue, you can set the maximum number of messages.
Definition: Platform.h:1398
int nlib_log_vprint(int prio, const char *tag, const char *fmt, va_list ap)
Outputs log messages.
errno_t nlib_cond_wait(nlib_cond *cond, nlib_mutex *mutex) NLIB_REQUIRES(*mutex)
Unlocks mutex and waits for a condition variable. It then relocks mutex after execution resumes...
errno_t nlib_strncpy(char *s1, size_t s1max, const char *s2, size_t n)
An implementation corresponding to N1078 strncpy_s.
#define NLIB_ASSUME(cond)
Indicates that cond is true and provides tips for optimizing the compiler.
Definition: Platform.h:581
NLIB_CHECK_RESULT void * nlib_malloc(size_t size)
A weak function that calls the C standard function malloc. nlib calls malloc via this function...
const void * nlib_memchr(const void *s, int c, size_t n)
Searches the n bytes from the start of the memory region (s, s + n) and returns a pointer to byte c...
static errno_t nlib_cond_wait_until_timespec(nlib_cond *cond, nlib_mutex *mutex, const struct timespec *tm) NLIB_REQUIRES(*mutex)
A version taking the timespec structure as the argument of nlib_cond_wait_until().
Definition: Platform.h:1096
errno_t nlib_is_dir(int *result, const char *native_path)
Checks whether the path is for a directory. Sets 0 in *result and returns 0 if no path exists...
#define NLIB_FD_O_WRONLY
Used for the flags parameter of the nlib_fd_open function.
Definition: Platform.h:1672
errno_t nlib_mempagesize(size_t *size)
Gets the page size.
#define NLIB_ATOMIC_ACQUIRE
Similar to __ATOMIC_ACQUIRE of gcc or std::memory_order_acquire of C++11.
errno_t nlib_condrwlock_init(nlib_condrwlock *cond)
Initializes a read-write lock conditional variable.
errno_t nlib_mq_readonly(nlib_mq mq)
Sets the message queue indicated with a handle as receive-only.
NLIB_CHECK_RESULT errno_t nlib_cond_wait_for(nlib_cond *cond, nlib_mutex *mutex, nlib_duration duration) NLIB_REQUIRES(*mutex)
Unlocks mutex and waits for just the duration amount of time for a condition variable. It then relocks mutex after execution resumes.
pthread_key_t nlib_tls
The type for TLS slot IDs.
#define NLIB_NONNULL_2
Indicates that you cannot specify NULL for the second argument.
Definition: Platform_unix.h:78
static errno_t nlib_strto_uint16(uint16_t *result, const char *nptr, char **endptr, int base)
Converts a string to the int16_t type. For details, see nlib_strto_int32().
Definition: Platform.h:3026
errno_t nlib_yield(void)
Relinquishes thread execution rights.
errno_t nlib_debug_backtrace(size_t *result, void **buffer, size_t count)
Stores backtraces in the array specified by buffer.
errno_t nlib_write_stdout(size_t *result, const void *buf, size_t count)
Writes a string to standard output.
NLIB_CHECK_RESULT errno_t nlib_tls_alloc(nlib_tls *tls, nlib_tls_destructor destr)
Allocates a new ID for the specified TLS slot.
int nlib_fd
The original file descriptor of nlib (a 32-bit integer value).
Definition: Platform.h:1728
int32_t nlib_mq
Handle associated with a message queue. If the handle is cleared to zero (using memset()), it will always be an invalid handle.
Definition: Platform.h:1382
errno_t nlib_mutex_lock(nlib_mutex *mutex) NLIB_ACQUIRE(*mutex)
Locks the specified mutex.
void * nlib_atomic_loadptr(void *const *ptr, int memorder)
Loads a value in an atomic operation. Its behavior is similar to the one for __atomic_load_n() of gcc...
int64_t nlib_atomic_exchange64(int64_t *ptr, int64_t val, int memorder)
Swaps values in an atomic operation. Its behavior is similar to the one for __atomic_exchange_n() of ...
NLIB_CHECK_RESULT errno_t nlib_mq_getattr(nlib_mq mq, nlib_mq_attr *attr)
Obtains the attribute set to the message queue indicated with a handle.
Specifies the output of debug-level messages.
Definition: Platform.h:1626
errno_t nlib_strto_int64(int64_t *result, const char *nptr, char **endptr, int base)
Converts a string to the int64_t type. For details, see nlib_strto_int32().
static int nlib_ctz64(uint64_t x)
Returns the number of consecutive zero bits, with respect to the least significant bit (LSB)...
Definition: Platform.h:3352
errno_t nlib_memwide_to_utf8(size_t *to_count, size_t *from_count, char *to, size_t to_size, const wchar_t *from, size_t from_size) NLIB_NONNULL_5
Depending on the size of wchar_t, nlib_memutf16_to_utf8() or nlib_memutf32_to_utf8() is called...
NLIB_CHECK_RESULT errno_t nlib_mkdir(const char *native_path, unsigned int flags)
Creates a directory.
int nlib_printf(const char *fmt,...)
The substitute for the printf function.
errno_t nlib_strto_int32_fallback(int32_t *result, const char *nptr, char **endptr, int base)
Converts a string to the int32_t type without using a standard C function. For details, see nlib_strto_int32().
errno_t nlib_disk_freespace(const char *native_path, uint64_t *free_bytes_available, uint64_t *total_bytes, uint64_t *total_free_bytes)
Gets information related to the capacity of the storage region to which the specified path belongs...
int nlib_getversion(void)
Dynamically gets the nlib version.
static int nlib_popcnt16(uint16_t x)
Returns the number of bits that are 1.
Definition: Platform.h:3212
static errno_t nlib_strto_uint8(uint8_t *result, const char *nptr, char **endptr, int base)
Converts a string to the int8_t type. For details, see nlib_strto_int32().
Definition: Platform.h:3013
static errno_t nlib_condrwlock_wait_for_timespec(nlib_condrwlock *cond, nlib_rwlock *rwlock, const struct timespec *tm, int rdlock)
A version taking the imespec structure as the argument of nlib_condrwlock_wait_for_timespec().
Definition: Platform.h:1302
const void * nlib_memrchr(const void *s, int c, size_t n)
Searches the n bytes from the end of memory region (s, s + n) and returns a pointer to byte c...
int64_t nlib_atomic_sub_fetch64(int64_t *ptr, int64_t val, int memorder)
Subtracts atomic values. Its behavior is similar to the one for __atomic_sub_fetch() of gcc...
#define NLIB_LIKELY(x)
Indicates to the compiler that condition x is likely to be true.
Definition: Platform_unix.h:71
uint32_t nlib_crc32c(uint32_t crc32c, const void *p, size_t n)
This function calculates the CRC-32C checksum value for data.
int nlib_compiler_version(void)
Dynamically obtains the compiler version used to compile nlib.
static errno_t nlib_mutex_trylock_for_timespec(nlib_mutex *mutex, const struct timespec *tm) NLIB_TRY_ACQUIRE(0
A version taking the timespec structure as the argument of nlib_mutex_trylock_for().
errno_t nlib_thread_attr_destroy(nlib_thread_attr *attr)
Destroys a thread-initialization object.
static int nlib_isalnum(int ch)
If ch is an ASCII character &#39;0&#39;-&#39;9&#39;, &#39;A&#39;-&#39;Z&#39;, or &#39;a&#39;-&#39;z&#39;, the function returns non-zero. Otherwise, the function returns 0.
Definition: Platform.h:3139
int32_t nlib_atomic_fetch_xor32(int32_t *ptr, int32_t val, int memorder)
Calculates XOR of atomic values. Its behavior is similar to the one for __atomic_fetch_xor() of gcc...
static errno_t nlib_strto_int8(int8_t *result, const char *nptr, char **endptr, int base)
Converts a string to the int8_t type. For details, see nlib_strto_int32().
Definition: Platform.h:2987
const char * nlib_error_string(errno_t e)
Returns a string literal corresponding to the error value of nlib.
struct nlib_barrier_ nlib_barrier
The type for a barrier object.
Definition: Platform.h:1329
static void nlib_spinlock_init(nlib_spinlock *lock)
Initializes the spinlock.
Definition: Platform.h:2602
errno_t nlib_utf8_to_wide(size_t *wccount, wchar_t *wcstr, size_t buflen, const char *utf8)
Converts a UTF-8 string into a UTF-16/UTF-32 string.
struct nlib_condrwlock_ nlib_condrwlock
Type of the conditional variable for read-write locks.
errno_t nlib_strto_int64_fallback(int64_t *result, const char *nptr, char **endptr, int base)
Converts a string to the int64_t type without using a standard C function. For details, see nlib_strto_int32().
Specifies the output of warning-level messages.
Definition: Platform.h:1628
int32_t nlib_atomic_sub_fetch32(int32_t *ptr, int32_t val, int memorder)
Subtracts atomic values. Its behavior is similar to the one for __atomic_sub_fetch() of gcc...
errno_t nlib_physical_alloc(void *ptr, size_t size, int prot)
Allocates physical memory.
int32_t nlib_atomic_fetch_sub32(int32_t *ptr, int32_t val, int memorder)
Subtracts atomic values. Its behavior is similar to the one for __atomic_fetch_sub() of gcc...
NLIB_CHECK_RESULT errno_t nlib_semaphore_trywait(nlib_semaphore *sem)
Decrements the semaphore count by 1 if the count is not 0.
static errno_t nlib_memcpy(void *s1, size_t s1max, const void *s2, size_t n)
An implementation corresponding to N1078 memcpy_s.
Definition: Platform.h:3170
int32_t nlib_atomic_add_fetch32(int32_t *ptr, int32_t val, int memorder)
Adds atomic values. Its behavior is similar to the one for __atomic_add_fetch() of gcc...
static int nlib_ctz32(uint32_t x)
Returns the number of consecutive zero bits, with respect to the least significant bit (LSB)...
Definition: Platform.h:3350
void nlib_atomic_storeptr(void **ptr, void *val, int memorder)
Stores a value in an atomic operation. Its behavior is similar to the one for __atomic_store_n() of g...
#define NLIB_FD_O_EXCL
Used for the flags parameter of the nlib_fd_open function.
Definition: Platform.h:1707
NLIB_CHECK_RESULT errno_t nlib_mq_send_until(nlib_mq mq, nlib_mq_msg msg, int prio, nlib_time abstime)
Sends a messages with a time-out set to the queue.
static errno_t nlib_condrwlock_wait_until_timespec(nlib_condrwlock *cond, nlib_rwlock *rwlock, const struct timespec *tm, int rdlock)
A version taking the timespec structure as the argument of nlib_condrwlock_wait_until_timespec().
Definition: Platform.h:1311
errno_t nlib_cond_destroy(nlib_cond *cond)
Destroys a condition variable object.
static uint32_t nlib_bitreverse32(uint32_t x)
Reverses the bit order within an entire 32-bit integer.
Definition: Platform.h:3378
errno_t nlib_rwlock_rdlock(nlib_rwlock *rwlock) NLIB_ACQUIRE_SHARED(*rwlock)
Gets the read lock, and enters the critical section. Blocks until it can get a lock.
errno_t nlib_epochtime(nlib_time *t)
Gets the current time.
static uint64_t nlib_bitreverse64(uint64_t x)
Reverses the bit order within an entire 64-bit integer.
Definition: Platform.h:3401
size_t nlib_memcspn(const void *buf, size_t len, const char *set, size_t n)
Returns the length of the set of sub-bytes from the beginning of buf. The set of sub-bytes consists o...
Specifies the output of fatal-level messages.
Definition: Platform.h:1630
static int nlib_isspace(int ch)
If ch is an ASCII character &#39; &#39;, &#39;\t&#39;, or &#39;\n&#39;, the function returns non-zero. Otherwise, the function returns 0.
Definition: Platform.h:3152
errno_t nlib_snwprintf(size_t *count, wchar_t *buf, size_t size, const wchar_t *fmt,...)
A safer form of snwprintf.
errno_t nlib_rwlock_wrunlock(nlib_rwlock *rwlock) NLIB_RELEASE(*rwlock)
Releases a write lock.
static errno_t nlib_spinlock_trylock(nlib_spinlock *lock)
Locks the spinlock. Returns 0 if successful or EBUSY if fails.
Definition: Platform.h:2635
errno_t nlib_thread_attr_getint(const nlib_thread_attr *attr, int key, int *value)
Gets the integer corresponding to the key of the thread attribute object.
static int nlib_isblank(int ch)
If ch is an ASCII character &#39; &#39; or &#39;\t&#39;, the function returns non-zero. Otherwise, the function returns 0.
Definition: Platform.h:3145
void nlib_atomic_thread_fence(int memorder)
Places the specified memory barrier.
Structure to store the settings and current status of a message queue.
Definition: Platform.h:1396
int32_t nlib_atomic_fetch_and32(int32_t *ptr, int32_t val, int memorder)
Calculates AND of atomic values. Its behavior is similar to the one for __atomic_fetch_and() of gcc...
errno_t nlib_dwprintf(nlib_fd fd, size_t *count, const wchar_t *fmt,...)
The version of the snwprintf function that outputs to a file descriptor.
errno_t nlib_write_stderr(size_t *result, const void *buf, size_t count)
Writes a string to standard error output.
errno_t nlib_thread_attr_init(nlib_thread_attr *attr)
Initializes a thread attribute object and sets it to the default.
void(* nlib_thread_func)(void *arg)
A function to be run on a different thread.
Definition: Platform.h:1456
pthread_cond_t nlib_cond
The type for a condition variable object.
errno_t nlib_rwlock_tryrdlock_for(nlib_rwlock *rwlock, nlib_duration duration) NLIB_TRY_ACQUIRE_SHARED(0
Gets the read lock, and attempts to enter the critical section. Times out.
size_t nlib_wcslen(const wchar_t *s)
Makes a call to thewcslen function. In some cases, it may operate as an independent implementation...
errno_t nlib_semaphore_init(nlib_semaphore *sem, int initial_count)
Initializes the semaphore object specified by sem.
errno_t nlib_condrwlock_destroy(nlib_condrwlock *cond)
Destroys a read-write lock conditional variable.
static int nlib_isgraph(int ch)
If ch is an ASCII character &#39;33&#39;-&#39;126&#39;, the function returns non-zero. Otherwise, the function return...
Definition: Platform.h:3148
static int nlib_islower(int ch)
If ch is an ASCII character &#39;a&#39;-&#39;z&#39;, the function returns non-zero. Otherwise, the function returns 0...
Definition: Platform.h:3149
errno_t nlib_rwlock_trywrlock_for(nlib_rwlock *rwlock, nlib_duration duration) NLIB_TRY_ACQUIRE(0
Gets a write lock, and attempts to enter the critical section. Times out.
errno_t nlib_wcsncpy(wchar_t *s1, size_t s1max, const wchar_t *s2, size_t n)
An implementation corresponding to N1078 wcsncpy_s.
errno_t nlib_memutf8_to_wide(size_t *to_count, size_t *from_count, wchar_t *to, size_t to_size, const char *from, size_t from_size) NLIB_NONNULL_5
Depending on the size of wchar_t, nlib_memutf8_to_utf16 or nlib_memutf8_to_utf32 is called...
errno_t nlib_sleep(nlib_duration t)
Sleeps for the duration of t.
errno_t nlib_semaphore_wait(nlib_semaphore *sem)
Waits until the semaphore count is no longer 0 and decrements the semaphore count by 1...
errno_t nlib_getenv(size_t *result, char *buf, size_t bufsize, const char *varname)
Gets the value for the environment variable as a string.
errno_t nlib_strto_uint64(uint64_t *result, const char *nptr, char **endptr, int base)
Converts a string to the uint64_t type. For details, see nlib_strto_int32().
errno_t nlib_rwlock_trywrlock(nlib_rwlock *rwlock) NLIB_TRY_ACQUIRE(0
Gets a write lock, and attempts to enter the critical section.
static int nlib_ispunct(int ch)
If ch is an ASCII character &#39;0&#39;-&#39;32&#39; or &#39;127&#39;, the function returns non-zero. Otherwise, the function returns 0.
Definition: Platform.h:3151
errno_t nlib_thread_attr_getptr(const nlib_thread_attr *attr, int key, void **value)
Gets the pointer corresponding to the key of the thread attribute object. As of now, returns EINVAL only.
NLIB_CHECK_RESULT void * nlib_realloc(void *ptr, size_t size)
A weak function that calls the C standard function realloc. nlib calls realloc via this function...
NLIB_CHECK_RESULT errno_t nlib_mq_send(nlib_mq mq, nlib_mq_msg msg, int prio)
Sends a message to a queue.
NLIB_CHECK_RESULT errno_t nlib_fd_pread(size_t *result, nlib_fd fd, void *buf, size_t count, nlib_offset offset)
Reads the file descriptor from the specified offset. The offset for the file descriptor will not be c...
int32_t nlib_spinlock
Spinlock variable type. Used by statically initializing with NLIB_SPINLOCK_INITIALIZER.
Definition: Platform.h:1435
NLIB_CHECK_RESULT errno_t nlib_memcplen(size_t *codepoint_count, size_t *supplementary_codepoint_count, size_t *from_read, const char *from, size_t from_size)
Gets the number of code points contained in the string and the number of supplementary characters con...
const char * nlib_basename(const char *path)
errno_t nlib_fd_sync(nlib_fd fd)
Synchronizes the content of a file in memory with what is on the device.
errno_t nlib_thread_setpriority(nlib_thread thread, int priority)
Sets the execution priority of the thread. The meaning of the numerical value is implementation-depen...
NLIB_CHECK_RESULT errno_t nlib_mutex_trylock(nlib_mutex *mutex) NLIB_TRY_ACQUIRE(0
Locks mutex, but only if it is not locked.
errno_t nlib_fd_native_handle(void **native_handle, nlib_fd fd)
Gets (the equivalent of) the native file handle.
NLIB_CHECK_RESULT errno_t nlib_fd_read(size_t *result, nlib_fd fd, void *buf, size_t count)
Reads (up to) count bytes from the file descriptor into buf.
errno_t nlib_swapendian_32(uint32_t *p, size_t count)
Swaps the endianness.
size_t nlib_malloc_size(const void *ptr)
Returns the allocated memory size.
#define NLIB_NONNULL_4
Indicates that you cannot specify NULL for the fourth argument.
Definition: Platform_unix.h:80
int nlib_thread_id
A unique integer value for each thread.
Definition: Platform.h:1458
#define NLIB_ATOMIC_RELAXED
Similar to __ATOMIC_RELAXED of gcc or std::memory_order_relaxed of C++11.
errno_t nlib_semaphore_post(nlib_semaphore *sem, int *previous_count)
Increments the semaphore count by 1.
errno_t nlib_rwlock_tryrdlock_until(nlib_rwlock *rwlock, nlib_time abstime) NLIB_TRY_ACQUIRE_SHARED(0
Gets the read lock, and attempts to enter the critical section. Times out.
NLIB_CHECK_RESULT errno_t nlib_fd_pwrite(size_t *result, nlib_fd fd, const void *buf, size_t count, nlib_offset offset)
Writes to the file descriptor at the specified offset. The offset for the file descriptor will not be...
size_t nlib_strlen(const char *s)
Internally calls strlen(). In some cases, it may operate as an independent implementation.
static int nlib_iscntrl(int ch)
If ch is an ASCII code &#39;0&#39;-&#39;31&#39; or &#39;127&#39;, the function returns non-zero. Otherwise, the function returns 0.
Definition: Platform.h:3146
pthread_mutex_t nlib_mutex
The type for mutex variables.
errno_t nlib_condrwlock_broadcast(nlib_condrwlock *cond)
Resumes the execution of all threads that are waiting for the read-write lock conditional variable co...
int nlib_log_print(int prio, const char *tag, const char *fmt,...)
Outputs log messages.
errno_t nlib_thread_join(nlib_thread thread)
Waits for the thread to terminate.
const void * nlib_memchr_range_not(const void *s, const char *range, size_t n)
Searches the n bytes from the start of memory region (s, s + n) and returns a pointer to a character ...
Specifies the output of verbose messages.
Definition: Platform.h:1625
errno_t nlib_snprintf(size_t *count, char *buf, size_t size, const char *fmt,...)
A safer form of snprintf.
Specifies all priority levels. Can be used with the nlib_log_attr_setint function.
Definition: Platform.h:1634
int64_t nlib_atomic_xor_fetch64(int64_t *ptr, int64_t val, int memorder)
Calculates XOR of atomic values. Its behavior is similar to the one for __atomic_xor_fetch() of gcc...
NLIB_CHECK_RESULT errno_t nlib_mutex_trylock_for(nlib_mutex *mutex, nlib_duration delta) NLIB_TRY_ACQUIRE(0
Locks the specified mutex. Times out.
NLIB_CHECK_RESULT errno_t nlib_thread_create(nlib_thread *thread, const nlib_thread_attr *attr, nlib_thread_func func, void *arg)
Creates and executes a new thread.
errno_t nlib_wide_to_utf8(size_t *utf8count, char *utf8, size_t buflen, const wchar_t *wcstr)
Converts a UTF-16/UTF-32 string into a UTF-8 string.
void(* nlib_tls_destructor)(void *tls_value)
The type for the TLS destructor function called when the thread is ended.
Definition: Platform.h:810
Specifies the output of information-level messages.
Definition: Platform.h:1627
errno_t nlib_rwlock_init(nlib_rwlock *rwlock) NLIB_EXCLUDES(*rwlock)
Initializes a read-write lock object.
int64_t nlib_atomic_add_fetch64(int64_t *ptr, int64_t val, int memorder)
Adds atomic values. Its behavior is similar to the one for __atomic_add_fetch() of gcc...
errno_t nlib_thread_setname(nlib_thread thread, const char *name)
Attaches a name to the thread.
errno_t nlib_swapendian_16(uint16_t *p, size_t count)
Swaps the endianness.
uint32_t nlib_crc32(uint32_t crc32, const void *p, size_t n)
This function calculates the CRC-32 checksum value for data.
#define NLIB_NONNULL_5
Indicates that you cannot specify NULL for the fifth argument.
Definition: Platform_unix.h:81
errno_t nlib_thread_detach(nlib_thread thread)
Detaches an executing thread.
errno_t nlib_strto_uint32(uint32_t *result, const char *nptr, char **endptr, int base)
Converts a string to the uint32_t type. For details, see nlib_strto_int32().
NLIB_CHECK_RESULT errno_t nlib_fd_truncate(nlib_fd fd, nlib_offset length)
Extends or truncates the file to be the specified size.
static errno_t nlib_strto_int16(int16_t *result, const char *nptr, char **endptr, int base)
Converts a string to the int16_t type. For details, see nlib_strto_int32().
Definition: Platform.h:3000
const void * nlib_memchr_gt(const void *s, int c, size_t n)
Searches the n bytes from the start of memory region (s, s + n) and returns a pointer to data having ...
int32_t nlib_atomic_and_fetch32(int32_t *ptr, int32_t val, int memorder)
Calculates AND of atomic values. Its behavior is similar to the one for __atomic_and_fetch() of gcc...
int nlib_atomic_compare_exchange32(int32_t *ptr, int32_t *expected, int32_t desired, int weak, int success_memorder, int failure_memorder)
Compares and swaps atomic values. Its behavior is similar to the one for __atomic_compare_exchange_n(...
errno_t nlib_vsnwprintf(size_t *count, wchar_t *buf, size_t size, const wchar_t *fmt, va_list args)
A safer form of vswprintf, with some differences from standard vswprintf behavior.
errno_t nlib_thread_getcpu(int *result)
Gets the CPU on which the called thread is executing.
static const char * nlib_strchr_mb(const char *s)
Searches for a character from the start of a string and then returns either the null character or the...
Definition: Platform.h:2878
errno_t nlib_thread_getpriority(nlib_thread thread, int *priority)
Gets the current execution priority of the thread. The meaning of the numerical value is implementati...
#define NLIB_NONNULL_3
Indicates that you cannot specify NULL for the third argument.
Definition: Platform_unix.h:79
NLIB_CHECK_RESULT errno_t nlib_fd_writev(size_t *result, nlib_fd fd, const nlib_fd_iovec *iov, int iovcnt)
Writes from multiple non-continuous buffers to the file associated with fd.
struct nlib_onceflag_ nlib_onceflag
The structure to use with nlib_once.
Definition: Platform.h:1364
errno_t nlib_thread_attr_setstack(nlib_thread_attr *attr, void *stack_addr, size_t stack_size)
Sets a stack setting for thread attribute objects. Platform Implementation Win32 nlib independent im...
NLIB_CHECK_RESULT errno_t nlib_rmdir(const char *native_path)
Deletes a directory.
size_t nlib_strlcpy(char(&s1)[N], const char *s2) noexcept
Calls the nlib_strlcpy(s1, s2, N) function.
Definition: Config.h:806
errno_t nlib_barrier_init(nlib_barrier *barrier, unsigned int count)
Initializes a barrier object.
void nlib_atomic_store64(int64_t *ptr, int64_t val, int memorder)
Stores a value in an atomic operation. Its behavior is similar to the one for __atomic_store_n() of g...
int64_t nlib_offset
The offset to the file. A 64-bit integer.
Definition: Platform.h:1727
unsigned int nlib_get_native_last_error(void)
Returns the last generated native error code.
void nlib_free(void *ptr)
A weak function that calls the C standard function free. nlib calls free via this function...
errno_t nlib_swapendian_64(uint64_t *p, size_t count)
Swaps the endianness.
static errno_t nlib_rwlock_trywrlock_until_timespec(nlib_rwlock *rwlock, const struct timespec *tm) NLIB_TRY_ACQUIRE(0
A version taking the timespec structure as the argument of nlib_rwlock_trywrlock_until().
errno_t nlib_barrier_wait(nlib_barrier *barrier)
Waits for a thread.
int32_t cur_msg
For a queue other than a lock-free queue, you can obtain the number of messages that are currently in...
Definition: Platform.h:1399
int32_t nlib_long_compatible_t
Defines an integer type that is compatible with long using typedef.
Definition: Platform.h:616
int64_t nlib_atomic_or_fetch64(int64_t *ptr, int64_t val, int memorder)
Calculates OR of atomic values. Its behavior is similar to the one for __atomic_or_fetch() of gcc...
static errno_t nlib_memmove(void *s1, size_t s1max, const void *s2, size_t n)
An implementation corresponding to N1078 memmove_s.
Definition: Platform.h:3188
static errno_t nlib_rwlock_tryrdlock_for_timespec(nlib_rwlock *rwlock, const struct timespec *tm) NLIB_TRY_ACQUIRE_SHARED(0
A version taking the timespec structure as the argument of nlib_rwlock_tryrdlock_for().
size_t nlib_wcsnlen(const wchar_t *s, size_t maxsize)
An implementation corresponding to N1078 wcsnlen_s.
errno_t nlib_thread_attr_setptr(nlib_thread_attr *attr, int key, void *value)
Sets a pointer corresponding to the key of the thread attribute object. As of now, returns EINVAL only.
errno_t nlib_munlock(void *addr, size_t len)
The specified memory region can be swapped out.
static int nlib_popcnt32(uint32_t x)
Returns the number of bits that are 1.
Definition: Platform.h:3215
int32_t nlib_atomic_fetch_or32(int32_t *ptr, int32_t val, int memorder)
Calculates OR of atomic values. Its behavior is similar to the one for __atomic_fetch_or() of gcc...
static errno_t nlib_semaphore_trywait_for_timespec(nlib_semaphore *sem, const struct timespec *tm)
A version taking the timespec structure as the argument of nlib_semaphore_trywait_for().
Definition: Platform.h:980
static void nlib_spinlock_lock(nlib_spinlock *lock)
Locks the spinlock. Behavior is undefined if a recursive lock is performed.
Definition: Platform.h:2605
static errno_t nlib_rwlock_trywrlock_for_timespec(nlib_rwlock *rwlock, const struct timespec *tm) NLIB_TRY_ACQUIRE(0
A version taking the timespec structure as the argument of nlib_rwlock_trywrlock_for().
void(* nlib_mq_msg_destructor)(nlib_mq_msg)
Destructor function for messages taken from a message queue.
Definition: Platform.h:1394
errno_t nlib_tls_getvalue(nlib_tls tls, void **value)
Gets the value from a TLS slot.
NLIB_CHECK_RESULT errno_t nlib_fd_seek(nlib_offset *result, nlib_fd fd, nlib_offset offset, int whence)
Changes the file offset.
errno_t nlib_strcpy(char *s1, size_t s1max, const char *s2)
An implementation corresponding to N1078 strcpy_s.
int64_t nlib_atomic_fetch_xor64(int64_t *ptr, int64_t val, int memorder)
Calculates XOR of atomic values. Its behavior is similar to the one for __atomic_fetch_xor() of gcc...
const void * nlib_memchr_mb(const void *s, size_t n)
Searches the n bytes from the start of memory region (s, s + n) and returns a pointer to the location...
void nlib_thread_exit(void) NLIB_NORETURN
Ends the called thread.
int32_t nlib_atomic_fetch_add32(int32_t *ptr, int32_t val, int memorder)
Adds atomic values. Its behavior is similar to the one for __atomic_fetch_add() of gcc...
#define NLIB_NONNULL
Indicates that you cannot specify NULL for all arguments.
Definition: Platform_unix.h:76
void nlib_atomic_store32(int32_t *ptr, int32_t val, int memorder)
Stores a value in an atomic operation. Its behavior is similar to the one for __atomic_store_n() of g...
int32_t flag
Settings to be used when creating a message queue. Value Description NLIB_MQ_BLOCK When reading an e...
Definition: Platform.h:1397
errno_t nlib_tls_free(nlib_tls tls)
Frees the ID corresponding to the TLS slot.
int32_t nlib_atomic_exchange32(int32_t *ptr, int32_t val, int memorder)
Swaps values in an atomic operation. Its behavior is similar to the one for __atomic_exchange_n() of ...
errno_t nlib_mutex_destroy(nlib_mutex *mutex) NLIB_EXCLUDES(*mutex)
Destroys the specified mutex object and frees any associated resources.
NLIB_CHECK_RESULT errno_t nlib_cond_wait_until(nlib_cond *cond, nlib_mutex *mutex, nlib_time abstime) NLIB_REQUIRES(*mutex)
Unlocks mutex and waits until abstime for a condition variable. It then relocks mutex after execution...
errno_t nlib_semaphore_destroy(nlib_semaphore *sem)
Destroys the semaphore count.
pthread_t nlib_thread
The identifier for threads.
int64_t nlib_duration
The type expressing the time in increments of 100 ns. A 64-bit signed integer.
Definition: Platform.h:746
errno_t nlib_thread_attr_getstack(const nlib_thread_attr *attr, void **stack_addr, size_t *stack_size)
Obtains a stack setting for thread attribute objects.
void * nlib_mq_msg
Type of messages stored in a message queue.
Definition: Platform.h:1388
static int nlib_clz64(uint64_t x)
Returns the number of consecutive zero bits, with respect to the most significant bit (MSB)...
Definition: Platform.h:3351
static errno_t nlib_rwlock_tryrdlock_until_timespec(nlib_rwlock *rwlock, const struct timespec *tm) NLIB_TRY_ACQUIRE_SHARED(0
A version taking the timespec structure as the argument of nlib_rwlock_tryrdlock_until().
errno_t nlib_strto_float_fallback(float *result, const char *nptr, char **endptr)
Converts a string to the float type without using a standard C function. For details, see nlib_strto_int32().
errno_t nlib_mutex_recursive_init(nlib_mutex *mutex) NLIB_EXCLUDES(*mutex)
Initializes a recursive mutex.
int64_t nlib_atomic_load64(const int64_t *ptr, int memorder)
Loads a value in an atomic operation. Its behavior is similar to the one for __atomic_load_n() of gcc...
errno_t nlib_rwlock_trywrlock_until(nlib_rwlock *rwlock, nlib_time abstime) NLIB_TRY_ACQUIRE(0
Gets a write lock, and attempts to enter the critical section. Times out.
NLIB_CHECK_RESULT errno_t nlib_unlink(const char *native_path)
Deletes a file.
NLIB_CHECK_RESULT errno_t nlib_fd_pwritev(size_t *result, nlib_fd fd, const nlib_fd_iovec *iov, int iovcnt, nlib_offset offset)
Same as the nlib_fd_writev function except when the pwrite or nlib_fd_pwrite function is used interna...
errno_t nlib_dprintf(nlib_fd fd, size_t *count, const char *fmt,...)
The version of the snprintf function that outputs to a file descriptor.
errno_t nlib_fd_open(nlib_fd *fd, const char *native_path, unsigned int flags, int mode)
Opens a file.
static int nlib_tolower(int ch)
If ch is an ASCII character &#39;A&#39;-&#39;Z&#39;, the function returns its lowercase letter. Otherwise, the function returns ch.
Definition: Platform.h:3160
static int nlib_isdigit(int ch)
If ch is an ASCII character &#39;0&#39;-&#39;9&#39;, the function returns non-zero. Otherwise, the function returns 0...
Definition: Platform.h:3147
int errno_t
Indicates with an int-type typedef that a POSIX error value is returned as the return value...
Definition: NMalloc.h:24