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