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