nlib
Platform.h
Go to the documentation of this file.
1 
2 /*--------------------------------------------------------------------------------*
3  Project: CrossRoad
4  Copyright (C)Nintendo All rights reserved.
5 
6  These coded instructions, statements, and computer programs contain proprietary
7  information of Nintendo and/or its licensed developers and are protected by
8  national and international copyright laws. They may not be disclosed to third
9  parties or copied or duplicated in any form, in whole or in part, without the
10  prior written consent of Nintendo.
11 
12  The content herein is highly confidential and should be handled accordingly.
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 2017
25 #define NLIB_VERSION_YEAR_SHORT 17
26 #define NLIB_VERSION_DATE 0926
27 #define NLIB_VERSION 20170926
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 __has_builtin
44 # define __has_builtin(x) 0
45 #endif
46 
47 #ifndef __has_feature
48 # define __has_feature(x) 0
49 #endif
50 
51 #ifndef __has_cpp_attribute
52 # define __has_cpp_attribute(x) 0
53 #endif
54 
55 #ifndef __has_attribute
56 # define __has_attribute(x) 0
57 #endif
58 
59 #ifndef __has_declspec_attribute
60 # define __has_declspec_attribute(x) 0
61 #endif
62 
63 #ifndef __has_include
64 # define __has_include(x) 0
65 #endif
66 
67 #if __has_feature(thread_sanitizer)
68 # define NLIB_NO_TSAN __attribute__((no_sanitize("thread")))
69 #else
70 # define NLIB_NO_TSAN
71 #endif
72 
73 #if __has_feature(address_sanitizer)
74 # define NLIB_NO_ASAN __attribute__((no_sanitize("address")))
75 #else
76 # define NLIB_NO_ASAN
77 #endif
78 
79 #if __has_feature(memory_sanitizer)
80 # define NLIB_NO_MSAN __attribute__((no_sanitize("memory")))
81 #else
82 # define NLIB_NO_MSAN
83 #endif
84 
85 #ifndef NLIB_UNUSED
86 // #if defined(__cplusplus) && __has_cpp_attribute(maybe_unused)
87 // # define NLIB_UNUSED(x) [[maybe_unused]]
88 // #else
89 # define NLIB_UNUSED(x) (void)(x)
90 // #endif
91 #endif
92 
93 //
94 // thread safety analysis
95 // http://clang.llvm.org/docs/ThreadSafetyAnalysis.html
96 //
97 #if !defined(NLIB_THREAD_AA_) && defined(__clang__) && \
98  (!defined(SWIG)) && __has_attribute(capability)
99 #define NLIB_THREAD_AA_(x) __attribute__((x))
100 #else
101 #ifdef NLIB_THREAD_AA_
102 #undef NLIB_THREAD_AA_
103 #endif
104 #define NLIB_THREAD_AA_(x)
105 #endif
106 
107 #define NLIB_CAPABILITY(x) NLIB_THREAD_AA_(capability(x))
108 #define NLIB_SCOPED_CAPABILITY NLIB_THREAD_AA_(scoped_lockable)
109 #define NLIB_GUARDED_BY(x) NLIB_THREAD_AA_(guarded_by(x))
110 #define NLIB_PT_GUARDED_BY(x) NLIB_THREAD_AA_(pt_guarded_by(x))
111 #define NLIB_ACQUIRED_BEFORE(...) NLIB_THREAD_AA_(acquired_before(__VA_ARGS__))
112 #define NLIB_ACQUIRED_AFTER(...) NLIB_THREAD_AA_(acquired_after(__VA_ARGS__))
113 #define NLIB_REQUIRES(...) NLIB_THREAD_AA_(requires_capability(__VA_ARGS__))
114 #define NLIB_REQUIRES_SHARED(...) NLIB_THREAD_AA_(requires_shared_capability(__VA_ARGS__))
115 #define NLIB_ACQUIRE(...) NLIB_THREAD_AA_(acquire_capability(__VA_ARGS__))
116 #define NLIB_ACQUIRE_SHARED(...) NLIB_THREAD_AA_(acquire_shared_capability(__VA_ARGS__))
117 #define NLIB_RELEASE(...) NLIB_THREAD_AA_(release_capability(__VA_ARGS__))
118 #define NLIB_RELEASE_SHARED(...) NLIB_THREAD_AA_(release_shared_capability(__VA_ARGS__))
119 #define NLIB_TRY_ACQUIRE(...) NLIB_THREAD_AA_(try_acquire_capability(__VA_ARGS__))
120 #define NLIB_TRY_ACQUIRE_SHARED(...) NLIB_THREAD_AA_(try_acquire_shared_capability(__VA_ARGS__))
121 #define NLIB_EXCLUDES(...) NLIB_THREAD_AA_(locks_excluded(__VA_ARGS__))
122 #define NLIB_ASSERT_CAPABILITY(x) NLIB_THREAD_AA_(assert_capability(x))
123 #define NLIB_ASSERT_SHARED_CAPABILITY(x) NLIB_THREAD_AA_(assert_shared_capability(x))
124 #define NLIB_RETURN_CAPABILITY(x) NLIB_THREAD_AA_(lock_returned(x))
125 #define NLIB_NO_THREAD_SAFETY_ANALYSIS NLIB_THREAD_AA_(no_thread_safety_analysis)
126 
127 #include <stddef.h> // for size_t
128 #include <stdio.h> // for SEEK_CUR, SEEK_END, SEEK_SET
129 #include <stdarg.h> // for va_list
130 #include <string.h> // for memcpy, memmove, memset
131 #include <time.h> // for struct timespec
132 #if (defined(__cplusplus) && __cplusplus >= 201703L) || \
133  (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
134 #include <cstddef> // for std::byte
135 #endif
136 
137 #if defined(NLIB_RENAME_CAPI)
138 #include "nn/nlib/Platform_rename.h"
139 #else
140 #ifdef NLIB_CAPI
141 #undef NLIB_CAPI
142 #endif
143 #define NLIB_CAPI(x) x
144 #endif
145 
146 #define NLIB_STRINGIFY_(s) #s
147 #define NLIB_STRINGIFY(s) NLIB_STRINGIFY_(s)
148 
149 #if defined(_MSC_VER)
150 # include "nn/nlib/Platform_win32.h"
151 #elif defined(__linux__) || \
152  defined(__FreeBSD__) || \
153  defined(__CYGWIN__) || \
154  (defined(__APPLE__) && defined(__MACH__))
155 # ifndef NLIB_UNIX
156 # define NLIB_UNIX
157 # endif
158 # include "nn/nlib/Platform_unix.h"
159 #elif defined(NN_PLATFORM_CTR)
160 # include "nn/nlib/Platform_ctr.h"
161 #elif defined(CAFE)
162 # include "nn/nlib/Platform_cafe.h"
163 #elif defined(__NX__)
164 # include "nn/nlib/Platform_nx.h"
165 #endif
166 
167 #if defined(_MSC_VER) && defined(n_EXPORTS)
168 #undef NLIB_VIS_PUBLIC
169 #define NLIB_VIS_PUBLIC NLIB_WINEXPORT
170 #endif
171 
172 #ifndef __analysis_assume
173 # define __analysis_assume(expr)
174 #endif
175 
176 #ifndef _Printf_format_string_
177 # define _Printf_format_string_
178 #endif
179 
180 #if defined(__ARM_NEON__) || defined(__aarch64__)
181 # ifndef NLIB_NEON
182 # define NLIB_NEON
183 # endif
184 #endif
185 
186 #ifdef __SSE4_1__
187 # ifndef NLIB_SSE41
188 # define NLIB_SSE41
189 # endif
190 #endif
191 
192 #ifdef __SSE4_2__
193 # ifndef NLIB_SSE41
194 # define NLIB_SSE41
195 # endif
196 # ifndef NLIB_SSE42
197 # define NLIB_SSE42
198 # endif
199 #endif
200 
201 #if defined(NLIB_SSE41) || defined(NLIB_NEON)
202 # define NLIB_SIMD
203 # ifdef NLIB_NEON
204 # include <arm_neon.h> // NOLINT
205 # endif
206 # ifdef NLIB_SSE41
207 # include <smmintrin.h> // NOLINT
208 # endif
209 # ifdef NLIB_SSE42
210 # include <nmmintrin.h> // NOLINT
211 # endif
212 #endif
213 
214 #if defined(__ARM_ACLE)
215 #include <arm_acle.h>
216 #endif
217 
218 // https://www.jpcert.or.jp/sc-rules/c-int01-c.html
219 // 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
220 #ifndef RSIZE_MAX
221 # ifndef NLIB_64BIT
222 # define RSIZE_MAX 0x7FFFFFFFL
223 # else
224 # define RSIZE_MAX 0x7FFFFFFFFFFFFFFFLL
225 # endif
226 #endif
227 
228 #ifndef NLIB_WARN
229 # define NLIB_WARN(exp) ("WARNING: " exp)
230 // #pragma message NLIB_WARN("your message")
231 #endif
232 
233 // NOTE:
234 // You can use those macros on the environment which printf does not support '%z'
235 // for size_t.
236 // "%"PRIuS, sizet_val
237 // See: https://google-styleguide.googlecode.com/svn/trunk/cppguide.html#64-bit_Portability
238 // In Japanese: http://www.textdrop.net/google-styleguide-ja/cppguide.xml
239 #ifndef __PRIS_PREFIX
240 # define __PRIS_PREFIX "z"
241 #endif
242 
243 #ifndef PRIdS
244 # define PRIdS __PRIS_PREFIX "d"
245 #endif
246 
247 #ifndef PRIxS
248 # define PRIxS __PRIS_PREFIX "x"
249 #endif
250 
251 #ifndef PRIuS
252 # define PRIuS __PRIS_PREFIX "u"
253 #endif
254 
255 #ifndef PRIXS
256 # define PRIXS __PRIS_PREFIX "X"
257 #endif
258 
259 #ifndef PRIoS
260 # define PRIoS __PRIS_PREFIX "o"
261 #endif
262 
263 #ifndef NLIB_ASSUME
264 # define NLIB_ASSUME(cond) switch (0) case 0: default: if (cond) ; else __builtin_unreachable() /* NOLINT */
265 #endif
266 
267 #ifdef NLIB_NONNULL_ENABLED
268 # define NLIB_EINVAL_IFNULL(p)
269 #else
270 # define NLIB_EINVAL_IFNULL(p) if (!p) return EINVAL
271 #endif
272 
273 #ifndef NLIB_C_INLINE
274 # define NLIB_C_INLINE __inline
275 #endif
276 
277 //
278 // Error Type
279 //
280 typedef int errno_t; // TR 24731-1
281 
282 //
283 // stdint
284 //
285 #include <stdint.h> // NOLINT
286 #include <inttypes.h> // NOLINT
287 
288 #ifdef __cplusplus
289 #ifdef __cpp_unicode_characters
290 typedef char16_t nlib_utf16_t;
291 typedef char32_t nlib_utf32_t;
292 #else
293 typedef uint16_t nlib_utf16_t;
294 typedef uint32_t nlib_utf32_t;
295 #endif
296 #else
297 // On some devenv, char16_t, char32_t not typedefed in uchar.h
298 // #if __has_include( <uchar.h> )
299 // #include <uchar.h>
300 // typedef char16_t nlib_utf16_t;
301 // typedef char32_t nlib_utf32_t;
302 // #else
303 typedef uint16_t nlib_utf16_t;
304 typedef uint32_t nlib_utf32_t;
305 // #endif
306 #endif
307 
308 typedef char nlib_utf8_t;
309 
310 #if defined(__cplusplus) && !defined(NLIB_DOXYGEN)
311 #if __cplusplus >= 201703L || (defined(_HAS_STD_BYTE) && _HAS_STD_BYTE != 0)
312 typedef ::std::byte nlib_byte_t;
313 #elif __cplusplus >= 201103L || defined(_MSC_VER)
314 enum class nlib_byte_t : unsigned char {};
315 #else
316 typedef unsigned char nlib_byte_t;
317 #endif
318 #else
319 typedef unsigned char nlib_byte_t;
320 #endif
321 
322 #if defined(__LP64__) && __LP64__ == 1
323 // if long, unsinged long are 64 bits long
324 #define NLIB_LP64
325 typedef int64_t nlib_long_compatible_t;
326 typedef uint64_t nlib_ulong_compatible_t;
327 #else
328 typedef int32_t nlib_long_compatible_t;
329 typedef uint32_t nlib_ulong_compatible_t;
330 #endif
331 
332 #ifndef NLIB_VIS_PUBLIC_ALT
333 #define NLIB_VIS_PUBLIC_ALT NLIB_VIS_PUBLIC
334 #endif
335 
336 #ifndef NLIB_EXPIMP_TEMPLATE
337 # define NLIB_EXPIMP_TEMPLATE(x) NLIB_STATIC_ASSERT(sizeof(char) == 1)
338 #endif
339 
340 #ifdef __cplusplus
341 extern "C" {
342 #endif
343 
345 
346 //
347 // Native error
348 //
350 
351 //
352 // Version
353 //
354 
355 // returns NLIB_VERSION
358 
359 // crc32 = 0 at the beginning
360 NLIB_VIS_PUBLIC uint32_t nlib_crc32(uint32_t crc32, const void* p, size_t n);
361 // crc32 = 0 at the beginning
362 NLIB_VIS_PUBLIC uint32_t nlib_crc32c(uint32_t crc32c, const void* p, size_t n);
363 
364 //
365 // Atomic
366 //
367 #if defined(__INTELLISENSE__)
368 #define NLIB_ATOMIC_RELAXED (0)
369 #define NLIB_ATOMIC_ACQUIRE (1)
370 #define NLIB_ATOMIC_RELEASE (2)
371 #define NLIB_ATOMIC_ACQ_REL (3)
372 #define NLIB_ATOMIC_SEQ_CST (7)
373 
374 int32_t nlib_atomic_load32(const int32_t* ptr, int memorder);
375 void nlib_atomic_store32(int32_t* ptr, int32_t val, int memorder);
376 // *target = value, and returns the old value of *target
377 int32_t nlib_atomic_exchange32(int32_t* ptr,
378  int32_t val, int memorder);
379 // *ptr = desired and return non-zero if successful
380 int nlib_atomic_compare_exchange32(int32_t* ptr,
381  int32_t* expected,
382  int32_t desired,
383  int weak,
384  int success_memorder,
385  int failure_memorder);
386 // *ptr += val; return *ptr;
387 int32_t nlib_atomic_add_fetch32(int32_t* ptr, int32_t val, int memorder);
388 // *ptr -= val; return *ptr;
389 int32_t nlib_atomic_sub_fetch32(int32_t* ptr, int32_t val, int memorder);
390 // *ptr &= val; return *ptr;
391 int32_t nlib_atomic_and_fetch32(int32_t* ptr, int32_t val, int memorder);
392 // *ptr ^= val; return *ptr;
393 int32_t nlib_atomic_xor_fetch32(int32_t* ptr, int32_t val, int memorder);
394 // *ptr |= val; return *ptr;
395 int32_t nlib_atomic_or_fetch32(int32_t* ptr, int32_t val, int memorder);
396 // tmp = *ptr; *ptr += val; return tmp;
397 int32_t nlib_atomic_fetch_add32(int32_t* ptr, int32_t val, int memorder);
398 // tmp = *ptr; *ptr -= val; return tmp;
399 int32_t nlib_atomic_fetch_sub32(int32_t* ptr, int32_t val, int memorder);
400 // tmp = *ptr; *ptr &= val; return tmp;
401 int32_t nlib_atomic_fetch_and32(int32_t* ptr, int32_t val, int memorder);
402 // tmp = *ptr; *ptr ^= val; return tmp;
403 int32_t nlib_atomic_fetch_xor32(int32_t* ptr, int32_t val, int memorder);
404 // tmp = *ptr; *ptr |= val; return tmp;
405 int32_t nlib_atomic_fetch_or32(int32_t* ptr, int32_t val, int memorder);
406 
407 int64_t nlib_atomic_load64(const int64_t* ptr, int memorder);
408 void nlib_atomic_store64(int64_t* ptr, int64_t val, int memorder);
409 // *target = value, and returns the old value of *target
410 int64_t nlib_atomic_exchange64(int64_t* ptr, int64_t val, int memorder);
411 // *ptr = desired and return non-zero if successful
412 int nlib_atomic_compare_exchange64(int64_t* ptr, int64_t* expected,
413  int64_t desired, int weak,
414  int success_memorder, int failure_memorder);
415 // *ptr += val; return *ptr;
416 int64_t nlib_atomic_add_fetch64(int64_t* ptr, int64_t val, int memorder);
417 // *ptr -= val; return *ptr;
418 int64_t nlib_atomic_sub_fetch64(int64_t* ptr, int64_t val, int memorder);
419 // *ptr &= val; return *ptr;
420 int64_t nlib_atomic_and_fetch64(int64_t* ptr, int64_t val, int memorder);
421 // *ptr ^= val; return *ptr;
422 int64_t nlib_atomic_xor_fetch64(int64_t* ptr, int64_t val, int memorder);
423 // *ptr |= val; return *ptr;
424 int64_t nlib_atomic_or_fetch64(int64_t* ptr, int64_t val, int memorder);
425 // tmp = *ptr; *ptr += val; return tmp;
426 int64_t nlib_atomic_fetch_add64(int64_t* ptr, int64_t val, int memorder);
427 // tmp = *ptr; *ptr -= val; return tmp;
428 int64_t nlib_atomic_fetch_sub64(int64_t* ptr, int64_t val, int memorder);
429 // tmp = *ptr; *ptr &= val; return tmp;
430 int64_t nlib_atomic_fetch_and64(int64_t* ptr, int64_t val, int memorder);
431 // tmp = *ptr; *ptr ^= val; return tmp;
432 int64_t nlib_atomic_fetch_xor64(int64_t* ptr, int64_t val, int memorder);
433 // tmp = *ptr; *ptr |= val; return tmp;
434 int64_t nlib_atomic_fetch_or64(int64_t* ptr, int64_t val, int memorder);
435 
436 void* nlib_atomic_loadptr(void* const* ptr, int memorder);
437 void nlib_atomic_storeptr(void** ptr, void* val, int memorder);
438 void* nlib_atomic_exchangeptr(void** ptr, void* val, int memorder);
439 // *ptr = desired and return non-zero if successful
440 int nlib_atomic_compare_exchangeptr(void** ptr, void** expected, void* desired,
441  int weak, int success_memorder, int failure_memorder);
442 
443 void nlib_atomic_thread_fence(int memorder);
444 #endif
445 
446 //
447 // Time, Duration
448 //
449 #ifndef NLIB_TIMESPEC_HAS_NATIVE
450 struct timespec {
451  time_t tv_sec;
452  long tv_nsec; // NOLINT
453 };
454 #endif
455 
456 // 100ns => 1, 1970/01/01 == 0
457 typedef int64_t nlib_time;
458 // 100ns => 1, 1ms => 10000
459 typedef int64_t nlib_duration;
460 
461 // 100ns => 1, 1970/01/01 == 0
463 // 100ns => 1, boot time == 0, msec = *t / 10000
465 // 100ns => 1, sleep 1 msec = nlib_sleep(10000)
466 NLIB_VIS_PUBLIC errno_t nlib_sleep(nlib_duration t);
467 
468 #define NLIB_TO_TIMESPEC(tm, t) \
469  (tm)->tv_sec = (time_t)((t) / (1000 * 10000)); \
470  (tm)->tv_nsec = ((long)((t) % (1000 * 10000)) * 100) // NOLINT
471 
472 #define NLIB_FROM_TIMESPEC(tm, t) \
473  (t) = (nlib_time)((tm)->tv_sec) * (1000 * 10000) + ((tm)->tv_nsec / 100)
474 
475 #define NLIB_TO_SEC_NSEC(sec, nsec, t) \
476  (sec) = (int64_t)((t) / (1000 * 10000)); \
477  (nsec) = ((uint32_t)((t) % (1000 * 10000)) * 100)
478 
479 #define NLIB_FROM_SEC_NSEC(sec, nsec, t) \
480  (t) = (nlib_time)(sec) * (1000 * 10000) + ((nsec) / 100)
481 
482 static NLIB_C_INLINE errno_t nlib_epochtime_timespec(struct timespec* tm) {
483  nlib_time t;
484  errno_t e = nlib_epochtime(&t);
485  if (NLIB_UNLIKELY(e != 0)) return e;
486  NLIB_TO_TIMESPEC(tm, t);
487  return 0;
488 }
489 
490 static NLIB_C_INLINE errno_t nlib_ticktime_timespec(struct timespec* tm) {
491  nlib_duration d;
492  errno_t e = nlib_ticktime(&d);
493  if (NLIB_UNLIKELY(e != 0)) return e;
494  NLIB_TO_TIMESPEC(tm, d);
495  return 0;
496 }
497 
498 static NLIB_C_INLINE errno_t nlib_sleep_timespec(const struct timespec* tm) {
499  nlib_duration d;
500  NLIB_FROM_TIMESPEC(tm, d);
501  return nlib_sleep(d);
502 }
503 
504 #if !defined(NLIB_TIMER_HAS_NATIVE)
505 typedef uint32_t nlib_timer;
506 #elif defined(_MSC_VER)
507 typedef HANDLE nlib_timer;
508 #elif defined(__linux__)
509 typedef int nlib_timer;
510 #else
511 # error sorry
512 #endif
513 typedef void (*nlib_timer_callback)(nlib_timer timer, void* param);
514 struct nlib_timerspec_ {
515  nlib_duration due_time;
516  nlib_duration interval;
517 };
518 typedef struct nlib_timerspec_ nlib_timerspec;
519 #ifdef NLIB_DOXYGEN
520 struct nlib_timerspec {
521  nlib_duration due_time;
522  nlib_duration interval;
523 };
524 #endif
526  void* param, uint32_t flags);
527 NLIB_VIS_PUBLIC errno_t nlib_timer_settime(nlib_timer timer, const nlib_timerspec* new_value,
528  nlib_timerspec* old_value);
529 NLIB_VIS_PUBLIC errno_t nlib_timer_gettime(nlib_timer timer, nlib_timerspec* curr_value);
530 NLIB_VIS_PUBLIC errno_t nlib_timer_delete(nlib_timer timer,
531  int wait_completion,
532  nlib_timer_callback completion_callback);
533 #define NLIB_TIMER_SHORTTERM_TASK 0x00000001
534 #define NLIB_TIMER_LONGTERM_TASK 0x00000002
535 
536 //
537 // Random
538 //
539 
540 // Store 'size' bytes of random values on 'buf'
542 
543 //
544 // Virtual Memory, Physical Memory
545 //
547 NLIB_VIS_PUBLIC errno_t nlib_virtual_alloc(void** ptr, size_t size) NLIB_NONNULL;
548 NLIB_VIS_PUBLIC errno_t nlib_virtual_free(void* ptr, size_t size) NLIB_NONNULL;
549 NLIB_VIS_PUBLIC errno_t nlib_physical_alloc(void* ptr, size_t size, int prot) NLIB_NONNULL;
551 NLIB_VIS_PUBLIC errno_t nlib_mlock(void* addr, size_t len) NLIB_NONNULL;
552 NLIB_VIS_PUBLIC errno_t nlib_munlock(void* addr, size_t len) NLIB_NONNULL;
553 
554 #define NLIB_PHYSICAL_ALLOC_PROT_NONE 0
555 #define NLIB_PHYSICAL_ALLOC_PROT_READ 1
556 #define NLIB_PHYSICAL_ALLOC_PROT_WRITE 2
557 #define NLIB_PHYSICAL_ALLOC_PROT_EXEC 4
558 
559 //
560 // TLS
561 //
562 typedef void (*nlib_tls_destructor)(void* tls_value);
563 #define NLIB_TLS_INVALID (nlib_tls)(-1)
564 
566 #ifdef NLIB_PTHREAD_nlib_tls_alloc
567 static
568 #else
570 #endif
571 // code snippets:
572 // # map tls_key on thread local storage
573 // nlib_tls tls_key;
574 // e = nlib_tls_alloc(&tls_key, NULL); # no dtor invoked if destr is NULL
575 // if (e != 0) { error ... }
576 // # unmap tls_key
577 // nlib_tls_free(tls_key);
578 // # access from a thread
579 // void* thread_local_value;
580 // nlib_tls_getvalue(tls_key, &thread_local_value);
581 // # use and update thread_local_value
582 // nlib_tls_setvalue(tls_key, thread_local_value);
584 #ifdef NLIB_PTHREAD_nlib_tls_alloc
585 static NLIB_C_INLINE errno_t nlib_tls_alloc(nlib_tls* tls, nlib_tls_destructor destr) {
586 #ifndef __NX__
587  return pthread_key_create(tls, destr);
588 #else
589  errno_t e = pthread_key_create(tls, destr);
590  if (e == 0) {
591  // NINTENDOSDK-5089 workaround
592  (void)pthread_setspecific(*tls, NULL);
593  }
594  return e;
595 #endif
596 }
597 #endif
598 #ifdef NLIB_PTHREAD_nlib_tls_free
599 static NLIB_C_INLINE errno_t nlib_tls_free(nlib_tls tls) {
600  return pthread_key_delete(tls);
601 }
602 #else
604 #endif
605 #ifdef NLIB_PTHREAD_nlib_tls_setvalue
606 static
607 #else
609 #endif
610 errno_t nlib_tls_setvalue(nlib_tls tls, const void* value);
611 #ifdef NLIB_PTHREAD_nlib_tls_setvalue
612 static NLIB_C_INLINE errno_t nlib_tls_setvalue(nlib_tls tls, const void* value) {
613  return pthread_setspecific(tls, value);
614 }
615 #endif
616 
617 #ifdef NLIB_PTHREAD_nlib_tls_getvalue
618 static
619 #else
621 #endif
622 
624 #ifdef NLIB_PTHREAD_nlib_tls_getvalue
625 static NLIB_C_INLINE errno_t nlib_tls_getvalue(nlib_tls tls, void** value) {
626  *value = pthread_getspecific(tls);
627  return 0;
628 }
629 #endif
630 
631 //
632 // Mutex
633 //
634 
635 #ifdef NLIB_PTHREAD_nlib_mutex_init
636 static
637 #else
639 #endif
640 
641 // you can use NLIB_MUTEX_INITIALIZER static initializer
642 errno_t nlib_mutex_init(nlib_mutex* mutex) NLIB_NONNULL NLIB_EXCLUDES(*mutex);
643 #ifdef NLIB_PTHREAD_nlib_mutex_init
644 static NLIB_C_INLINE errno_t nlib_mutex_init(nlib_mutex* mutex) NLIB_NO_THREAD_SAFETY_ANALYSIS {
645  return pthread_mutex_init(mutex, NULL);
646 }
647 #endif
648 
649 // you can use NLIB_RECURSIVE_MUTEX_INITIALIZER static initializer
651  NLIB_NONNULL NLIB_EXCLUDES(*mutex);
652 // you can use NLIB_RECURSIVE_TIMED_MUTEX_INITIALIZER static initializer
654  NLIB_NONNULL NLIB_EXCLUDES(*mutex);
655 
656 #ifdef NLIB_PTHREAD_nlib_mutex_lock
657 static
658 #else
660 #endif
661 // code snippets:
662 // nlib_mutex m;
663 // if (nlib_mutex_init(&m) != 0) { ... } # always returns 0 on almost all platforms?
664 // nlib_mutex_lock(&m);
665 // ....
666 // nlib_mutex_unlock(&m);
667 // nlib_mutex_destroy(&m);
668 errno_t nlib_mutex_lock(nlib_mutex* mutex) NLIB_NONNULL NLIB_ACQUIRE(*mutex);
669 #ifdef NLIB_PTHREAD_nlib_mutex_lock
670 static NLIB_C_INLINE errno_t nlib_mutex_lock(nlib_mutex* mutex) NLIB_NO_THREAD_SAFETY_ANALYSIS {
671  return pthread_mutex_lock(mutex);
672 }
673 #endif
674 
675 // returns EBUSY if a lock cannot be acquired
677 #ifdef NLIB_PTHREAD_nlib_mutex_trylock
678 static
679 #else
681 #endif
682 errno_t nlib_mutex_trylock(nlib_mutex* mutex) NLIB_NONNULL NLIB_TRY_ACQUIRE(0, *mutex);
683 #ifdef NLIB_PTHREAD_nlib_mutex_trylock
684 static NLIB_C_INLINE errno_t nlib_mutex_trylock(nlib_mutex* mutex) NLIB_TRY_ACQUIRE(0, *mutex) {
685  return pthread_mutex_trylock(mutex);
686 }
687 #endif
688 // returns ETIMEDOUT if timeout
691  nlib_duration delta) NLIB_NONNULL NLIB_TRY_ACQUIRE(0, *mutex);
692 #ifdef NLIB_PTHREAD_nlib_mutex_unlock
693 static
694 #else
696 #endif
697 errno_t nlib_mutex_unlock(nlib_mutex* mutex) NLIB_NONNULL NLIB_RELEASE(*mutex);
698 #ifdef NLIB_PTHREAD_nlib_mutex_unlock
699 static NLIB_C_INLINE errno_t nlib_mutex_unlock(nlib_mutex* mutex) NLIB_NO_THREAD_SAFETY_ANALYSIS {
700  return pthread_mutex_unlock(mutex);
701 }
702 #endif
703 
704 #ifdef NLIB_PTHREAD_nlib_mutex_destroy
705 static
706 #else
708 #endif
709 // don't forget to write this, some platforms require this called.
710 errno_t nlib_mutex_destroy(nlib_mutex* mutex) NLIB_NONNULL NLIB_EXCLUDES(*mutex);
711 #ifdef NLIB_PTHREAD_nlib_mutex_destroy
712 static NLIB_C_INLINE errno_t nlib_mutex_destroy(nlib_mutex* mutex) NLIB_NO_THREAD_SAFETY_ANALYSIS {
713  return pthread_mutex_destroy(mutex);
714 }
715 #endif
716 
717 static NLIB_C_INLINE errno_t nlib_mutex_trylock_for_timespec(nlib_mutex* mutex,
718  const struct timespec* tm)
719  NLIB_TRY_ACQUIRE(0, *mutex) {
720  nlib_duration delta;
721  NLIB_FROM_TIMESPEC(tm, delta);
722  return nlib_mutex_trylock_for(mutex, delta);
723 }
724 
725 //
726 // Semaphore
727 //
728 
731 // returns EAGAIN if semaphore cannot be acquired
733 // returns ETIMEDOUT if timeout
735  nlib_semaphore* sem, nlib_duration duration) NLIB_NONNULL;
737  int* __restrict previous_count) NLIB_NONNULL_1;
738 NLIB_VIS_PUBLIC errno_t nlib_semaphore_post_ex(nlib_semaphore* __restrict sem, int release_count,
739  int* __restrict previous_count) NLIB_NONNULL_1;
741 
743  nlib_semaphore* sem, const struct timespec* tm) {
744  nlib_duration duration;
745  NLIB_FROM_TIMESPEC(tm, duration);
746  return nlib_semaphore_trywait_for(sem, duration);
747 }
748 
749 //
750 // Condition Variable
751 //
752 
753 #ifdef NLIB_PTHREAD_nlib_cond_init
754 static
755 #else
757 #endif
758 
759 // you can use NLIB_COND_INITIALIZER for static initializer
761 #ifdef NLIB_PTHREAD_nlib_cond_init
762 static NLIB_C_INLINE errno_t nlib_cond_init(nlib_cond* cond) {
763  return pthread_cond_init(cond, NULL);
764 }
765 #endif
766 
767 #ifdef NLIB_PTHREAD_nlib_cond_signal
768 static
769 #else
771 #endif
773 #ifdef NLIB_PTHREAD_nlib_cond_signal
774 static NLIB_C_INLINE errno_t nlib_cond_signal(nlib_cond* cond) {
775  return pthread_cond_signal(cond);
776 }
777 #endif
778 
779 #ifdef NLIB_PTHREAD_nlib_cond_broadcast
780 static
781 #else
783 #endif
785 #ifdef NLIB_PTHREAD_nlib_cond_broadcast
786 static NLIB_C_INLINE errno_t nlib_cond_broadcast(nlib_cond* cond) {
787  return pthread_cond_broadcast(cond);
788 }
789 #endif
790 
791 #ifdef NLIB_PTHREAD_nlib_cond_wait
792 static
793 #else
795 #endif
796 // code snippets:
797 // Initialization:
798 // bool flag = false;
799 // nlib_mutex m;
800 // nlib_cond cond;
801 // nlib_mutex_init(&m);
802 // nlib_cond_init(&cond);
803 // Thread1:
804 // nlib_mutex_lock(&m);
805 // while (!flag)
806 // e = nlib_cond_wait(&cond, &m); # m to be unlocked in nlib_cond_wait
807 // # note that nlib_cond_wait may return without signal notified
808 // if (e != 0) { error .... }
809 // # do job and reset flag
810 // flag = false;
811 // nlib_mutex_unlock(&m);
812 // Thread2:
813 // nlib_mutex_lock(&m);
814 // flag = true;
815 // nlib_cond_broadcast(&cond);
816 // nlib_mutex_unlock(&m);
817 errno_t nlib_cond_wait(nlib_cond* __restrict cond, nlib_mutex* __restrict mutex)
818  NLIB_NONNULL NLIB_REQUIRES(*mutex);
819 #ifdef NLIB_PTHREAD_nlib_cond_wait
820 static NLIB_C_INLINE
821 errno_t nlib_cond_wait(nlib_cond* __restrict cond, nlib_mutex* __restrict mutex) {
822  return pthread_cond_wait(cond, mutex);
823 }
824 #endif
825 
826 // returns ETIMEDOUT if timeout, and see baloon for nlib_cond_wait()
828 errno_t nlib_cond_wait_for(nlib_cond* __restrict cond,
829  nlib_mutex* __restrict mutex,
830  nlib_duration duration) NLIB_NONNULL NLIB_REQUIRES(*mutex);
831 // returns ETIMEDOUT if timeout, and see baloon for nlib_cond_wait()
833 errno_t nlib_cond_wait_until(nlib_cond* __restrict cond,
834  nlib_mutex* __restrict mutex,
835  nlib_time abstime) NLIB_NONNULL NLIB_REQUIRES(*mutex);
836 
837 #ifdef NLIB_PTHREAD_nlib_cond_destroy
838 static
839 #else
841 #endif
843 #ifdef NLIB_PTHREAD_nlib_cond_destroy
844 static NLIB_C_INLINE errno_t nlib_cond_destroy(nlib_cond* cond) {
845  return pthread_cond_destroy(cond);
846 }
847 #endif
848 
849 static NLIB_C_INLINE
850 errno_t nlib_cond_wait_for_timespec(nlib_cond* cond, nlib_mutex* mutex, const struct timespec* tm)
851  NLIB_REQUIRES(*mutex) {
852  nlib_duration d;
853  NLIB_FROM_TIMESPEC(tm, d);
854  return nlib_cond_wait_for(cond, mutex, d);
855 }
856 
857 static NLIB_C_INLINE
859  const struct timespec* tm) NLIB_REQUIRES(*mutex) {
860  nlib_duration d;
861  NLIB_FROM_TIMESPEC(tm, d);
862  return nlib_cond_wait_until(cond, mutex, d);
863 }
864 
865 //
866 // Read/Write lock
867 //
868 #ifndef NLIB_RWLOCK_HAS_NATIVE
869 struct nlib_rwlock_ {
870  int32_t _0[3];
871  nlib_mutex _1[2];
872  nlib_cond _2;
873 };
874 NLIB_CAPABILITY("mutex")
875 typedef struct nlib_rwlock_ nlib_rwlock;
876 
877 #define NLIB_RWLOCK_INITIALIZER { \
878  { 0, 0, 0 }, \
879  { NLIB_RECURSIVE_TIMED_MUTEX_INITIALIZER, NLIB_RECURSIVE_TIMED_MUTEX_INITIALIZER }, \
880  NLIB_COND_INITIALIZER }
881 #endif
882 
883 #ifdef NLIB_PTHREAD_nlib_rwlock_init
884 static
885 #else
887 #endif
888 
889 errno_t nlib_rwlock_init(nlib_rwlock* rwlock) NLIB_NONNULL NLIB_EXCLUDES(*rwlock);
890 #ifdef NLIB_PTHREAD_nlib_rwlock_init
891 static NLIB_C_INLINE errno_t nlib_rwlock_init(nlib_rwlock* rwlock) {
892  return pthread_rwlock_init(rwlock, NULL);
893 }
894 #endif
895 
896 #ifdef NLIB_PTHREAD_nlib_rwlock_destroy
897 static
898 #else
900 #endif
901 errno_t nlib_rwlock_destroy(nlib_rwlock* rwlock) NLIB_NONNULL NLIB_EXCLUDES(*rwlock);
902 #ifdef NLIB_PTHREAD_nlib_rwlock_destroy
903 static NLIB_C_INLINE errno_t nlib_rwlock_destroy(nlib_rwlock* rwlock) {
904  return pthread_rwlock_destroy(rwlock);
905 }
906 #endif
907 
908 #ifdef NLIB_PTHREAD_nlib_rwlock_rdlock
909 static
910 #else
912 #endif
913 errno_t nlib_rwlock_rdlock(nlib_rwlock* rwlock) NLIB_NONNULL NLIB_ACQUIRE_SHARED(*rwlock);
914 #ifdef NLIB_PTHREAD_nlib_rwlock_rdlock
915 static NLIB_C_INLINE errno_t nlib_rwlock_rdlock(nlib_rwlock* rwlock)
916  NLIB_NO_THREAD_SAFETY_ANALYSIS {
917  return pthread_rwlock_rdlock(rwlock);
918 }
919 #endif
920 
921 #ifdef NLIB_PTHREAD_nlib_rwlock_tryrdlock
922 static
923 #else
925 #endif
926 errno_t nlib_rwlock_tryrdlock(nlib_rwlock* rwlock)
927  NLIB_NONNULL NLIB_TRY_ACQUIRE_SHARED(0, *rwlock);
928 #ifdef NLIB_PTHREAD_nlib_rwlock_tryrdlock
929 static NLIB_C_INLINE errno_t nlib_rwlock_tryrdlock(nlib_rwlock* rwlock)
930  NLIB_NO_THREAD_SAFETY_ANALYSIS {
931  return pthread_rwlock_tryrdlock(rwlock);
932 }
933 #endif
934 
936 errno_t nlib_rwlock_tryrdlock_for(nlib_rwlock* rwlock, nlib_duration duration)
937  NLIB_NONNULL NLIB_TRY_ACQUIRE_SHARED(0, *rwlock);
939 errno_t nlib_rwlock_tryrdlock_until(nlib_rwlock* rwlock, nlib_time abstime)
940  NLIB_NONNULL NLIB_TRY_ACQUIRE_SHARED(0, *rwlock);
941 
942 #ifdef NLIB_PTHREAD_nlib_rwlock_rdunlock
943 static
944 #else
946 #endif
947 errno_t nlib_rwlock_rdunlock(nlib_rwlock* rwlock)
948  NLIB_NONNULL NLIB_RELEASE_SHARED(*rwlock);
949 #ifdef NLIB_PTHREAD_nlib_rwlock_rdunlock
950 static NLIB_C_INLINE errno_t nlib_rwlock_rdunlock(nlib_rwlock* rwlock)
951  NLIB_NO_THREAD_SAFETY_ANALYSIS {
952  return pthread_rwlock_unlock(rwlock);
953 }
954 #endif
955 
956 #ifdef NLIB_PTHREAD_nlib_rwlock_wrlock
957 static
958 #else
960 #endif
961 errno_t nlib_rwlock_wrlock(nlib_rwlock* rwlock) NLIB_NONNULL NLIB_ACQUIRE(*rwlock);
962 #ifdef NLIB_PTHREAD_nlib_rwlock_wrlock
963 static NLIB_C_INLINE errno_t nlib_rwlock_wrlock(nlib_rwlock* rwlock)
964  NLIB_NO_THREAD_SAFETY_ANALYSIS {
965  return pthread_rwlock_wrlock(rwlock);
966 }
967 #endif
968 
969 #ifdef NLIB_PTHREAD_nlib_rwlock_trywrlock
970 static
971 #else
973 #endif
974 errno_t nlib_rwlock_trywrlock(nlib_rwlock* rwlock) NLIB_NONNULL NLIB_TRY_ACQUIRE(0, *rwlock);
975 #ifdef NLIB_PTHREAD_nlib_rwlock_trywrlock
976 static NLIB_C_INLINE errno_t nlib_rwlock_trywrlock(nlib_rwlock* rwlock)
977  NLIB_NO_THREAD_SAFETY_ANALYSIS {
978  return pthread_rwlock_trywrlock(rwlock);
979 }
980 #endif
981 
983 errno_t nlib_rwlock_trywrlock_for(nlib_rwlock* rwlock, nlib_duration duration)
984  NLIB_NONNULL NLIB_TRY_ACQUIRE(0, *rwlock);
986 errno_t nlib_rwlock_trywrlock_until(nlib_rwlock* rwlock, nlib_time abstime)
987  NLIB_NONNULL NLIB_TRY_ACQUIRE(0, *rwlock);
988 
989 #ifdef NLIB_PTHREAD_nlib_rwlock_wrunlock
990 static
991 #else
993 #endif
994 errno_t nlib_rwlock_wrunlock(nlib_rwlock* rwlock) NLIB_NONNULL NLIB_RELEASE(*rwlock);
995 #ifdef NLIB_PTHREAD_nlib_rwlock_wrunlock
996 static NLIB_C_INLINE errno_t nlib_rwlock_wrunlock(nlib_rwlock* rwlock)
997  NLIB_NO_THREAD_SAFETY_ANALYSIS {
998  return pthread_rwlock_unlock(rwlock);
999 }
1000 #endif
1001 
1002 static NLIB_C_INLINE
1003 errno_t nlib_rwlock_tryrdlock_for_timespec(nlib_rwlock* rwlock, const struct timespec* tm)
1004  NLIB_TRY_ACQUIRE_SHARED(0, *rwlock) {
1005  nlib_duration d;
1006  NLIB_FROM_TIMESPEC(tm, d);
1007  return nlib_rwlock_tryrdlock_for(rwlock, d);
1008 }
1009 
1010 static NLIB_C_INLINE
1011 errno_t nlib_rwlock_tryrdlock_until_timespec(nlib_rwlock* rwlock, const struct timespec* tm)
1012  NLIB_TRY_ACQUIRE_SHARED(0, *rwlock) {
1013  nlib_duration d;
1014  NLIB_FROM_TIMESPEC(tm, d);
1015  return nlib_rwlock_tryrdlock_until(rwlock, d);
1016 }
1017 
1018 static NLIB_C_INLINE
1019 errno_t nlib_rwlock_trywrlock_for_timespec(nlib_rwlock* rwlock, const struct timespec* tm)
1020  NLIB_TRY_ACQUIRE(0, *rwlock) {
1021  nlib_duration d;
1022  NLIB_FROM_TIMESPEC(tm, d);
1023  return nlib_rwlock_trywrlock_for(rwlock, d);
1024 }
1025 
1026 static NLIB_C_INLINE
1027 errno_t nlib_rwlock_trywrlock_until_timespec(nlib_rwlock* rwlock, const struct timespec* tm)
1028  NLIB_TRY_ACQUIRE(0, *rwlock) {
1029  nlib_duration d;
1030  NLIB_FROM_TIMESPEC(tm, d);
1031  return nlib_rwlock_trywrlock_until(rwlock, d);
1032 }
1033 
1034 
1035 #if defined(_MSC_VER) && defined(NLIB_RWLOCK_HAS_NATIVE)
1036 typedef struct nlib_condrwlock_ {
1037  CONDITION_VARIABLE cond;
1038 } nlib_condrwlock;
1039 #define NLIB_CONDRWLOCK_INITIALIZER { CONDITION_VARIABLE_INIT }
1040 #else
1041 typedef struct nlib_condrwlock_ {
1042  nlib_cond cond;
1043  nlib_mutex mutex;
1044 } nlib_condrwlock;
1045 #define NLIB_CONDRWLOCK_INITIALIZER { NLIB_COND_INITIALIZER, NLIB_MUTEX_INITIALIZER }
1046 #endif
1047 
1053  nlib_rwlock* __restrict rwlock,
1054  int rdlock) NLIB_NONNULL;
1056  nlib_rwlock* __restrict rwlock,
1057  nlib_duration duration,
1058  int rdlock) NLIB_NONNULL;
1060  nlib_rwlock* __restrict rwlock,
1061  nlib_time abstime,
1062  int rdlock) NLIB_NONNULL;
1063 
1065  nlib_rwlock* rwlock,
1066  const struct timespec* tm,
1067  int rdlock) {
1068  nlib_duration d;
1069  NLIB_FROM_TIMESPEC(tm, d);
1070  return nlib_condrwlock_wait_for(cond, rwlock, d, rdlock);
1071 }
1072 
1074  nlib_rwlock* rwlock,
1075  const struct timespec* tm,
1076  int rdlock) {
1077  nlib_duration d;
1078  NLIB_FROM_TIMESPEC(tm, d);
1079  return nlib_condrwlock_wait_until(cond, rwlock, d, rdlock);
1080 }
1081 
1082 //
1083 // Barrier
1084 //
1085 #ifndef NLIB_BARRIER_HAS_NATIVE
1086 struct nlib_barrier_ {
1087  nlib_mutex _0;
1088  nlib_cond _1;
1089  unsigned int _2[3];
1090 };
1091 typedef struct nlib_barrier_ nlib_barrier;
1092 #endif
1093 
1094 #ifdef NLIB_PTHREAD_nlib_barrier_init
1095 static
1096 #else
1098 #endif
1099 errno_t nlib_barrier_init(nlib_barrier* barrier, unsigned int count) NLIB_NONNULL;
1100 #ifdef NLIB_PTHREAD_nlib_barrier_init
1101 static NLIB_C_INLINE errno_t nlib_barrier_init(nlib_barrier* barrier, unsigned int count) {
1102  return pthread_barrier_init(barrier, NULL, count);
1103 }
1104 #endif
1105 
1106 #ifdef NLIB_PTHREAD_nlib_barrier_destroy
1107 static
1108 #else
1110 #endif
1112 #ifdef NLIB_PTHREAD_nlib_barrier_destroy
1113 static NLIB_C_INLINE errno_t nlib_barrier_destroy(nlib_barrier* barrier) {
1114  return pthread_barrier_destroy(barrier);
1115 }
1116 #endif
1117 
1119 
1120 //
1121 // Once
1122 //
1123 #ifndef NLIB_ONCE_HAS_NATIVE
1124 struct nlib_onceflag_ {
1125  int status;
1126 };
1127 typedef struct nlib_onceflag_ nlib_onceflag;
1128 #define NLIB_ONCE_INIT { 0 }
1129 typedef void (*nlib_oncefunc)(void);
1130 
1131 // code snippets
1132 // void OnceFunc() { .... }
1133 // nlib_onceflag flag = NLIB_ONCE_INIT; // should be static initialized
1134 // nlib_once(&flag, OnceFunc); // OnceFunc executes only once
1137 #elif defined(_MSC_VER)
1138 typedef INIT_ONCE nlib_onceflag;
1139 #define NLIB_ONCE_INIT INIT_ONCE_STATIC_INIT
1140 typedef void (*nlib_oncefunc)(void);
1141 NLIB_VIS_PUBLIC errno_t nlib_once(nlib_onceflag* flag, nlib_oncefunc func);
1142 #elif defined(__APPLE__) || defined(__FreeBSD__)
1143 typedef dispatch_once_t nlib_onceflag;
1144 #define NLIB_ONCE_INIT 0
1145 typedef void (*nlib_oncefunc)(void);
1146 NLIB_VIS_PUBLIC errno_t nlib_once(nlib_onceflag* flag, nlib_oncefunc func) NLIB_NONNULL;
1147 #else
1148 typedef pthread_once_t nlib_onceflag;
1149 #define NLIB_ONCE_INIT PTHREAD_ONCE_INIT
1150 typedef void (*nlib_oncefunc)(void);
1151 static errno_t nlib_once(nlib_onceflag* flag, nlib_oncefunc func) NLIB_NONNULL;
1152 static NLIB_C_INLINE errno_t nlib_once(nlib_onceflag* flag, nlib_oncefunc func) {
1153  return pthread_once(flag, func);
1154 }
1155 #endif
1156 
1157 //
1158 // Message Queue
1159 //
1160 #ifdef NLIB_DOXYGEN
1161 typedef int32_t nlib_mq;
1162 #else
1163 typedef struct nlib_mq_ {
1164  int32_t raw_handle; // 0 for invalid handle
1165 } nlib_mq;
1166 #endif
1167 typedef void* nlib_mq_msg;
1168 
1169 #define NLIB_MQ_BLOCK 0
1170 #define NLIB_MQ_NONBLOCK 1
1171 #define NLIB_MQ_LOCKFREE 2
1172 
1174 #ifdef NLIB_DOXYGEN
1176  int32_t flag;
1177  int32_t max_msg;
1178  int32_t cur_msg;
1180 };
1181 #else
1182 typedef struct nlib_mq_attr_ {
1183  int32_t flag; // NLIB_MQ_BLOCK / NLIB_MQ_NONBLOCK
1184  int32_t max_msg; // 0 for 128
1185  int32_t cur_msg; // blocking mode only
1186  nlib_mq_msg_destructor destructor;
1187 } nlib_mq_attr;
1188 #endif
1189 
1191 errno_t nlib_mq_open(nlib_mq* mq, const nlib_mq_attr* attr) NLIB_NONNULL;
1196 NLIB_CHECK_RESULT NLIB_VIS_PUBLIC errno_t nlib_mq_send(nlib_mq mq, nlib_mq_msg msg, int prio);
1198 errno_t nlib_mq_send_until(nlib_mq mq, nlib_mq_msg msg, int prio, nlib_time abstime);
1200 errno_t nlib_mq_receive(nlib_mq mq, nlib_mq_msg* msg, int* prio) NLIB_NONNULL_2;
1202 errno_t nlib_mq_receive_until(nlib_mq mq, nlib_mq_msg* msg, int* prio, nlib_time abstime)
1205 errno_t nlib_mq_drop(nlib_mq mq, nlib_mq_msg* msg, int* prio) NLIB_NONNULL_2;
1206 
1207 //
1208 // Thread
1209 //
1211 static NLIB_ALWAYS_INLINE void nlib_pause(void) {
1212 #if defined(__x86_64__) || defined(__i386__) || defined(_M_IX86) || defined(_M_AMD64)
1213  _mm_pause();
1214 #elif defined(__ARM_ACLE)
1215  __yield();
1216 #else
1217  (void)nlib_yield();
1218 #endif
1219 }
1220 
1221 #define NLIB_THREAD_INVALID (nlib_thread)(0) // NOLINT
1222 
1223 #ifndef NLIB_SPINLOCK_HAS_NATIVE
1224 typedef int32_t nlib_spinlock;
1225 #endif
1226 
1227 #ifndef NLIB_THREAD_ATTR_HAS_NATIVE
1228 struct nlib_thread_attr_ {
1229  nlib_spinlock spin;
1230  int detach_state;
1231  int explicit_sched;
1232  int priority;
1233  uint32_t affinity;
1234  void* stack_addr;
1235  size_t stack_size;
1236 };
1237 typedef struct nlib_thread_attr_ nlib_thread_attr;
1238 #else
1239 struct nlib_thread_attr_ {
1240  pthread_attr_t attr;
1241  uint32_t affinity;
1242 };
1243 typedef struct nlib_thread_attr_ nlib_thread_attr;
1244 #endif
1245 typedef void (*nlib_thread_func)(void* arg);
1246 // -1 for invalid
1247 typedef int nlib_thread_id;
1248 
1249 // code snippets:
1250 // nlib_thread th;
1251 // if ((e = nlib_thread_create(&th, NULL, myfunc, myarg)) != 0) { error ... }
1252 // nlib_thread_join(th); # or nlib_thread_detach(th);
1254 errno_t nlib_thread_create(nlib_thread* __restrict thread, const nlib_thread_attr* __restrict attr,
1255  nlib_thread_func func, void* __restrict arg)
1256  NLIB_NONNULL_1 NLIB_NONNULL_3;
1257 #ifdef NLIB_PTHREAD_nlib_thread_join
1258 static
1259 #else
1261 #endif
1263 #ifdef NLIB_PTHREAD_nlib_thread_join
1264 static NLIB_C_INLINE errno_t nlib_thread_join(nlib_thread thread) {
1265  return pthread_join(thread, NULL);
1266 }
1267 #endif
1268 
1269 #ifdef NLIB_PTHREAD_nlib_thread_detach
1270 static
1271 #else
1273 #endif
1275 #ifdef NLIB_PTHREAD_nlib_thread_detach
1276 static NLIB_C_INLINE errno_t nlib_thread_detach(nlib_thread thread) {
1277  return pthread_detach(thread);
1278 }
1279 #endif
1280 
1281 #ifdef NLIB_PTHREAD_nlib_thread_self
1282 static
1283 #else
1285 #endif
1287 #ifdef NLIB_PTHREAD_nlib_thread_self
1288 static NLIB_C_INLINE errno_t nlib_thread_self(nlib_thread* thread) {
1289  *thread = pthread_self();
1290  return 0;
1291 }
1292 #endif
1293 
1296 
1297 #ifdef NLIB_PTHREAD_nlib_thread_equal
1298 static
1299 #else
1301 #endif
1303 #ifdef NLIB_PTHREAD_nlib_thread_equal
1304 static NLIB_C_INLINE int nlib_thread_equal(nlib_thread th1, nlib_thread th2) {
1305  return pthread_equal(th1, th2);
1306 }
1307 #endif
1308 
1310 NLIB_VIS_PUBLIC errno_t nlib_thread_setaffinity(nlib_thread thread, uint32_t affinity);
1312 
1313 #ifdef NLIB_PTHREAD_nlib_thread_getname
1314 static
1315 #else
1317 #endif
1318 errno_t nlib_thread_getname(nlib_thread thread, char* name, size_t len) NLIB_NONNULL;
1319 #ifdef NLIB_PTHREAD_nlib_thread_getname
1320 static NLIB_C_INLINE errno_t nlib_thread_getname(nlib_thread thread, char* name, size_t len) {
1321  return pthread_getname_np(thread, name, len);
1322 }
1323 #endif
1324 
1325 // NOTE:
1326 // win32 does not have GetThreadAffinityMask()
1327 // errno_t nlib_thread_get_affinify(nlib_thread thread, uint32_t* affinity);
1328 
1333 errno_t nlib_thread_attr_getint(const nlib_thread_attr* __restrict attr, int key,
1334  int* __restrict value) NLIB_NONNULL;
1336 errno_t nlib_thread_attr_setptr(nlib_thread_attr* __restrict attr, int key,
1337  void* __restrict value) NLIB_NONNULL_1;
1339 errno_t nlib_thread_attr_getptr(const nlib_thread_attr* __restrict attr, int key,
1340  void** __restrict value) NLIB_NONNULL;
1342 errno_t nlib_thread_attr_setstack(nlib_thread_attr* __restrict attr, void* __restrict stack_addr,
1343  size_t stack_size) NLIB_NONNULL;
1345 errno_t nlib_thread_attr_getstack(const nlib_thread_attr* __restrict attr,
1346  void** __restrict stack_addr, size_t* __restrict stack_size)
1347  NLIB_NONNULL;
1349 
1350 #define NLIB_THREAD_ATTR_KEY_DETACHSTATE (1)
1351 #define NLIB_THREAD_ATTR_KEY_STACKSIZE (2)
1352 #define NLIB_THREAD_ATTR_KEY_PRIORITY (4)
1353 #define NLIB_THREAD_ATTR_KEY_AFFINITY (5)
1354 #define NLIB_THREAD_ATTR_KEY_EXPLICIT_SCHED (6)
1355 
1361 
1362 #ifndef NN_PLATFORM_CTR
1363 // See also nlib_thread_exit_cpp();
1365 #endif
1366 
1367 #ifdef NLIB_DOXYGEN
1368 void nlib_thread_cleanup_push(void (*fn)(void*), void* arg);
1369 void nlib_thread_cleanup_pop(int exec);
1370 #elif defined(pthread_cleanup_push)
1371 # define nlib_thread_cleanup_push(fn, arg) pthread_cleanup_push(fn, arg)
1372 # define nlib_thread_cleanup_pop(exec) pthread_cleanup_pop(exec)
1373 #elif !defined(NN_PLATFORM_CTR)
1374 struct nlib_thread_cleanup_handler_ {
1375  void (*func)(void*);
1376  void* arg;
1377  struct nlib_thread_cleanup_handler_* next;
1378 };
1379 #define nlib_thread_cleanup_push(fn, arg) switch (0) case 0: default: { \
1380  struct nlib_thread_cleanup_handler_ _thread_cleanup_handler = { fn, arg, NULL }; \
1381  nlib_thread_cleanup_push_(&_thread_cleanup_handler)
1382 #define nlib_thread_cleanup_pop(exec) nlib_thread_cleanup_pop_(exec); }
1383 
1384 NLIB_VIS_PUBLIC void nlib_thread_cleanup_push_(struct nlib_thread_cleanup_handler_* handler);
1385 NLIB_VIS_PUBLIC void nlib_thread_cleanup_pop_(int exec);
1386 #endif
1387 
1388 //
1389 // Console/Debug
1390 //
1391 
1392 // note that buf is not null terminated
1394 errno_t nlib_write_stdout(size_t* __restrict result, const void* __restrict buf, size_t count)
1395  NLIB_NONNULL;
1396 // note that buf is not null terminated
1398 errno_t nlib_write_stderr(size_t* __restrict result, const void* __restrict buf, size_t count)
1399  NLIB_NONNULL;
1402 errno_t nlib_debug_backtrace(size_t* __restrict result, void** __restrict buffer, size_t count)
1403  NLIB_NONNULL;
1405 errno_t nlib_debug_backtrace_gettext(char* __restrict str, size_t strbufsize,
1406  void* const* __restrict buf, size_t count) NLIB_NONNULL;
1408 errno_t nlib_getenv(size_t* __restrict result, char* __restrict buf, size_t bufsize,
1409  const char* __restrict varname) NLIB_NONNULL_1 NLIB_NONNULL_4;
1410 
1411 typedef enum nlib_log_priority {
1412  kNlibLogUnknown = 0,
1413  kNlibLogDefault,
1420  kNlibLogSilent,
1424  NLIB_LOG_UNKNOWN = kNlibLogUnknown,
1425  NLIB_LOG_DEAFULT = kNlibLogDefault,
1426  NLIB_LOG_VERBOSE = kNlibLogVerbose,
1427  NLIB_LOG_DEBUG = kNlibLogDebug,
1428  NLIB_LOG_INFO = kNlibLogInfo,
1429  NLIB_LOG_WARN = kNlibLogWarn,
1430  NLIB_LOG_ERROR = kNlibLogError,
1431  NLIB_LOG_FATAL = kNlibLogFatal,
1432  NLIB_LOG_SILENT = kNlibLogSilent,
1433  NLIB_LOG_LEVEL_EQUAL_OR_ABOVE = kNlibLogLevelEqualOrAbove,
1434  NLIB_LOG_LEVEL_EQUAL_OR_BELOW = kNlibLogLevelEqualOrBelow,
1435  NLIB_LOG_LEVEL_ALL = kNlibLogLevelAll
1437 
1438 typedef enum nlib_log_key {
1439  kNlibLogAttrUnknown = 0,
1440  kNlibLogAttrStdout,
1441  kNlibLogAttrStderr,
1442  kNlibLogAttrMsvcTrace,
1443  kNlibLogAttrSyslog,
1444  kNlibLogAttrNlibFd,
1445  kNlibLogAttrMax,
1446  NLIB_LOG_ATTR_UNKNOWN = kNlibLogAttrUnknown,
1447  NLIB_LOG_ATTR_STDOUT = kNlibLogAttrStdout,
1448  NLIB_LOG_ATTR_STDERR = kNlibLogAttrStderr,
1449  NLIB_LOG_ATTR_MSVC_TRACE = kNlibLogAttrMsvcTrace,
1450  NLIB_LOG_ATTR_SYSLOG = kNlibLogAttrSyslog,
1451  NLIB_LOG_ATTR_NLIB_FD = kNlibLogAttrNlibFd,
1452  NLIB_LOG_ATTR_MAX = kNlibLogAttrMax
1453 } nlib_log_key;
1454 
1455 #ifndef NLIB_ATTRIBUTE_PRINTF
1456 # define NLIB_ATTRIBUTE_PRINTF(x, y) __attribute__((format(printf, x, y)))
1457 #endif
1458 
1459 NLIB_VIS_PUBLIC int nlib_log_print(int prio, _Printf_format_string_ const char* __restrict tag,
1460  const char* __restrict fmt, ...)
1461  NLIB_ATTRIBUTE_PRINTF(3, 4) NLIB_NONNULL;
1462 NLIB_VIS_PUBLIC int nlib_log_vprint(int prio, _Printf_format_string_ const char* __restrict tag,
1463  const char* __restrict fmt, va_list ap) NLIB_NONNULL;
1464 NLIB_VIS_PUBLIC errno_t nlib_log_attr_setint(int prio, int key, int value);
1465 
1466 //
1467 // File Access
1468 //
1469 #ifndef NLIB_FD_O_RDONLY
1470 # ifndef O_RDONLY
1471 # error
1472 # endif
1473 # define NLIB_FD_O_RDONLY O_RDONLY
1474 #endif
1475 
1476 #ifndef NLIB_FD_O_WRONLY
1477 # ifndef O_WRONLY
1478 # error
1479 # endif
1480 # define NLIB_FD_O_WRONLY O_WRONLY
1481 #endif
1482 
1483 #ifndef NLIB_FD_O_RDWR
1484 # ifndef O_RDWR
1485 # error
1486 # endif
1487 # define NLIB_FD_O_RDWR O_RDWR
1488 #endif
1489 
1490 #ifndef NLIB_FD_O_APPEND
1491 # ifndef O_APPEND
1492 # error
1493 # endif
1494 # define NLIB_FD_O_APPEND O_APPEND
1495 #endif
1496 
1497 #ifndef NLIB_FD_O_CREAT
1498 # ifndef O_CREAT
1499 # error
1500 # endif
1501 # define NLIB_FD_O_CREAT O_CREAT
1502 #endif
1503 
1504 #ifndef NLIB_FD_O_TRUNC
1505 # ifndef O_TRUNC
1506 # error
1507 # endif
1508 # define NLIB_FD_O_TRUNC O_TRUNC
1509 #endif
1510 
1511 #ifndef NLIB_FD_O_EXCL
1512 # ifndef O_EXCL
1513 # error
1514 # endif
1515 # define NLIB_FD_O_EXCL O_EXCL
1516 #endif
1517 
1518 #ifndef NLIB_SEEK_SET
1519 # ifndef SEEK_SET
1520 # error
1521 # endif
1522 # define NLIB_SEEK_SET SEEK_SET
1523 #endif
1524 
1525 #ifndef NLIB_SEEK_CUR
1526 # ifndef SEEK_CUR
1527 # error
1528 # endif
1529 # define NLIB_SEEK_CUR SEEK_CUR
1530 #endif
1531 
1532 // NOTE:
1533 // SEEK_END not supported(because of FIO19-C)
1534 
1535 typedef int64_t nlib_offset;
1536 typedef int nlib_fd;
1537 #define NLIB_FD_INVALID (-1)
1538 
1539 #ifdef NLIB_DOXYGEN
1540 errno_t nlib_fd_open(nlib_fd* fd, const char* native_path, unsigned int flags);
1541 errno_t nlib_fd_open(nlib_fd* fd, const char* native_path, unsigned int flags, int mode);
1542 #else
1544 errno_t nlib_fd_open(nlib_fd* fd, const char* native_path, unsigned int flags, ...) NLIB_NONNULL_1;
1545 #endif
1546 NLIB_CHECK_RESULT static NLIB_C_INLINE
1547 errno_t nlib_fd_creat(nlib_fd* fd, const char* native_path, int mode) {
1548  return nlib_fd_open(fd, native_path,
1550 }
1553 errno_t nlib_fd_read(size_t* __restrict result, nlib_fd fd, void* __restrict buf, size_t count)
1556 errno_t nlib_fd_write(size_t* __restrict result, nlib_fd fd, const void* __restrict buf,
1557  size_t count) NLIB_NONNULL_1;
1559 errno_t nlib_fd_seek(nlib_offset* result, nlib_fd fd, nlib_offset offset, int whence)
1562 errno_t nlib_fd_pread(size_t* __restrict result, nlib_fd fd, void* __restrict buf,
1563  size_t count, nlib_offset offset) NLIB_NONNULL_1;
1565 errno_t nlib_fd_pwrite(size_t* __restrict result, nlib_fd fd, const void* __restrict buf,
1566  size_t count, nlib_offset offset) NLIB_NONNULL_1;
1567 NLIB_CHECK_RESULT NLIB_VIS_PUBLIC errno_t nlib_fd_truncate(nlib_fd fd, nlib_offset length);
1568 
1570 errno_t nlib_fd_getsize(nlib_offset* size, nlib_fd fd) NLIB_NONNULL;
1573 NLIB_VIS_PUBLIC errno_t nlib_fd_native_handle(void** native_handle, nlib_fd fd) NLIB_NONNULL;
1574 // errno_t nlib_fd_fcntl_getflag(unsigned int* flags, nlib_fd fd);
1575 // errno_t nlib_fd_fcntl_setflag(nlib_fd fd, unsigned int flags);
1576 
1577 // Scatter/Gather buffer
1578 #if !defined(NLIB_IOVEC_HAS_NATIVE)
1579 struct nlib_fd_iovec_ {
1580  void* iov_base;
1581  size_t iov_len;
1582 };
1583 typedef struct nlib_fd_iovec_ nlib_fd_iovec;
1584 #else
1585 typedef struct iovec nlib_fd_iovec;
1586 #endif
1588 errno_t nlib_fd_readv(size_t* __restrict result, nlib_fd fd, const nlib_fd_iovec* __restrict iov,
1589  int iovcnt) NLIB_NONNULL;
1591 errno_t nlib_fd_writev(size_t* __restrict result, nlib_fd fd, const nlib_fd_iovec* __restrict iov,
1592  int iovcnt) NLIB_NONNULL;
1594 errno_t nlib_fd_preadv(size_t* __restrict result, nlib_fd fd, const nlib_fd_iovec* __restrict iov,
1595  int iovcnt, nlib_offset offset) NLIB_NONNULL;
1597 errno_t nlib_fd_pwritev(size_t* __restrict result, nlib_fd fd, const nlib_fd_iovec* __restrict iov,
1598  int iovcnt, nlib_offset offset) NLIB_NONNULL;
1599 // errno_t nlib_fd_stat(stat* stat, nlib_fd fd);
1600 
1601 NLIB_CHECK_RESULT NLIB_VIS_PUBLIC errno_t nlib_unlink(const char* native_path);
1602 NLIB_CHECK_RESULT NLIB_VIS_PUBLIC errno_t nlib_mkdir(const char* native_path,
1603  unsigned int flags);
1604 NLIB_CHECK_RESULT NLIB_VIS_PUBLIC errno_t nlib_rmdir(const char* native_path);
1605 NLIB_CHECK_RESULT NLIB_VIS_PUBLIC errno_t nlib_remove(const char* native_path);
1607 errno_t nlib_rename(const char* __restrict old_path, const char* __restrict new_path);
1608 
1609 struct nlib_dir_ {
1610  void* ptr;
1611 };
1612 typedef struct nlib_dir_ nlib_dir;
1613 typedef struct nlib_dirent_ {
1614  uint32_t flags; // 0: file, 1: directory
1615  char name[768];
1616 } nlib_dirent;
1618 errno_t nlib_dir_open(nlib_dir* __restrict dir, const char* __restrict native_path) NLIB_NONNULL_1;
1619 NLIB_VIS_PUBLIC errno_t nlib_dir_close(nlib_dir dir);
1621 errno_t nlib_dir_read(nlib_dirent* ent, nlib_dir dir) NLIB_NONNULL;
1622 
1623 // CTR does not have getcwd.....
1624 // errno_t nlib_getcwd(char* buf, size_t bufsize);
1625 // errno_t nlib_chdir(const char* path);
1626 
1628 errno_t nlib_is_dir(int* __restrict result, const char* __restrict native_path) NLIB_NONNULL_1;
1629 // *result != 0 if exists
1631 errno_t nlib_exist_path(int* __restrict result, const char* __restrict native_path) NLIB_NONNULL_1;
1633 errno_t nlib_disk_freespace(const char* __restrict native_path,
1634  uint64_t* __restrict free_bytes_available,
1635  uint64_t* __restrict total_bytes,
1636  uint64_t* __restrict total_free_bytes);
1637 
1638 NLIB_VIS_PUBLIC const char* nlib_basename(const char* path) NLIB_NONNULL;
1639 NLIB_VIS_PUBLIC const char* nlib_dirname(size_t* len, const char* path) NLIB_NONNULL;
1640 NLIB_VIS_PUBLIC errno_t nlib_mkostemps(nlib_fd* fd, char* templ, int suffixlen, int flags);
1641 
1642 struct nlib_fileid_ {
1643 #if defined(_MSC_VER)
1644  FILE_ID_INFO _;
1645 #elif defined(NLIB_UNIX)
1646  dev_t _0;
1647  ino_t _1;
1648 #else
1649  uint64_t _;
1650 #endif
1651 };
1652 typedef struct nlib_fileid_ nlib_fileid;
1653 NLIB_VIS_PUBLIC errno_t nlib_fd_fileid(nlib_fileid* result, nlib_fd fd);
1654 NLIB_VIS_PUBLIC errno_t nlib_readlink(size_t* len, const char* native_path, char* buf,
1655  size_t bufsize);
1656 
1657 //
1658 // Socket(Win32/Linux/Cygwin only)
1659 //
1660 #if defined(_MSC_VER) || defined(NLIB_UNIX)
1661 #include "nn/nlib/Platform_socket.h"
1662 #endif
1663 
1664 //
1665 // errno workaround
1666 //
1667 
1668 // PLEASE DO NOT DEFINE POSIX.1-2008 errno macros in your code
1669 // http://pubs.opengroup.org/onlinepubs/9699919799/
1670 #ifdef _MSC_VER
1671 # ifdef EDQUOT
1672 # warning Do not define EDQUOT. nlib may not work correctly.
1673 # endif
1674 #endif
1675 
1676 #ifndef NLIB_SKIP_ERRNO_DEFINE
1677 #include <errno.h> // NOLINT, for POSIX error values
1678 #if !defined(__CYGWIN__) && !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NX__)
1679 #include "nn/nlib/Platform_errno.h"
1680 #endif
1681 #endif
1682 
1683 //
1684 // nlib_spinlock
1685 //
1686 #ifndef NLIB_SPINLOCK_HAS_NATIVE
1687 #define NLIB_SPINLOCK_INITIALIZER (0)
1688 NLIB_VIS_PUBLIC void nlib_spinlock_lock_(nlib_spinlock* lock) NLIB_NONNULL;
1689 #ifndef NN_PLATFORM_CTR
1690 NLIB_VIS_PUBLIC void nlib_spinlock_unlock_(nlib_spinlock* lock) NLIB_NONNULL;
1691 #endif
1692 
1693 static void nlib_spinlock_init(nlib_spinlock* lock) NLIB_NONNULL;
1694 static void nlib_spinlock_lock(nlib_spinlock* lock) NLIB_NONNULL;
1695 static errno_t nlib_spinlock_trylock(nlib_spinlock* lock) NLIB_NONNULL;
1696 static void nlib_spinlock_unlock(nlib_spinlock* lock) NLIB_NONNULL;
1697 
1698 static NLIB_ALWAYS_INLINE void nlib_spinlock_init(nlib_spinlock* lock) {
1699  *lock = 0;
1700 }
1701 static NLIB_ALWAYS_INLINE void nlib_spinlock_lock(nlib_spinlock* lock) {
1702 #if defined(__arm__)
1703 #if __has_builtin(__builtin_arm_ldrex)
1704  int R5 = __builtin_arm_ldrex(lock);
1705 #else
1706  int R5 = __ldrex(lock);
1707 #endif
1708  if (R5 == 0) {
1709 #if __has_builtin(__builtin_arm_strex)
1710  if (__builtin_arm_strex(1, lock) == 0) {
1711 #else
1712  if (__strex(1, lock) == 0) {
1713 #endif
1714 #if !defined(NN_PLATFORM_CTR)
1715  __dmb(0xf);
1716 #else
1717  nlib_ctr_barrier();
1718 #endif
1719  }
1720  return;
1721  }
1722  nlib_spinlock_lock_(lock);
1723 #else
1724  int32_t expected = 0;
1725  if (!nlib_atomic_compare_exchange32(lock, &expected, 1, 1,
1727  nlib_spinlock_lock_(lock);
1728  }
1729 #endif
1730 }
1731 static NLIB_ALWAYS_INLINE errno_t nlib_spinlock_trylock(nlib_spinlock* lock) {
1732 #if defined(__arm__)
1733 #if __has_builtin(__builtin_arm_ldrex)
1734  int R5 = __builtin_arm_ldrex(lock);
1735 #else
1736  int R5 = __ldrex(lock);
1737 #endif
1738  if (R5 == 0) {
1739 #if __has_builtin(__builtin_arm_strex)
1740  if (__builtin_arm_strex(1, lock) == 0) {
1741 #else
1742  if (__strex(1, lock) == 0) {
1743 #endif
1744 #if !defined(NN_PLATFORM_CTR)
1745  __dmb(0xf);
1746 #else
1747  nlib_ctr_barrier();
1748 #endif
1749  return 0;
1750  }
1751  }
1752  return EBUSY;
1753 #else
1754  int32_t expected = 0;
1755  if (nlib_atomic_compare_exchange32(lock, &expected, 1, 0,
1757  return 0;
1758  else
1759  return EBUSY;
1760 #endif
1761 }
1762 static NLIB_ALWAYS_INLINE void nlib_spinlock_unlock(nlib_spinlock* lock) {
1763 #if defined(NN_PLATFORM_CTR)
1765 #else
1766  int32_t expected = 1;
1767  if (!nlib_atomic_compare_exchange32(lock, &expected, 0, 0,
1769  NLIB_ASSUME(expected == 2);
1770  nlib_spinlock_unlock_(lock);
1771  }
1772 #if defined(__arm__)
1773  __sev();
1774 #endif
1775 #endif
1776 }
1777 #endif
1778 
1779 //
1780 // Utilities(Safer style functions)
1781 //
1783 errno_t nlib_vsnprintf(size_t* __restrict count, char* __restrict buf, size_t size,
1784  _Printf_format_string_ const char* __restrict fmt, va_list args)
1787 errno_t nlib_snprintf(size_t* __restrict count, char* __restrict buf, size_t size,
1788  _Printf_format_string_ const char* __restrict fmt, ...)
1789  NLIB_ATTRIBUTE_PRINTF(4, 5) NLIB_NONNULL_4;
1791 errno_t nlib_vdprintf(nlib_fd fd, size_t* __restrict count,
1792  _Printf_format_string_ const char* __restrict fmt, va_list args)
1795 errno_t nlib_dprintf(nlib_fd fd, size_t* __restrict count,
1796  _Printf_format_string_ const char* __restrict fmt, ...)
1797  NLIB_ATTRIBUTE_PRINTF(3, 4) NLIB_NONNULL_3;
1798 // fmt and string must be in UTF-8 even if you use Visual Studio
1800 int nlib_printf(_Printf_format_string_ const char* fmt, ...)
1801  NLIB_ATTRIBUTE_PRINTF(1, 2) NLIB_NONNULL_1;
1802 
1804 errno_t nlib_vsnwprintf(size_t* __restrict count, wchar_t* __restrict buf, size_t size,
1805  _Printf_format_string_ const wchar_t* __restrict fmt, va_list args)
1808 errno_t nlib_snwprintf(size_t* __restrict count, wchar_t* __restrict buf, size_t size,
1809  _Printf_format_string_ const wchar_t* __restrict fmt, ...)
1812 errno_t nlib_vdwprintf(nlib_fd fd, size_t* __restrict count,
1813  _Printf_format_string_ const wchar_t* __restrict fmt, va_list args)
1816 errno_t nlib_dwprintf(nlib_fd fd, size_t* __restrict count,
1817  _Printf_format_string_ const wchar_t* __restrict fmt, ...) NLIB_NONNULL_3;
1819 int nlib_wprintf(_Printf_format_string_ const wchar_t* fmt, ...) NLIB_NONNULL_1;
1820 
1822 errno_t nlib_vsnprintf_fallback(size_t* __restrict count, char* __restrict buf, size_t size,
1823  _Printf_format_string_ const char* __restrict fmt, va_list args)
1826 errno_t nlib_snprintf_fallback(size_t* __restrict count, char* __restrict buf,
1827  size_t size, _Printf_format_string_ const char* __restrict fmt, ...)
1828  NLIB_ATTRIBUTE_PRINTF(4, 5) NLIB_NONNULL_4;
1830 errno_t nlib_vsnwprintf_fallback(size_t* __restrict count, wchar_t* __restrict buf, size_t size,
1831  _Printf_format_string_ const wchar_t* __restrict fmt, va_list args)
1834 errno_t nlib_snwprintf_fallback(size_t* __restrict count, wchar_t* __restrict buf, size_t size,
1835  _Printf_format_string_ const wchar_t* __restrict fmt, ...)
1837 
1838 // http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1078.pdf
1839 // http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1079.htm
1840 // a bit different from Microsoft's strcpy_s or etc.
1841 // returns ERANGE instead of EINVAL
1842 
1843 static errno_t nlib_memcpy(void* __restrict s1, size_t s1max, const void* __restrict s2, size_t n)
1844  NLIB_NONNULL;
1845 static errno_t nlib_memmove(void* s1, size_t s1max, const void* s2, size_t n) NLIB_NONNULL;
1846 static errno_t nlib_memset(void* buf, int ch, size_t n) NLIB_NONNULL;
1848 void* nlib_memccpy(void* __restrict dest, size_t dest_size, const void* __restrict src,
1849  size_t src_size, int c) NLIB_NONNULL;
1850 
1851 #ifdef NLIB_LIBC_nlib_memcmp
1852 static
1853 #else
1854 NLIB_VIS_PUBLIC_ALT
1855 #endif
1856 int nlib_memcmp(const void* buf1, const void* buf2, size_t n) NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
1857 #ifdef NLIB_LIBC_nlib_memcmp
1858 static NLIB_C_INLINE int nlib_memcmp(const void* buf1, const void* buf2, size_t n) {
1859  return memcmp(buf1, buf2, n);
1860 }
1861 #endif
1862 
1863 NLIB_VIS_PUBLIC_ALT const void* nlib_memchr(const void* s, int c, size_t n)
1864  NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
1865 NLIB_VIS_PUBLIC_ALT const void* nlib_memrchr(const void* s, int c, size_t n)
1866  NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
1867 NLIB_VIS_PUBLIC_ALT const void* nlib_memchr_not(const void* s, int c, size_t n)
1868  NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
1869 NLIB_VIS_PUBLIC_ALT
1870 const void* nlib_memchr_range_not(const void* __restrict s, const char* __restrict range,
1871  size_t n) NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
1872 NLIB_VIS_PUBLIC_ALT const void* nlib_memchr_lt(const void* s, int c, size_t n)
1873  NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
1874 NLIB_VIS_PUBLIC_ALT const void* nlib_memchr_gt(const void* s, int c, size_t n)
1875  NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
1876 // find (c & 0x80) != 0
1877 NLIB_VIS_PUBLIC_ALT const void* nlib_memchr_mb(const void* s, size_t n)
1878  NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
1879 NLIB_VIS_PUBLIC size_t nlib_memspn(const void* __restrict buf, size_t len,
1880  const char* __restrict set, size_t n)
1881  NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
1882 NLIB_VIS_PUBLIC size_t nlib_memcspn(const void* __restrict buf, size_t len,
1883  const char* __restrict set, size_t n)
1884  NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
1885 
1886 // ' ', CR, LF, HT are skipped
1887 NLIB_VIS_PUBLIC_ALT
1888 const char* nlib_skipws(size_t* __restrict cnt_lf, const char** __restrict last_lf,
1889  const char* __restrict s, size_t n) NLIB_NONNULL_2;
1890 
1891 #ifdef NLIB_LIBC_nlib_strlen
1892 static
1893 #else
1894 NLIB_VIS_PUBLIC_ALT
1895 #endif
1896 size_t nlib_strlen(const char* s) NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
1897 #ifdef NLIB_LIBC_nlib_strlen
1898 static NLIB_C_INLINE size_t nlib_strlen(const char* s) { return strlen(s); }
1899 #endif
1900 
1901 #ifdef NLIB_LIBC_nlib_strnlen
1902 static
1903 #else
1904 NLIB_VIS_PUBLIC_ALT
1905 #endif
1906 size_t nlib_strnlen(const char* s, size_t maxsize) NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
1907 #ifdef NLIB_LIBC_nlib_strnlen
1908 static NLIB_C_INLINE size_t nlib_strnlen(const char* s, size_t maxsize) {
1909 #if defined(_MSC_VER) || defined(__STDC_LIB_EXT1__)
1910  return strnlen_s(s, maxsize);
1911 #else
1912  return strnlen(s, maxsize);
1913 #endif
1914 }
1915 #endif
1916 
1917 #ifdef NLIB_LIBC_nlib_strcpy
1918 static
1919 #else
1921 #endif
1922 errno_t nlib_strcpy(char* __restrict s1, size_t s1max, const char* __restrict s2) NLIB_NONNULL;
1923 #ifdef NLIB_LIBC_nlib_strcpy
1924 static NLIB_C_INLINE
1925 errno_t nlib_strcpy(char* __restrict s1, size_t s1max, const char* __restrict s2) {
1926 #if defined(_MSC_VER) || defined(__STDC_LIB_EXT1__)
1927  return strcpy_s(s1, s1max, s2);
1928 #else
1929 # error
1930 #endif
1931 }
1932 #endif
1933 
1934 #ifdef NLIB_LIBC_nlib_strncpy
1935 static
1936 #else
1938 #endif
1939 errno_t nlib_strncpy(char* __restrict s1, size_t s1max, const char* __restrict s2, size_t n)
1940  NLIB_NONNULL;
1941 #ifdef NLIB_LIBC_nlib_strncpy
1942 static NLIB_C_INLINE
1943 errno_t nlib_strncpy(char* __restrict s1, size_t s1max, const char* __restrict s2, size_t n) {
1944 #if defined(_MSC_VER) || defined(__STDC_LIB_EXT1__)
1945  return strncpy_s(s1, s1max, s2, n);
1946 #else
1947 # error
1948 #endif
1949 }
1950 #endif
1951 
1952 #ifdef NLIB_LIBC_nlib_strchr
1953 static
1954 #else
1955 NLIB_VIS_PUBLIC_ALT
1956 #endif
1957 const char* nlib_strchr(const char* s, int c) NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
1958 #ifdef NLIB_LIBC_nlib_strchr
1959 static NLIB_C_INLINE const char* nlib_strchr(const char* s, int c) { return strchr(s, c); }
1960 #endif
1961 
1962 #ifdef NLIB_LIBC_nlib_strrchr
1963 static
1964 #else
1965 NLIB_VIS_PUBLIC_ALT
1966 #endif
1967 const char* nlib_strrchr(const char* s, int c) NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
1968 #ifdef NLIB_LIBC_nlib_strrchr
1969 static NLIB_C_INLINE const char* nlib_strrchr(const char* s, int c) { return strrchr(s, c); }
1970 #endif
1971 
1972 // find (c & 0x80) != 0, used for skipping ASCII chars
1973 static const char* nlib_strchr_mb(const char* s) NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
1974 static NLIB_C_INLINE const char* nlib_strchr_mb(const char* s) {
1975  size_t n = nlib_strlen(s);
1976  const void* p = nlib_memchr_mb(s, n);
1977  if (p) {
1978  return (const char*)p; // NOLINT
1979  } else {
1980  return s + n;
1981  }
1982 }
1983 
1984 #ifdef NLIB_LIBC_nlib_wcslen
1985 static
1986 #else
1988 #endif
1989 size_t nlib_wcslen(const wchar_t* s) NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
1990 #ifdef NLIB_LIBC_nlib_wcslen
1991 static NLIB_C_INLINE size_t nlib_wcslen(const wchar_t* s) { return wcslen(s); }
1992 #endif
1993 
1994 #ifdef NLIB_LIBC_nlib_wcsnlen
1995 static
1996 #else
1998 #endif
1999 size_t nlib_wcsnlen(const wchar_t* s, size_t maxsize) NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
2000 #ifdef NLIB_LIBC_nlib_wcsnlen
2001 static NLIB_C_INLINE size_t nlib_wcsnlen(const wchar_t* s, size_t maxsize) {
2002 #if defined(_MSC_VER) || defined(__STDC_LIB_EXT1__)
2003  return wcsnlen_s(s, maxsize);
2004 #else
2005  return wcsnlen(s, maxsize);
2006 #endif
2007 }
2008 #endif
2009 
2010 #ifdef NLIB_LIBC_nlib_wcscpy
2011 static
2012 #else
2014 #endif
2015 errno_t nlib_wcscpy(wchar_t* __restrict s1, size_t s1max, const wchar_t* __restrict s2)
2016  NLIB_NONNULL;
2017 #ifdef NLIB_LIBC_nlib_wcscpy
2018 static NLIB_C_INLINE
2019 errno_t nlib_wcscpy(wchar_t* __restrict s1, size_t s1max, const wchar_t* __restrict s2) {
2020 #if defined(_MSC_VER) || defined(__STDC_LIB_EXT1__)
2021  return wcscpy_s(s1, s1max, s2);
2022 #else
2023 # error
2024 #endif
2025 }
2026 #endif
2027 
2028 #ifdef NLIB_LIBC_nlib_wcsncpy
2029 static
2030 #else
2032 #endif
2033 errno_t nlib_wcsncpy(wchar_t* __restrict s1, size_t s1max, const wchar_t* __restrict s2, size_t n)
2034  NLIB_NONNULL;
2035 #ifdef NLIB_LIBC_nlib_wcsncpy
2036 static NLIB_C_INLINE
2037 errno_t nlib_wcsncpy(wchar_t* __restrict s1, size_t s1max, const wchar_t* __restrict s2, size_t n) {
2038 #if defined(_MSC_VER) || defined(__STDC_LIB_EXT1__)
2039  return wcsncpy_s(s1, s1max, s2, n);
2040 #else
2041 # error
2042 #endif
2043 }
2044 #endif
2045 
2047 errno_t nlib_strto_int32(int32_t* result, const char* nptr, char** endptr, int base)
2048  NLIB_NONNULL_1 NLIB_NONNULL_2;
2050 errno_t nlib_strto_int64(int64_t* result, const char* nptr, char** endptr, int base)
2051  NLIB_NONNULL_1 NLIB_NONNULL_2;
2053 errno_t nlib_strto_uint32(uint32_t* result, const char* nptr, char** endptr, int base)
2054  NLIB_NONNULL_1 NLIB_NONNULL_2;
2056 errno_t nlib_strto_uint64(uint64_t* result, const char* nptr, char** endptr, int base)
2057  NLIB_NONNULL_1 NLIB_NONNULL_2;
2059 errno_t nlib_strto_double(double* result, const char* nptr, char** endptr)
2060  NLIB_NONNULL_1 NLIB_NONNULL_2;
2062 errno_t nlib_strto_float(float* result, const char* nptr, char** endptr)
2063  NLIB_NONNULL_1 NLIB_NONNULL_2;
2065 errno_t nlib_strto_int32_fallback(int32_t* result, const char* nptr, char** endptr, int base)
2066  NLIB_NONNULL_1 NLIB_NONNULL_2;
2068 errno_t nlib_strto_int64_fallback(int64_t* result, const char* nptr, char** endptr, int base)
2069  NLIB_NONNULL_1 NLIB_NONNULL_2;
2071 errno_t nlib_strto_uint32_fallback(uint32_t* result, const char* nptr, char** endptr, int base)
2072  NLIB_NONNULL_1 NLIB_NONNULL_2;
2074 errno_t nlib_strto_uint64_fallback(uint64_t* result, const char* nptr, char** endptr, int base)
2075  NLIB_NONNULL_1 NLIB_NONNULL_2;
2077 errno_t nlib_strto_double_fallback(double* result, const char* nptr, char** endptr)
2078  NLIB_NONNULL_1 NLIB_NONNULL_2;
2080 errno_t nlib_strto_float_fallback(float* result, const char* nptr, char** endptr)
2081  NLIB_NONNULL_1 NLIB_NONNULL_2;
2082 static NLIB_C_INLINE
2083 errno_t nlib_strto_int8(int8_t* result, const char* nptr, char** endptr, int base) {
2084  int32_t tmp;
2085  errno_t e;
2086  e = nlib_strto_int32(&tmp, nptr, endptr, base);
2087  if (e != 0 && e != ERANGE) return e;
2088  if (tmp > 127 || tmp < -128) {
2089  *result = tmp < 0 ? -128 : 127;
2090  return ERANGE;
2091  }
2092  *result = (int8_t)tmp; // NOLINT
2093  return e;
2094 }
2095 static NLIB_C_INLINE
2096 errno_t nlib_strto_int16(int16_t* result, const char* nptr, char** endptr, int base) {
2097  int32_t tmp;
2098  errno_t e;
2099  e = nlib_strto_int32(&tmp, nptr, endptr, base);
2100  if (e != 0 && e != ERANGE) return e;
2101  if (tmp > 32767 || tmp < -32768) {
2102  *result = tmp < 0 ? -32768 : 32767;
2103  return ERANGE;
2104  }
2105  *result = (int16_t)tmp; // NOLINT
2106  return e;
2107 }
2108 static NLIB_C_INLINE
2109 errno_t nlib_strto_uint8(uint8_t* result, const char* nptr, char** endptr, int base) {
2110  uint32_t tmp;
2111  errno_t e;
2112  e = nlib_strto_uint32(&tmp, nptr, endptr, base);
2113  if (e != 0 && e != ERANGE) return e;
2114  if (tmp > 255) {
2115  *result = 255;
2116  return ERANGE;
2117  }
2118  *result = (uint8_t)tmp; // NOLINT
2119  return e;
2120 }
2121 static NLIB_C_INLINE
2122 errno_t nlib_strto_uint16(uint16_t* result, const char* nptr, char** endptr, int base) {
2123  uint32_t tmp;
2124  errno_t e;
2125  e = nlib_strto_uint32(&tmp, nptr, endptr, base);
2126  if (e != 0 && e != ERANGE) return e;
2127  if (tmp > 65535) {
2128  *result = 65535;
2129  return ERANGE;
2130  }
2131  *result = (uint16_t)tmp; // NOLINT
2132  return e;
2133 }
2135 errno_t nlib_int8_from_chars(int8_t* result, const char** endptr,
2136  const char* first, const char* last, int base);
2138 errno_t nlib_int16_from_chars(int16_t* result, const char** endptr,
2139  const char* first, const char* last, int base);
2141 errno_t nlib_int32_from_chars(int32_t* result, const char** endptr,
2142  const char* first, const char* last, int base);
2144 errno_t nlib_int64_from_chars(int64_t* result, const char** endptr,
2145  const char* first, const char* last, int base);
2147 errno_t nlib_uint8_from_chars(uint8_t* result, const char** endptr,
2148  const char* first, const char* last, int base);
2150 errno_t nlib_uint16_from_chars(uint16_t* result, const char** endptr,
2151  const char* first, const char* last, int base);
2153 errno_t nlib_uint32_from_chars(uint32_t* result, const char** endptr,
2154  const char* first, const char* last, int base);
2156 errno_t nlib_uint64_from_chars(uint64_t* result, const char** endptr,
2157  const char* first, const char* last, int base);
2159 errno_t nlib_double_from_chars(double* result, const char** endptr,
2160  const char* first, const char* last);
2162 errno_t nlib_float_from_chars(float* result, const char** endptr,
2163  const char* first, const char* last);
2164 
2166 errno_t nlib_wide_to_utf8(size_t* __restrict utf8count, nlib_utf8_t* __restrict utf8,
2167  size_t buflen, const wchar_t* __restrict wcstr) NLIB_NONNULL_4;
2169 errno_t nlib_utf8_to_wide(size_t* __restrict wccount, wchar_t* __restrict wcstr,
2170  size_t buflen, const nlib_utf8_t* __restrict utf8) NLIB_NONNULL_4;
2172 errno_t nlib_memwide_to_utf8(size_t* __restrict to_count, size_t* __restrict from_count,
2173  nlib_utf8_t* __restrict to, size_t to_size,
2174  const wchar_t* __restrict from, size_t from_size)
2175  NLIB_NONNULL_1 NLIB_NONNULL_2 NLIB_NONNULL_5;
2177 errno_t nlib_memutf8_to_wide(size_t* __restrict to_count, size_t* __restrict from_count,
2178  wchar_t* __restrict to, size_t to_size,
2179  const nlib_utf8_t* __restrict from, size_t from_size)
2180  NLIB_NONNULL_1 NLIB_NONNULL_2 NLIB_NONNULL_5;
2181 
2183 errno_t nlib_wcscplen(size_t* __restrict count, const wchar_t* __restrict str) NLIB_NONNULL_2;
2185 errno_t nlib_strcplen(size_t* __restrict codepoint_count,
2186  size_t* __restrict supplementary_codepoint_count,
2187  size_t* __restrict len,
2188  const nlib_utf8_t* __restrict str) NLIB_NONNULL_4;
2190 errno_t nlib_memcplen(size_t* __restrict codepoint_count,
2191  size_t* __restrict supplementary_codepoint_count,
2192  size_t* __restrict from_read,
2193  const nlib_utf8_t* __restrict from,
2194  size_t from_size) NLIB_NONNULL_3 NLIB_NONNULL_4;
2195 
2196 // 0 if error
2199  nlib_utf16_t lower) NLIB_NONNULL;
2200 // 0 if error
2203  nlib_utf32_t utf32) NLIB_NONNULL;
2204 // 0 if error
2207 #ifdef __cplusplus
2208 // 0 if error
2210 int nlib_utf32char_to_utf8(nlib_utf8_t (&utf8)[4], nlib_utf32_t utf32);
2211 #endif
2212 
2214 errno_t nlib_utf16_to_utf8(size_t* utf8count, nlib_utf8_t* utf8, size_t buflen,
2215  const nlib_utf16_t* utf16) NLIB_NONNULL_4;
2217 errno_t nlib_utf8_to_utf16(size_t* utf16count, nlib_utf16_t* utf16, size_t buflen,
2218  const nlib_utf8_t* utf8) NLIB_NONNULL_4;
2220 errno_t nlib_utf32_to_utf8(size_t* utf8count, nlib_utf8_t* utf8, size_t buflen,
2221  const nlib_utf32_t* utf32) NLIB_NONNULL_4;
2223 errno_t nlib_utf8_to_utf32(size_t* utf32count, nlib_utf32_t* utf32, size_t buflen,
2224  const nlib_utf8_t* utf8) NLIB_NONNULL_4;
2225 
2227 errno_t nlib_memutf16_to_utf8(size_t* __restrict to_count, size_t* __restrict from_count,
2228  nlib_utf8_t* __restrict to, size_t to_size,
2229  const nlib_utf16_t* __restrict from, size_t from_size)
2230  NLIB_NONNULL_1 NLIB_NONNULL_2 NLIB_NONNULL_5;
2232 errno_t nlib_memutf8_to_utf16(size_t* __restrict to_count, size_t* __restrict from_count,
2233  nlib_utf16_t* __restrict to, size_t to_size,
2234  const nlib_utf8_t* __restrict from, size_t from_size)
2235  NLIB_NONNULL_1 NLIB_NONNULL_2 NLIB_NONNULL_5;
2237 errno_t nlib_memutf32_to_utf8(size_t* __restrict to_count, size_t* __restrict from_count,
2238  nlib_utf8_t* __restrict to, size_t to_size,
2239  const nlib_utf32_t* __restrict from, size_t from_size)
2240  NLIB_NONNULL_1 NLIB_NONNULL_2 NLIB_NONNULL_5;
2242 errno_t nlib_memutf8_to_utf32(size_t* __restrict to_count, size_t* __restrict from_count,
2243  nlib_utf32_t* __restrict to, size_t to_size,
2244  const nlib_utf8_t* __restrict from, size_t from_size)
2245  NLIB_NONNULL_1 NLIB_NONNULL_2 NLIB_NONNULL_5;
2246 
2247 NLIB_VIS_PUBLIC_ALT
2248 size_t nlib_utf16len_(const uint16_t* str) NLIB_NONNULL;
2249 NLIB_VIS_PUBLIC_ALT
2250 size_t nlib_utf16nlen_(const uint16_t* str, size_t maxsize) NLIB_NONNULL;
2252 errno_t nlib_utf16cpy_(uint16_t* s1, size_t s1max, const uint16_t* s2) NLIB_NONNULL;
2254 errno_t nlib_utf16ncpy_(uint16_t* s1, size_t s1max, const uint16_t* s2, size_t n) NLIB_NONNULL;
2256 size_t nlib_utf16len(const nlib_utf16_t* str) {
2257  return nlib_utf16len_((const uint16_t*)str);
2258 }
2260 size_t nlib_utf16nlen(const nlib_utf16_t* str, size_t maxsize) {
2261  return nlib_utf16nlen_((const uint16_t*)str, maxsize);
2262 }
2263 static NLIB_ALWAYS_INLINE
2264 errno_t nlib_utf16cpy(nlib_utf16_t* s1, size_t s1max, const nlib_utf16_t* s2) {
2265  return nlib_utf16cpy_((uint16_t*)s1, s1max, (const uint16_t*)s2); // NOLINT
2266 }
2267 static NLIB_ALWAYS_INLINE
2268 errno_t nlib_utf16ncpy(nlib_utf16_t* s1, size_t s1max, const nlib_utf16_t* s2, size_t n) {
2269  return nlib_utf16ncpy_((uint16_t*)s1, s1max, (const uint16_t*)s2, n); // NOLINT
2270 }
2271 
2272 NLIB_VIS_PUBLIC_ALT
2273 size_t nlib_utf32len_(const uint32_t* str) NLIB_NONNULL;
2274 NLIB_VIS_PUBLIC_ALT
2275 size_t nlib_utf32nlen_(const uint32_t* str, size_t maxsize) NLIB_NONNULL;
2277 errno_t nlib_utf32cpy_(uint32_t* s1, size_t s1max, const uint32_t* s2) NLIB_NONNULL;
2279 errno_t nlib_utf32ncpy_(uint32_t* s1, size_t s1max, const uint32_t* s2, size_t n) NLIB_NONNULL;
2281 size_t nlib_utf32len(const nlib_utf32_t* str) {
2282  return nlib_utf32len_((const uint32_t*)str);
2283 }
2285 size_t nlib_utf32nlen(const nlib_utf32_t* str, size_t maxsize) {
2286  return nlib_utf32nlen_((const uint32_t*)str, maxsize);
2287 }
2288 static NLIB_ALWAYS_INLINE
2289 errno_t nlib_utf32cpy(nlib_utf32_t* s1, size_t s1max, const nlib_utf32_t* s2) {
2290  return nlib_utf32cpy_((uint32_t*)s1, s1max, (const uint32_t*)s2); // NOLINT
2291 }
2292 static NLIB_ALWAYS_INLINE
2293 errno_t nlib_utf32ncpy(nlib_utf32_t* s1, size_t s1max, const nlib_utf32_t* s2, size_t n) {
2294  return nlib_utf32ncpy_((uint32_t*)s1, s1max, (const uint32_t*)s2, n); // NOLINT
2295 }
2296 
2297 NLIB_CHECK_RESULT NLIB_VIS_PUBLIC_ALT
2298 errno_t nlib_utf16cplen_ex_(size_t* count, size_t* len, const uint16_t* str) NLIB_NONNULL_3;
2299 
2300 static NLIB_ALWAYS_INLINE
2301 errno_t nlib_utf16cplen(size_t* count, const nlib_utf16_t* str) {
2302  return nlib_utf16cplen_ex_(count, NULL, (const uint16_t*)str);
2303 }
2304 static NLIB_ALWAYS_INLINE
2305 errno_t nlib_utf16cplen_ex(size_t* count, size_t* len, const nlib_utf16_t* str) {
2306  return nlib_utf16cplen_ex_(count, len, (const uint16_t*)str);
2307 }
2309 errno_t nlib_utf32cplen(size_t* count, const nlib_utf32_t* str) NLIB_NONNULL_2;
2310 
2311 #if defined(CAFE) || defined(NN_PLATFORM_CTR)
2312 static NLIB_ALWAYS_INLINE uint16_t nlib_bswap16(uint16_t x) {
2313  return ((x & 0xFF) << 8) | ((x >> 8) & 0xFF);
2314 }
2315 static NLIB_ALWAYS_INLINE uint32_t nlib_bswap32(uint32_t x) {
2316  return (x << 24) | ((x & 0xFF00U) << 8) | ((x >> 8) & 0xFF00U) | (x >> 24);
2317 }
2318 static NLIB_ALWAYS_INLINE uint64_t nlib_bswap64(uint64_t x) {
2319  return (x << 56) |
2320  ((x & 0xFF00U) << 40) |
2321  ((x & 0xFF0000U) << 24) |
2322  ((x & 0xFF000000U) << 8) |
2323  ((x >> 8) & 0xFF000000U) |
2324  ((x >> 24) & 0xFF0000U) |
2325  ((x >> 40) & 0xFF00U) |
2326  (x >> 56);
2327 }
2328 #elif defined(_MSC_VER)
2329 static NLIB_ALWAYS_INLINE uint16_t nlib_bswap16(uint16_t x) { return _byteswap_ushort(x); }
2330 static NLIB_ALWAYS_INLINE uint32_t nlib_bswap32(uint32_t x) { return _byteswap_ulong(x); }
2331 static NLIB_ALWAYS_INLINE uint64_t nlib_bswap64(uint64_t x) { return _byteswap_uint64(x); }
2332 #else
2333 static NLIB_ALWAYS_INLINE uint16_t nlib_bswap16(uint16_t x) { return __builtin_bswap16(x); }
2334 static NLIB_ALWAYS_INLINE uint32_t nlib_bswap32(uint32_t x) { return __builtin_bswap32(x); }
2335 static NLIB_ALWAYS_INLINE uint64_t nlib_bswap64(uint64_t x) { return __builtin_bswap64(x); }
2336 #endif
2337 
2338 // for (0..count) { swapendian(p[count]); }
2339 NLIB_VIS_PUBLIC_ALT errno_t nlib_swapendian_16(uint16_t* p, size_t count) NLIB_NONNULL;
2340 // for (0..count) { swapendian(p[count]); }
2341 NLIB_VIS_PUBLIC_ALT errno_t nlib_swapendian_32(uint32_t* p, size_t count) NLIB_NONNULL;
2342 // for (0..count) { swapendian(p[count]); }
2343 NLIB_VIS_PUBLIC_ALT errno_t nlib_swapendian_64(uint64_t* p, size_t count) NLIB_NONNULL;
2344 
2345 //
2346 // malloc functions which nlib uses
2347 // You can redefine them.
2348 // See sample replace_malloc.cpp of nlibnx_heap.a library.
2349 //
2350 
2351 // weak function
2352 NLIB_CHECK_RESULT NLIB_VIS_PUBLIC_ALT
2353 void* nlib_malloc(size_t size) NLIB_ATTRIBUTE_MALLOC NLIB_ATTRIBUTE_ALLOC_SIZE1(1);
2354 
2355 // weak function
2356 NLIB_VIS_PUBLIC_ALT void nlib_free(void* ptr);
2357 
2358 // weak function
2359 NLIB_CHECK_RESULT NLIB_VIS_PUBLIC_ALT
2360 void* nlib_calloc(size_t nmemb, size_t size)
2361  NLIB_ATTRIBUTE_MALLOC NLIB_ATTRIBUTE_ALLOC_SIZE2(1, 2);
2362 
2363 // weak function
2364 NLIB_CHECK_RESULT NLIB_VIS_PUBLIC_ALT
2365 void* nlib_realloc(void* ptr, size_t size) NLIB_ATTRIBUTE_MALLOC NLIB_ATTRIBUTE_ALLOC_SIZE1(2);
2366 
2367 // weak function, not defined if CAFE or CTR
2368 NLIB_VIS_PUBLIC size_t nlib_malloc_size(const void* ptr) NLIB_NONNULL;
2369 
2370 // weak function(calls nlib_free(ptr) by default)
2371 NLIB_VIS_PUBLIC_ALT void nlib_free_size(void* ptr, size_t size);
2372 
2373 // weak function, not defined if WIN32 or CTR
2374 NLIB_CHECK_RESULT NLIB_VIS_PUBLIC_ALT
2375 void* nlib_memalign(size_t alignment, size_t size)
2376  NLIB_ATTRIBUTE_MALLOC NLIB_ATTRIBUTE_ALLOC_SIZE1(2) NLIB_ATTRIBUTE_ALLOC_ALIGN(1);
2377 
2378 #ifndef NLIB_MEMCPY
2379 # define NLIB_MEMCPY(a, b, c) memcpy((a), (b), (c))
2380 #endif
2381 
2382 #ifndef NLIB_MEMMOVE
2383 # define NLIB_MEMMOVE(a, b, c) memmove((a), (b), (c))
2384 #endif
2385 
2386 #ifndef NLIB_MEMSET
2387 # define NLIB_MEMSET(a, b, c) memset((a), (b), (c))
2388 #endif
2389 
2390 // ctype.h without locale
2391 static int nlib_isalnum(int ch) NLIB_ATTRIBUTE_CONST;
2392 static int nlib_isalpha(int ch) NLIB_ATTRIBUTE_CONST;
2393 static int nlib_isblank(int ch) NLIB_ATTRIBUTE_CONST;
2394 static int nlib_iscntrl(int ch) NLIB_ATTRIBUTE_CONST;
2395 static int nlib_isdigit(int ch) NLIB_ATTRIBUTE_CONST;
2396 static int nlib_isgraph(int ch) NLIB_ATTRIBUTE_CONST;
2397 static int nlib_islower(int ch) NLIB_ATTRIBUTE_CONST;
2398 static int nlib_isprint(int ch) NLIB_ATTRIBUTE_CONST;
2399 static int nlib_ispunct(int ch) NLIB_ATTRIBUTE_CONST;
2400 static int nlib_isspace(int ch) NLIB_ATTRIBUTE_CONST;
2401 static int nlib_isupper(int ch) NLIB_ATTRIBUTE_CONST;
2402 static int nlib_isxdigit(int ch) NLIB_ATTRIBUTE_CONST;
2403 static int nlib_tolower(int ch) NLIB_ATTRIBUTE_CONST;
2404 static int nlib_toupper(int ch) NLIB_ATTRIBUTE_CONST;
2405 
2406 static NLIB_C_INLINE int nlib_isalnum(int ch) {
2407  return ('0' <= ch && ch <= '9') || ('A' <= ch && ch <= 'Z') || ('a' <= ch && ch <= 'z');
2408 }
2409 static NLIB_C_INLINE int nlib_isalpha(int ch) {
2410  return ('A' <= ch && ch <= 'Z') || ('a' <= ch && ch <= 'z');
2411 }
2412 static NLIB_C_INLINE int nlib_isblank(int ch) { return ch == ' ' || ch == '\t'; }
2413 static NLIB_C_INLINE int nlib_iscntrl(int ch) { return (ch >= 0 && ch <= 0x1F) || ch == 0x7F; }
2414 static NLIB_C_INLINE int nlib_isdigit(int ch) { return ('0' <= ch && ch <= '9'); }
2415 static NLIB_C_INLINE int nlib_isgraph(int ch) { return ch >= 0x21 && ch <= 0x7E; }
2416 static NLIB_C_INLINE int nlib_islower(int ch) { return (ch >= 'a' && ch <= 'z'); }
2417 static NLIB_C_INLINE int nlib_isprint(int ch) { return ch >= 0x20 && ch <= 0x7E; }
2418 static NLIB_C_INLINE int nlib_ispunct(int ch) { return (ch >= 0x00 && ch <= 0x20) || ch == 0x7F; }
2419 static NLIB_C_INLINE int nlib_isspace(int ch) {
2420  return ((ch) == ' ' || (ch) == '\t' || (ch) == '\n');
2421 }
2422 static NLIB_C_INLINE int nlib_isupper(int ch) { return (ch >= 'A' && ch <= 'Z'); }
2423 static NLIB_C_INLINE int nlib_isxdigit(int ch) {
2424  return (unsigned int)(ch - '0') < 10u ||
2425  (unsigned int)((ch | 0x20) - 'a') < 6u;
2426 }
2427 static NLIB_C_INLINE int nlib_tolower(int ch) {
2428  return (ch >= 'A' && ch <= 'Z') ? ch + ('a' - 'A') : ch;
2429 }
2430 static NLIB_C_INLINE int nlib_toupper(int ch) {
2431  return (ch >= 'a' && ch <= 'z') ? ch - ('a' - 'A') : ch;
2432 }
2433 // no isascii, toascii
2434 
2435 // memcpy_s
2436 static NLIB_C_INLINE
2437 errno_t nlib_memcpy(void* __restrict s1, size_t s1max, const void* __restrict s2, size_t n) {
2438 #if defined(_MSC_VER) || defined(__STDC_LIB_EXT1__)
2439  return memcpy_s(s1, s1max, s2, n);
2440 #else
2441 #ifndef NLIB_NONNULL_ENABLED
2442  if (!s1 || !s2) return ERANGE;
2443 #endif
2444  if (s1max < n) {
2445  NLIB_MEMSET(s1, 0, s1max);
2446  return ERANGE;
2447  }
2448  NLIB_MEMCPY(s1, s2, n);
2449  return 0;
2450 #endif
2451 }
2452 
2453 // memmove_s
2454 static NLIB_C_INLINE
2455 errno_t nlib_memmove(void* s1, size_t s1max, const void* s2, size_t n) {
2456 #if defined(_MSC_VER) || defined(__STDC_LIB_EXT1__)
2457  return memmove_s(s1, s1max, s2, n);
2458 #else
2459 #ifndef NLIB_NONNULL_ENABLED
2460  if (!s1 || !s2) return ERANGE;
2461 #endif
2462  if (s1max < n) return ERANGE;
2463  NLIB_MEMMOVE(s1, s2, n);
2464  return 0;
2465 #endif
2466 }
2467 
2468 static NLIB_C_INLINE
2469 errno_t nlib_memset(void* buf, int ch, size_t n) {
2470  NLIB_EINVAL_IFNULL(buf);
2471  NLIB_MEMSET(buf, ch, n);
2472  return 0;
2473 }
2474 
2475 static int nlib_popcnt16(uint16_t x) NLIB_ATTRIBUTE_CONST;
2476 static int nlib_popcnt32(uint32_t x) NLIB_ATTRIBUTE_CONST;
2477 static int nlib_popcnt64(uint64_t x) NLIB_ATTRIBUTE_CONST;
2478 #if defined(NLIB_SSE42)
2479 static NLIB_ALWAYS_INLINE int nlib_popcnt16(uint16_t x) {
2480  return _mm_popcnt_u32(x);
2481 }
2482 static NLIB_ALWAYS_INLINE int nlib_popcnt32(uint32_t x) {
2483  return _mm_popcnt_u32(x);
2484 }
2485 static NLIB_ALWAYS_INLINE int nlib_popcnt64(uint64_t x) {
2486 #ifdef NLIB_64BIT
2487  return (int)_mm_popcnt_u64(x); // NOLINT
2488 #else
2489  uint32_t lo = (uint32_t)(x & 0xFFFFFFFFU); // NOLINT
2490  uint32_t hi = (uint32_t)((x >> 32) & 0xFFFFFFFFU); // NOLINT
2491  return _mm_popcnt_u32(lo) + _mm_popcnt_u32(hi); // NOLINT
2492 #endif
2493 }
2494 #elif defined(NLIB_NEON)
2495 static NLIB_ALWAYS_INLINE int nlib_popcnt16(uint16_t x) {
2496  uint8x8_t x0 = vcnt_u8(vreinterpret_u8_u64(vcreate_u64(x)));
2497 #ifdef __aarch64__
2498  return vaddv_u8(x0);
2499 #else
2500  uint8x8_t x1 = vpadd_u8(x0, x0);
2501  return vget_lane_u8(x1, 0);
2502 #endif
2503 }
2504 static NLIB_ALWAYS_INLINE int nlib_popcnt32(uint32_t x) {
2505  uint8x8_t x0 = vcnt_u8(vreinterpret_u8_u64(vcreate_u64(x)));
2506 #ifdef __aarch64__
2507  return vaddv_u8(x0);
2508 #else
2509  uint8x8_t x1 = vpadd_u8(x0, x0);
2510  uint8x8_t x2 = vpadd_u8(x1, x1);
2511  return vget_lane_u8(x2, 0);
2512 #endif
2513 }
2514 static NLIB_ALWAYS_INLINE int nlib_popcnt64(uint64_t x) {
2515  uint8x8_t x0 = vcnt_u8(vreinterpret_u8_u64(vcreate_u64(x)));
2516 #ifdef __aarch64__
2517  return vaddv_u8(x0);
2518 #else
2519  uint8x8_t x1 = vpadd_u8(x0, x0);
2520  uint8x8_t x2 = vpadd_u8(x1, x1);
2521  uint8x8_t x3 = vpadd_u8(x2, x2);
2522  return vget_lane_u8(x3, 0);
2523 #endif
2524 }
2525 #else
2526 extern NLIB_VIS_PUBLIC const unsigned char _nlib_popcnt_array[];
2527 static NLIB_ALWAYS_INLINE int nlib_popcnt32(uint32_t x) {
2528  return _nlib_popcnt_array[(x >> 24) & 0xFF] + _nlib_popcnt_array[(x >> 16) & 0xFF] +
2529  _nlib_popcnt_array[(x >> 8) & 0xFF] + _nlib_popcnt_array[(x)& 0xFF];
2530 }
2531 static NLIB_ALWAYS_INLINE int nlib_popcnt64(uint64_t x) {
2532  return _nlib_popcnt_array[(x >> 56) & 0xFF] + _nlib_popcnt_array[(x >> 48) & 0xFF] +
2533  _nlib_popcnt_array[(x >> 40) & 0xFF] + _nlib_popcnt_array[(x >> 32) & 0xFF] +
2534  _nlib_popcnt_array[(x >> 24) & 0xFF] + _nlib_popcnt_array[(x >> 16) & 0xFF] +
2535  _nlib_popcnt_array[(x >> 8) & 0xFF] + _nlib_popcnt_array[(x)& 0xFF];
2536 }
2537 static NLIB_ALWAYS_INLINE int nlib_popcnt16(uint16_t x) {
2538  return _nlib_popcnt_array[(x >> 8) & 0xFF] + _nlib_popcnt_array[(x)& 0xFF];
2539 }
2540 #endif
2541 
2542 // nlib_clz32(0x80000000) -> 0, nlib_clz32(1) -> 31
2543 static int nlib_clz32(uint32_t x) NLIB_ATTRIBUTE_CONST;
2544 // nlib_ctz32(0x80000000) -> 31, nlib_ctz32(1) -> 0
2545 static int nlib_ctz32(uint32_t x) NLIB_ATTRIBUTE_CONST;
2546 // nlib_clz64(INT64_MIN) -> 0, nlib_clz64(1) -> 63
2547 static int nlib_clz64(uint64_t x) NLIB_ATTRIBUTE_CONST;
2548 // nlib_ctz64(INT64_MIN) -> 63, nlib_ctz64(1) -> 0
2549 static int nlib_ctz64(uint64_t x) NLIB_ATTRIBUTE_CONST;
2550 #if defined(_MSC_VER)
2551 static NLIB_ALWAYS_INLINE int nlib_clz32(uint32_t x) {
2552  DWORD cnt;
2553  return _BitScanReverse(&cnt, x) ? (int)(31 - cnt) : 32; // NOLINT
2554  // return (int)(__lzcnt(x)); // needs haswell+
2555 }
2556 static NLIB_ALWAYS_INLINE int nlib_ctz32(uint32_t x) {
2557  DWORD cnt;
2558  return _BitScanForward(&cnt, x) ? cnt : 32;
2559 }
2560 static NLIB_ALWAYS_INLINE int nlib_clz64(uint64_t x) {
2561 #ifdef NLIB_64BIT
2562  DWORD cnt;
2563  return _BitScanReverse64(&cnt, x) ? (int)(63 - cnt) : 64; // NOLINT
2564  // return (int)(__lzcnt64(x)); // needs haswell+
2565 #else
2566  DWORD cnt;
2567  DWORD dw = (DWORD)(x >> 32);
2568  if (_BitScanReverse(&cnt, dw)) {
2569  return (int)(31 - cnt); // NOLINT
2570  } else {
2571  dw = (DWORD)(x);
2572  return _BitScanReverse(&cnt, dw) ?
2573  (int)(63 - cnt) : 64; // NOLINT
2574  }
2575 #endif
2576 }
2577 static NLIB_ALWAYS_INLINE int nlib_ctz64(uint64_t x) {
2578 #ifdef NLIB_64BIT
2579  DWORD cnt;
2580  return _BitScanForward64(&cnt, x) ? cnt : 64;
2581 #else
2582  DWORD cnt;
2583  DWORD dw = (DWORD)(x);
2584  if (_BitScanForward(&cnt, dw)) {
2585  return (int)(cnt); // NOLINT
2586  } else {
2587  dw = (DWORD)(x >> 32);
2588  return _BitScanForward(&cnt, dw) ?
2589  (int)(32 + cnt) : 64; // NOLINT
2590  }
2591 #endif
2592 }
2593 #elif defined(CAFE)
2594 static NLIB_ALWAYS_INLINE int nlib_clz32(uint32_t x) { return __CLZ32(x); }
2595 static NLIB_ALWAYS_INLINE int nlib_ctz32(uint32_t x) { return 32 - nlib_clz32(~x & (x - 1)); }
2596 static NLIB_ALWAYS_INLINE int nlib_clz64(uint64_t x) {
2597  int cnt;
2598  unsigned int dw = (unsigned int)(x >> 32); // NOLINT
2599  cnt = __CLZ32(dw);
2600  if (cnt < 32) {
2601  return cnt;
2602  } else {
2603  dw = (unsigned int)(x); // NOLINT
2604  cnt = __CLZ32(dw);
2605  return 32 + cnt;
2606  }
2607 }
2608 static NLIB_ALWAYS_INLINE int nlib_ctz64(uint64_t x) { return 64 - nlib_clz64(~x & (x - 1)); }
2609 #elif defined(NN_PLATFORM_CTR)
2610 static NLIB_ALWAYS_INLINE int nlib_clz32(uint32_t x) { return x != 0 ? __builtin_clz(x) : 32; }
2611 static NLIB_ALWAYS_INLINE int nlib_ctz32(uint32_t x) { return 32 - nlib_clz32(~x & (x - 1)); }
2612 static NLIB_ALWAYS_INLINE int nlib_clz64(uint64_t x) { return x != 0 ? __builtin_clzll(x) : 64; }
2613 static NLIB_ALWAYS_INLINE int nlib_ctz64(uint64_t x) { return 64 - nlib_clz64(~x & (x - 1)); }
2614 #else
2615 static NLIB_ALWAYS_INLINE int nlib_clz32(uint32_t x) { return x != 0 ? __builtin_clz(x) : 32; }
2616 static NLIB_ALWAYS_INLINE int nlib_ctz32(uint32_t x) { return x != 0 ? __builtin_ctz(x) : 32; }
2617 static NLIB_ALWAYS_INLINE int nlib_clz64(uint64_t x) { return x != 0 ? __builtin_clzll(x) : 64; }
2618 static NLIB_ALWAYS_INLINE int nlib_ctz64(uint64_t x) { return x != 0 ? __builtin_ctzll(x) : 64; }
2619 #endif
2620 
2621 static size_t nlib_strlcpy(char* __restrict s1, const char* __restrict s2, size_t s1max)
2622  NLIB_NONNULL;
2623 static NLIB_C_INLINE
2624 size_t nlib_strlcpy(char* __restrict s1, const char* __restrict s2, size_t s1max) {
2625 #if defined(__FreeBSD__)
2626  return strlcpy(s1, s2, s1max);
2627 #else
2628  size_t len = nlib_strlen(s2);
2629  if (NLIB_LIKELY(len < s1max)) {
2630  NLIB_MEMCPY(s1, s2, len + 1);
2631  } else if (NLIB_LIKELY(s1max > 0)) {
2632  NLIB_MEMCPY(s1, s2, s1max - 1);
2633  s1[s1max - 1] = '\0';
2634  }
2635  return len;
2636 #endif
2637 }
2638 
2639 static uint32_t nlib_bitreverse32(uint32_t x) NLIB_ATTRIBUTE_CONST;
2640 static uint64_t nlib_bitreverse64(uint64_t x) NLIB_ATTRIBUTE_CONST;
2641 
2642 static NLIB_ALWAYS_INLINE uint32_t nlib_bitreverse32(uint32_t x) {
2643 #if __has_builtin(__builtin_bitreverse32)
2644  return __builtin_bitreverse32(x);
2645 #elif __has_builtin(__builtin_arm_rbit)
2646  return __builtin_arm_rbit(x);
2647 #elif defined(__arm__) && !defined(NN_PLATFORM_CTR)
2648  return __rbit(x);
2649 #else
2650  x = ((x & 0x55555555U) << 1) | ((x >> 1) & 0x55555555U);
2651  x = ((x & 0x33333333U) << 2) | ((x >> 2) & 0x33333333U);
2652  x = ((x & 0x0F0F0F0FU) << 4) | ((x >> 4) & 0x0F0F0F0FU);
2653 #ifdef _MSC_VER
2654  x = _byteswap_ulong(x);
2655 #elif defined(CAFE) || defined(NN_PLATFORM_CTR)
2656  x = (x << 24) | ((x & 0xFF00) << 8) |
2657  ((x >> 8) & 0xFF00) | (x >> 24);
2658 #else
2659  x = __builtin_bswap32(x);
2660 #endif
2661  return x;
2662 #endif
2663 }
2664 
2665 static NLIB_ALWAYS_INLINE uint64_t nlib_bitreverse64(uint64_t x) {
2666 #if __has_builtin(__builtin_bitreverse64)
2667  return __builtin_bitreverse64(x);
2668 #elif __has_builtin(__builtin_arm_rbit64)
2669  return __builtin_arm_rbit64(x);
2670 #elif __has_builtin(__builtin_arm_rbit)
2671  return __builtin_arm_rbit(x >> 32) |
2672  (((uint64_t)__builtin_arm_rbit(x)) << 32);
2673 #elif defined(__arm__) && !defined(NN_PLATFORM_CTR)
2674  return __rbit(x >> 32) |
2675  (((uint64_t)__rbit(x)) << 32);
2676 #else
2677  x = ((x & 0x5555555555555555ULL) << 1) | ((x >> 1) & 0x5555555555555555ULL);
2678  x = ((x & 0x3333333333333333ULL) << 2) | ((x >> 2) & 0x3333333333333333ULL);
2679  x = ((x & 0x0F0F0F0F0F0F0F0FULL) << 4) | ((x >> 4) & 0x0F0F0F0F0F0F0F0FULL);
2680 #ifdef _MSC_VER
2681  x = _byteswap_uint64(x);
2682 #elif defined(CAFE) || defined(NN_PLATFORM_CTR)
2683  x =
2684  (x << 56) |
2685  ((x & 0xFF00U) << 40) |
2686  ((x & 0xFF0000U) << 24) |
2687  ((x & 0xFF000000U) << 8) |
2688  ((x >> 8) & 0xFF000000U) |
2689  ((x >> 24) & 0xFF0000U) |
2690  ((x >> 40) & 0xFF00U) |
2691  (x >> 56);
2692 #else
2693  x = __builtin_bswap64(x);
2694 #endif
2695  return x;
2696 #endif
2697 }
2698 
2699 #undef NLIB_MEMCPY
2700 #undef NLIB_MEMMOVE
2701 #undef NLIB_MEMSET
2702 
2703 #ifdef __cplusplus
2704 }
2705 #endif
2706 
2707 #if defined(_MSC_VER)
2708 #if defined(n_EXPORTS)
2709 #undef NLIB_VIS_PUBLIC
2710 #define NLIB_VIS_PUBLIC NLIB_WINIMPORT
2711 #elif defined(nx_misc_EXPORTS)
2712 # undef NLIB_VIS_PUBLIC
2713 # define NLIB_VIS_PUBLIC NLIB_WINEXPORT
2714 #endif
2715 #endif
2716 
2717 #endif // INCLUDE_NN_NLIB_PLATFORM_H_
errno_t nlib_rwlock_rdunlock(nlib_rwlock *rwlock) NLIB_RELEASE_SHARED(*rwlock)
Releases the read lock.
Specifies all priority levels. Can be used with the nlib_log_attr_setint function.
Definition: Platform.h:1423
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_utf8_to_utf32(size_t *utf32count, nlib_utf32_t *utf32, size_t buflen, const nlib_utf8_t *utf8)
Converts a UTF-8 string into a UTF-32 string.
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:1762
#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:513
#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...
static errno_t nlib_utf16ncpy(nlib_utf16_t *s1, size_t s1max, const nlib_utf16_t *s2, size_t n)
The UTF-16 version of the nlib_strcpy function.
Definition: Platform.h:2268
static size_t nlib_utf16len(const nlib_utf16_t *str)
Counts the number of nlib_utf16_t-type characters, not including the null character.
Definition: Platform.h:2256
errno_t nlib_wcscplen(size_t *count, const wchar_t *str)
Gets the number of code points in the string.
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.
Specifies the output of warning-level messages.
Definition: Platform.h:1417
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:2422
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 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:1547
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:2469
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...
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:97
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:498
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:875
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:1179
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:2409
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.
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:1501
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.
sem_t nlib_semaphore
The type for a semaphore object.
errno_t nlib_uint64_from_chars(uint64_t *result, const char **endptr, const char *first, const char *last, int base)
Converts a string to the uint64_t type. For more information, refer to the description for nlib_int32...
errno_t nlib_mutex_recursive_timed_init(nlib_mutex *mutex) NLIB_EXCLUDES(*mutex)
Initializes a mutex that is recursive and can time out.
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.
Specifies the output of debug-level messages.
Definition: Platform.h:1415
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...
errno_t nlib_memcplen(size_t *codepoint_count, size_t *supplementary_codepoint_count, size_t *from_read, const nlib_utf8_t *from, size_t from_size)
Gets the number of code points contained in the string and the number of supplementary characters con...
Specifies the output of error-level messages.
Definition: Platform.h:1418
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.
errno_t nlib_utf8_to_utf16(size_t *utf16count, nlib_utf16_t *utf16, size_t buflen, const nlib_utf8_t *utf8)
Converts a UTF-8 string into a UTF-16 string. The UTF-16 string is null-terminated.
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.
static uint16_t nlib_bswap16(uint16_t x)
Returns __builtin_bswap16(x) or _byteswap_ushort(x).
Definition: Platform.h:2333
nlib_log_priority
Defines the priority (level category) for output.
Definition: Platform.h:1411
#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.
Uses a bitwise OR to output levels at and below the specified level. Can be used with the nlib_log_at...
Definition: Platform.h:1422
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.
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:2417
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:522
errno_t nlib_fd_fileid(nlib_fileid *result, nlib_fd fd)
errno_t nlib_cond_init(nlib_cond *cond)
Initializes a condition variable.
errno_t nlib_float_from_chars(float *result, const char **endptr, const char *first, const char *last)
Converts a string to the float type. For more information, refer to the description for nlib_double_f...
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:2430
struct nlib_thread_attr_ nlib_thread_attr
The thread attribute to apply to a newly created thread.
Definition: Platform.h:1237
int nlib_utf32char_to_utf16(nlib_utf16_t *upper, nlib_utf16_t *lower, nlib_utf32_t utf32)
Converts a single UTF-32 character into UTF-16.
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:2423
static int nlib_popcnt64(uint64_t x)
Returns the number of bits that are 1.
Definition: Platform.h:2485
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.
#define NLIB_UNLIKELY(x)
Indicates to the compiler that condition x is likely to be false.
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.
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...
errno_t nlib_rename(const char *old_path, const char *new_path)
Renames a file.
errno_t nlib_fd_getsize(nlib_offset *size, nlib_fd fd)
Gets the file size.
#define nlib_getversion
Dynamically gets the nlib version.
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.
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:329
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...
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:457
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.
static size_t nlib_utf32len(const nlib_utf32_t *str)
Counts the number of nlib_utf32_t-type characters, not including the null character.
Definition: Platform.h:2281
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...
static errno_t nlib_ticktime_timespec(struct timespec *tm)
A version taking the timespec structure as the argument of nlib_ticktime().
Definition: Platform.h:490
errno_t nlib_fd_close(nlib_fd fd)
Closes a file. The file descriptor will be released even if an error is returned. ...
errno_t nlib_thread_attr_setint(nlib_thread_attr *attr, int key, int value)
Sets an integer corresponding to the key of the thread attribute object.
int nlib_atomic_compare_exchange64(int64_t *ptr, int64_t *expected, int64_t desired, int weak, int success_memorder, int failure_memorder)
Compares and swaps atomic values. Its behavior is similar to the one for __atomic_compare_exchange_n(...
static int nlib_clz32(uint32_t x)
Returns the number of consecutive zero bits, with respect to the most significant bit (MSB)...
Definition: Platform.h:2615
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:850
errno_t nlib_uint8_from_chars(uint8_t *result, const char **endptr, const char *first, const char *last, int base)
Converts a string to the uint8_t type. For more information, refer to the description for nlib_int32_...
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().
void(* nlib_oncefunc)(void)
The type for functions to execute with nlib_once.
Definition: Platform.h:1129
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:89
static errno_t nlib_utf32cpy(nlib_utf32_t *s1, size_t s1max, const nlib_utf32_t *s2)
The UTF-32 version of the nlib_strcpy function.
Definition: Platform.h:2289
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:482
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.
errno_t nlib_gen_random(void *buf, size_t size)
Generates a random value of size bytes and stores it in buf.
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...
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:1177
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:264
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:858
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:1480
errno_t nlib_strcplen(size_t *codepoint_count, size_t *supplementary_codepoint_count, size_t *len, const nlib_utf8_t *str)
Gets the number of code points contained in the string, the number of supplementary characters contai...
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.
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.
errno_t nlib_utf32_to_utf8(size_t *utf8count, nlib_utf8_t *utf8, size_t buflen, const nlib_utf32_t *utf32)
Converts a UTF-32 string into a UTF-8 string.
uint32_t nlib_utf32_t
Uses typedef to define as char32_t if that can be used. If not, it uses typedef to define as uint32_t...
Definition: Platform.h:294
static errno_t nlib_utf16cpy(nlib_utf16_t *s1, size_t s1max, const nlib_utf16_t *s2)
The UTF-16 version of the nlib_strcpy function.
Definition: Platform.h:2264
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.
errno_t nlib_tls_alloc(nlib_tls *tls, nlib_tls_destructor destr)
Allocates a new ID for the specified TLS slot.
errno_t nlib_int32_from_chars(int32_t *result, const char **endptr, const char *first, const char *last, int base)
Converts a string to the int32_t type.
int nlib_fd
The original file descriptor of nlib (a 32-bit integer value).
Definition: Platform.h:1536
Specifies the output of information-level messages.
Definition: Platform.h:1416
errno_t nlib_utf32cplen(size_t *count, const nlib_utf32_t *str)
Gets the number of code points in the string.
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:1161
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...
static uint64_t nlib_bswap64(uint64_t x)
Returns __builtin_bswap64(x) or _byteswap_uint64(x).
Definition: Platform.h:2335
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 ...
errno_t nlib_mq_getattr(nlib_mq mq, nlib_mq_attr *attr)
Obtains the attribute set to the message queue indicated with a handle.
static errno_t nlib_utf16cplen_ex(size_t *count, size_t *len, const nlib_utf16_t *str)
Gets the number of code points in the string.
Definition: Platform.h:2305
errno_t nlib_int8_from_chars(int8_t *result, const char **endptr, const char *first, const char *last, int base)
Converts a string to the int8_t type. For more information, refer to the description for nlib_int32_f...
int nlib_utf8_to_utf32char(nlib_utf32_t *utf32, const nlib_utf8_t *utf8)
Converts UTF-8 into one character&#39;s worth of UTF-32.
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().
uint16_t nlib_utf16_t
Uses typedef to define as char16_t if that can be used. If not, it uses typedef to define as uint16_t...
Definition: Platform.h:293
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:2618
errno_t nlib_memutf8_to_utf32(size_t *to_count, size_t *from_count, nlib_utf32_t *to, size_t to_size, const nlib_utf8_t *from, size_t from_size) NLIB_NONNULL_5
Converts a UTF-8 string that is not null terminated to a UTF-32 string.
errno_t nlib_memutf16_to_utf8(size_t *to_count, size_t *from_count, nlib_utf8_t *to, size_t to_size, const nlib_utf16_t *from, size_t from_size) NLIB_NONNULL_5
Converts a UTF-16 string that is not null terminated to a UTF-8 string.
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...
static int nlib_popcnt16(uint16_t x)
Returns the number of bits that are 1.
Definition: Platform.h:2479
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:1064
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:99
uint32_t nlib_crc32c(uint32_t crc32c, const void *p, size_t n)
This function calculates the CRC-32C checksum value for data.
errno_t nlib_int64_from_chars(int64_t *result, const char **endptr, const char *first, const char *last, int base)
Converts a string to the int64_t type. For more information, refer to the description for nlib_int32_...
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:2406
static errno_t nlib_utf32ncpy(nlib_utf32_t *s1, size_t s1max, const nlib_utf32_t *s2, size_t n)
The UTF-32 version of the nlib_strcpy function.
Definition: Platform.h:2293
uint32_t nlib_timer
The ID of the timer used with nlib_timer_create() and nlib_timer_delete().
Definition: Platform.h:505
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...
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:1091
static void nlib_spinlock_init(nlib_spinlock *lock)
Initializes the spinlock.
Definition: Platform.h:1698
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().
errno_t nlib_wide_to_utf8(size_t *utf8count, nlib_utf8_t *utf8, size_t buflen, const wchar_t *wcstr)
Converts a UTF-16/UTF-32 string into a UTF-8 string.
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...
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:2437
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:2616
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:1515
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:1073
Uses a bitwise OR to output levels at and above the specified level. Can be used with the nlib_log_at...
Definition: Platform.h:1421
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:2642
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:2665
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...
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:2419
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:1731
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:2412
Specifies the output of fatal-level messages.
Definition: Platform.h:1419
#define nlib_yield
Relinquishes thread execution rights.
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:1175
int nlib_utf16_to_utf32char(nlib_utf32_t *utf32, nlib_utf16_t upper, nlib_utf16_t lower)
Converts a single code point from UTF-16 into UTF-32.
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.
#define nlib_compiler_version
Dynamically obtains the compiler version used to compile nlib.
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:1245
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:1211
errno_t nlib_semaphore_init(nlib_semaphore *sem, int initial_count)
Initializes the semaphore object specified by sem.
#define nlib_debug_break
A breakpoint.
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:2415
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:2416
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_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.
#define nlib_get_native_last_error
Returns the last generated native error code.
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.
errno_t nlib_utf8_to_wide(size_t *wccount, wchar_t *wcstr, size_t buflen, const nlib_utf8_t *utf8)
Converts a UTF-8 string into a UTF-16/UTF-32 string.
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:2418
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.
static size_t nlib_utf32nlen(const nlib_utf32_t *str, size_t maxsize)
The UTF-32 version of the nlib_strnlen function.
Definition: Platform.h:2285
void * nlib_realloc(void *ptr, size_t size)
A weak function that calls the C standard function realloc. nlib calls realloc via this function...
errno_t nlib_mq_send(nlib_mq mq, nlib_mq_msg msg, int prio)
Sends a message to a queue.
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:1224
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...
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.
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_memutf8_to_utf16(size_t *to_count, size_t *from_count, nlib_utf16_t *to, size_t to_size, const nlib_utf8_t *from, size_t from_size) NLIB_NONNULL_5
Converts a UTF-8 string that is not null terminated to a UTF-16 string.
errno_t nlib_swapendian_32(uint32_t *p, size_t count)
Swaps the endianness.
static errno_t nlib_utf16cplen(size_t *count, const nlib_utf16_t *str)
Gets the number of code points in the string.
Definition: Platform.h:2301
size_t nlib_malloc_size(const void *ptr)
Returns the allocated memory size.
Specifies the output of verbose messages.
Definition: Platform.h:1414
#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:1247
#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.
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 size_t nlib_utf16nlen(const nlib_utf16_t *str, size_t maxsize)
The UTF-16 version of the nlib_strnlen function.
Definition: Platform.h:2260
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:2413
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 ...
errno_t nlib_snprintf(size_t *count, char *buf, size_t size, const char *fmt,...)
A safer form of snprintf.
errno_t nlib_int16_from_chars(int16_t *result, const char **endptr, const char *first, const char *last, int base)
Converts a string to the int16_t type. For more information, refer to the description for nlib_int32_...
errno_t nlib_memutf32_to_utf8(size_t *to_count, size_t *from_count, nlib_utf8_t *to, size_t to_size, const nlib_utf32_t *from, size_t from_size) NLIB_NONNULL_5
Converts a UTF-32 string that is not null terminated to a UTF-8 string.
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...
errno_t nlib_mutex_trylock_for(nlib_mutex *mutex, nlib_duration delta) NLIB_TRY_ACQUIRE(0
Locks the specified mutex. Times out.
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.
void(* nlib_tls_destructor)(void *tls_value)
The type for the TLS destructor function called when the thread is ended.
Definition: Platform.h:562
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().
errno_t nlib_fd_truncate(nlib_fd fd, nlib_offset length)
Extends or truncates the file to be the specified size.
static uint32_t nlib_bswap32(uint32_t x)
Returns __builtin_bswap32(x) or _byteswap_ulong(x).
Definition: Platform.h:2334
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.
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.
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:1127
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.
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:566
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...
errno_t nlib_memwide_to_utf8(size_t *to_count, size_t *from_count, nlib_utf8_t *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...
int64_t nlib_offset
The offset to the file. A 64-bit integer.
Definition: Platform.h:1535
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:1178
int32_t nlib_long_compatible_t
Defines an integer type that is compatible with long using typedef.
Definition: Platform.h:328
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...
unsigned char nlib_byte_t
This type will be defined as std::byte in a typedef of C++17 or later.
Definition: Platform.h:319
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:2455
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:2482
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:742
static void nlib_spinlock_lock(nlib_spinlock *lock)
Locks the spinlock. Behavior is undefined if a recursive lock is performed.
Definition: Platform.h:1701
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:1173
errno_t nlib_tls_getvalue(nlib_tls tls, void **value)
Gets the value from a TLS slot.
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...
errno_t nlib_double_from_chars(double *result, const char **endptr, const char *first, const char *last)
Converts a string to the double type.
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...
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:1176
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.
#define nlib_thread_exit
Ends the called thread.
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_uint16_from_chars(uint16_t *result, const char **endptr, const char *first, const char *last, int base)
Converts a string to the uint16_t type. For more information, refer to the description for nlib_int32...
errno_t nlib_uint32_from_chars(uint32_t *result, const char **endptr, const char *first, const char *last, int base)
Converts a string to the uint32_t type. For more information, refer to the description for nlib_int32...
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:459
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:1167
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:2617
nlib_duration due_time
Specifies the time to elapse before the timer initially starts up.
Definition: Platform.h:521
char nlib_utf8_t
Defines char with a typedef. Indicates that it is a UTF-8 string.
Definition: Platform.h:308
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_utf16_to_utf8(size_t *utf8count, nlib_utf8_t *utf8, size_t buflen, const nlib_utf16_t *utf16)
Converts a UTF-16 string into a UTF-8 string.
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_memutf8_to_wide(size_t *to_count, size_t *from_count, wchar_t *to, size_t to_size, const nlib_utf8_t *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_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.
errno_t nlib_unlink(const char *native_path)
Deletes a file.
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:2427
int nlib_utf32char_to_utf8(nlib_utf8_t(&utf8)[4], nlib_utf32_t utf32)
Converts the UTF-32 for one character into UTF-8.
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:2414
int errno_t
Indicates with an int-type typedef that a POSIX error value is returned as the return value...
Definition: NMalloc.h:37