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