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