nlib
Platform.h
[詳解]
1 
2 /*--------------------------------------------------------------------------------*
3  Project: CrossRoad
4  Copyright (C)Nintendo All rights reserved.
5 
6  These coded instructions, statements, and computer programs contain proprietary
7  information of Nintendo and/or its licensed developers and are protected by
8  national and international copyright laws. They may not be disclosed to third
9  parties or copied or duplicated in any form, in whole or in part, without the
10  prior written consent of Nintendo.
11 
12  The content herein is highly confidential and should be handled accordingly.
13  *--------------------------------------------------------------------------------*/
14 
15 #pragma once
16 #ifndef INCLUDE_NN_NLIB_PLATFORM_H_
17 #define INCLUDE_NN_NLIB_PLATFORM_H_
18 
19 #ifdef __ILP64__
20 # error Sorry, ILP64 not supported
21 #endif
22 
23 // Note that the C preprocessor # operator must be able to use.
24 #define NLIB_VERSION_YEAR 2017
25 #define NLIB_VERSION_YEAR_SHORT 17
26 #define NLIB_VERSION_DATE 0516
27 #define NLIB_VERSION 20170516
28 
29 #ifdef __cplusplus
30 # ifndef __STDC_FORMAT_MACROS
31 # ifdef _MSC_VER
32 # pragma message(__FILE__ ": __STDC_FORMAT_MACROS not defined, compile may fail")
33 # elif !defined(NN_PLATFORM_CTR) && !defined(CAFE)
34 # warning __STDC_FORMAT_MACROS not defined, compile may fail
35 # endif
36 # define __STDC_FORMAT_MACROS
37 # endif
38 #endif
39 #ifndef __STDC_WANT_LIB_EXT1__
40 # define __STDC_WANT_LIB_EXT1__ 1
41 #endif
42 
43 #ifndef NLIB_UNUSED
44 # define NLIB_UNUSED(x) (void)(x)
45 #endif
46 
47 #ifndef __has_builtin
48 # define __has_builtin(x) 0
49 #endif
50 
51 #ifndef __has_feature
52 # define __has_feature(x) 0
53 #endif
54 
55 #ifndef __has_cpp_attribute
56 # define __has_cpp_attribute(x) 0
57 #endif
58 
59 #ifndef __has_attribute
60 # define __has_attribute(x) 0
61 #endif
62 
63 #ifndef __has_declspec_attribute
64 # define __has_declspec_attribute(x) 0
65 #endif
66 
67 #ifndef __has_include
68 # define __has_include(x) 0
69 #endif
70 
71 #if __has_feature(thread_sanitizer)
72 # define NLIB_NO_TSAN __attribute__((no_sanitize("thread")))
73 #else
74 # define NLIB_NO_TSAN
75 #endif
76 
77 #if __has_feature(address_sanitizer)
78 # define NLIB_NO_ASAN __attribute__((no_sanitize("address")))
79 #else
80 # define NLIB_NO_ASAN
81 #endif
82 
83 #if __has_feature(memory_sanitizer)
84 # define NLIB_NO_MSAN __attribute__((no_sanitize("memory")))
85 #else
86 # define NLIB_NO_MSAN
87 #endif
88 
89 //
90 // thread safety analysis
91 // http://clang.llvm.org/docs/ThreadSafetyAnalysis.html
92 //
93 #if !defined(NLIB_THREAD_AA_) && defined(__clang__) && \
94  (!defined(SWIG)) && __has_attribute(capability)
95 #define NLIB_THREAD_AA_(x) __attribute__((x))
96 #else
97 #ifdef NLIB_THREAD_AA_
98 #undef NLIB_THREAD_AA_
99 #endif
100 #define NLIB_THREAD_AA_(x)
101 #endif
102 
103 #define NLIB_CAPABILITY(x) NLIB_THREAD_AA_(capability(x))
104 #define NLIB_SCOPED_CAPABILITY NLIB_THREAD_AA_(scoped_lockable)
105 #define NLIB_GUARDED_BY(x) NLIB_THREAD_AA_(guarded_by(x))
106 #define NLIB_PT_GUARDED_BY(x) NLIB_THREAD_AA_(pt_guarded_by(x))
107 #define NLIB_ACQUIRED_BEFORE(...) NLIB_THREAD_AA_(acquired_before(__VA_ARGS__))
108 #define NLIB_ACQUIRED_AFTER(...) NLIB_THREAD_AA_(acquired_after(__VA_ARGS__))
109 #define NLIB_REQUIRES(...) NLIB_THREAD_AA_(requires_capability(__VA_ARGS__))
110 #define NLIB_REQUIRES_SHARED(...) NLIB_THREAD_AA_(requires_shared_capability(__VA_ARGS__))
111 #define NLIB_ACQUIRE(...) NLIB_THREAD_AA_(acquire_capability(__VA_ARGS__))
112 #define NLIB_ACQUIRE_SHARED(...) NLIB_THREAD_AA_(acquire_shared_capability(__VA_ARGS__))
113 #define NLIB_RELEASE(...) NLIB_THREAD_AA_(release_capability(__VA_ARGS__))
114 #define NLIB_RELEASE_SHARED(...) NLIB_THREAD_AA_(release_shared_capability(__VA_ARGS__))
115 #define NLIB_TRY_ACQUIRE(...) NLIB_THREAD_AA_(try_acquire_capability(__VA_ARGS__))
116 #define NLIB_TRY_ACQUIRE_SHARED(...) NLIB_THREAD_AA_(try_acquire_shared_capability(__VA_ARGS__))
117 #define NLIB_EXCLUDES(...) NLIB_THREAD_AA_(locks_excluded(__VA_ARGS__))
118 #define NLIB_ASSERT_CAPABILITY(x) NLIB_THREAD_AA_(assert_capability(x))
119 #define NLIB_ASSERT_SHARED_CAPABILITY(x) NLIB_THREAD_AA_(assert_shared_capability(x))
120 #define NLIB_RETURN_CAPABILITY(x) NLIB_THREAD_AA_(lock_returned(x))
121 #define NLIB_NO_THREAD_SAFETY_ANALYSIS NLIB_THREAD_AA_(no_thread_safety_analysis)
122 
123 #include <stddef.h> // for size_t
124 #include <stdio.h> // for SEEK_CUR, SEEK_END, SEEK_SET
125 #include <stdarg.h> // for va_list
126 #include <string.h> // for memcpy, memmove, memset
127 #include <time.h> // for struct timespec
128 
129 #if defined(NLIB_RENAME_CAPI)
130 #include "nn/nlib/Platform_rename.h"
131 #else
132 #ifdef NLIB_CAPI
133 #undef NLIB_CAPI
134 #endif
135 #define NLIB_CAPI(x) x
136 #endif
137 
138 #define NLIB_STRINGIFY_(s) #s
139 #define NLIB_STRINGIFY(s) NLIB_STRINGIFY_(s)
140 
141 #if defined(_MSC_VER)
142 # include "nn/nlib/Platform_win32.h"
143 #elif defined(__linux__) || \
144  defined(__FreeBSD__) || \
145  defined(__CYGWIN__) || \
146  (defined(__APPLE__) && defined(__MACH__))
147 # ifndef NLIB_UNIX
148 # define NLIB_UNIX
149 # endif
150 # include "nn/nlib/Platform_unix.h"
151 #elif defined(NN_PLATFORM_CTR)
152 # include "nn/nlib/Platform_ctr.h"
153 #elif defined(CAFE)
154 # include "nn/nlib/Platform_cafe.h"
155 #elif defined(__NX__)
156 # include "nn/nlib/Platform_nx.h"
157 #endif
158 
159 #if defined(_MSC_VER) && defined(n_EXPORTS)
160 #undef NLIB_VIS_PUBLIC
161 #define NLIB_VIS_PUBLIC NLIB_WINEXPORT
162 #endif
163 
164 #ifndef __analysis_assume
165 # define __analysis_assume(expr)
166 #endif
167 
168 #ifndef _Printf_format_string_
169 # define _Printf_format_string_
170 #endif
171 
172 #if defined(__ARM_NEON__) || defined(__aarch64__)
173 # ifndef NLIB_NEON
174 # define NLIB_NEON
175 # endif
176 #endif
177 
178 #ifdef __SSE4_1__
179 # ifndef NLIB_SSE41
180 # define NLIB_SSE41
181 # endif
182 #endif
183 
184 #ifdef __SSE4_2__
185 # ifndef NLIB_SSE41
186 # define NLIB_SSE41
187 # endif
188 # ifndef NLIB_SSE42
189 # define NLIB_SSE42
190 # endif
191 #endif
192 
193 #if defined(NLIB_SSE41) || defined(NLIB_NEON)
194 # define NLIB_SIMD
195 # ifdef NLIB_NEON
196 # include <arm_neon.h> // NOLINT
197 # endif
198 # ifdef NLIB_SSE41
199 # include <smmintrin.h> // NOLINT
200 # endif
201 # ifdef NLIB_SSE42
202 # include <nmmintrin.h> // NOLINT
203 # endif
204 #endif
205 
206 #if defined(__ARM_ACLE)
207 #include <arm_acle.h>
208 #endif
209 
210 // https://www.jpcert.or.jp/sc-rules/c-int01-c.html
211 // 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
212 #ifndef RSIZE_MAX
213 # ifndef NLIB_64BIT
214 # define RSIZE_MAX 0x7FFFFFFFL
215 # else
216 # define RSIZE_MAX 0x7FFFFFFFFFFFFFFFLL
217 # endif
218 #endif
219 
220 #ifndef NLIB_WARN
221 # define NLIB_WARN(exp) ("WARNING: " exp)
222 // #pragma message NLIB_WARN("your message")
223 #endif
224 
225 // NOTE:
226 // You can use those macros on the environment which printf does not support '%z'
227 // for size_t.
228 // "%"PRIuS, sizet_val
229 // See: https://google-styleguide.googlecode.com/svn/trunk/cppguide.html#64-bit_Portability
230 // In Japanese: http://www.textdrop.net/google-styleguide-ja/cppguide.xml
231 #ifndef __PRIS_PREFIX
232 # define __PRIS_PREFIX "z"
233 #endif
234 
235 #ifndef PRIdS
236 # define PRIdS __PRIS_PREFIX "d"
237 #endif
238 
239 #ifndef PRIxS
240 # define PRIxS __PRIS_PREFIX "x"
241 #endif
242 
243 #ifndef PRIuS
244 # define PRIuS __PRIS_PREFIX "u"
245 #endif
246 
247 #ifndef PRIXS
248 # define PRIXS __PRIS_PREFIX "X"
249 #endif
250 
251 #ifndef PRIoS
252 # define PRIoS __PRIS_PREFIX "o"
253 #endif
254 
255 #ifndef NLIB_ASSUME
256 # define NLIB_ASSUME(cond) switch (0) case 0: default: if (cond) ; else __builtin_unreachable() /* NOLINT */
257 #endif
258 
259 #ifdef NLIB_NONNULL_ENABLED
260 # define NLIB_EINVAL_IFNULL(p)
261 #else
262 # define NLIB_EINVAL_IFNULL(p) if (!p) return EINVAL
263 #endif
264 
265 #ifndef NLIB_C_INLINE
266 # define NLIB_C_INLINE __inline
267 #endif
268 
269 //
270 // Error Type
271 //
272 typedef int errno_t; // TR 24731-1
273 
274 //
275 // stdint
276 //
277 #include <stdint.h> // NOLINT
278 #include <inttypes.h> // NOLINT
279 
280 #ifdef __cplusplus
281 #ifdef NLIB_CXX11_NEW_CHARACTER_TYPES
282 typedef char16_t nlib_utf16_t;
283 typedef char32_t nlib_utf32_t;
284 #else
285 typedef uint16_t nlib_utf16_t;
286 typedef uint32_t nlib_utf32_t;
287 #endif
288 #else
289 // On some devenv, char16_t, char32_t not typedefed in uchar.h
290 // #if __has_include( <uchar.h> )
291 // #include <uchar.h>
292 // typedef char16_t nlib_utf16_t;
293 // typedef char32_t nlib_utf32_t;
294 // #else
295 typedef uint16_t nlib_utf16_t;
296 typedef uint32_t nlib_utf32_t;
297 // #endif
298 #endif
299 
300 typedef char nlib_utf8_t;
301 
302 #ifdef __cplusplus
303 // typedef ::std::byte nlib_byte_t for C++17
304 #ifdef _MSC_VER
305 enum class nlib_byte_t : unsigned char {};
306 #elif __cplusplus >= 201103L
307 enum class nlib_byte_t : unsigned char {};
308 #else
309 typedef unsigned char nlib_byte_t;
310 #endif
311 #else
312 typedef unsigned char nlib_byte_t;
313 #endif
314 
315 #if defined(__LP64__) && __LP64__ == 1
316 // if long, unsinged long are 64 bits long
317 #define NLIB_LP64
318 typedef int64_t nlib_long_compatible_t;
319 typedef uint64_t nlib_ulong_compatible_t;
320 #else
321 typedef int32_t nlib_long_compatible_t;
322 typedef uint32_t nlib_ulong_compatible_t;
323 #endif
324 
325 #ifndef NLIB_VIS_PUBLIC_ALT
326 #define NLIB_VIS_PUBLIC_ALT NLIB_VIS_PUBLIC
327 #endif
328 
329 #ifndef NLIB_EXPIMP_TEMPLATE
330 # define NLIB_EXPIMP_TEMPLATE(x) NLIB_STATIC_ASSERT(sizeof(char) == 1)
331 #endif
332 
333 #ifdef __cplusplus
334 extern "C" {
335 #endif
336 
338 
339 //
340 // Native error
341 //
343 
344 //
345 // Version
346 //
347 
348 // returns NLIB_VERSION
351 
352 // crc32 = 0 at the beginning
353 NLIB_VIS_PUBLIC uint32_t nlib_crc32(uint32_t crc32, const void* p, size_t n);
354 // crc32 = 0 at the beginning
355 NLIB_VIS_PUBLIC uint32_t nlib_crc32c(uint32_t crc32c, const void* p, size_t n);
356 
357 //
358 // Atomic
359 //
360 #if defined(__INTELLISENSE__)
361 #define NLIB_ATOMIC_RELAXED (0)
362 #define NLIB_ATOMIC_ACQUIRE (1)
363 #define NLIB_ATOMIC_RELEASE (2)
364 #define NLIB_ATOMIC_ACQ_REL (3)
365 #define NLIB_ATOMIC_SEQ_CST (7)
366 
367 int32_t nlib_atomic_load32(const int32_t* ptr, int memorder);
368 void nlib_atomic_store32(int32_t* ptr, int32_t val, int memorder);
369 // *target = value, and returns the old value of *target
370 int32_t nlib_atomic_exchange32(int32_t* ptr,
371  int32_t val, int memorder);
372 // *ptr = desired and return non-zero if successful
373 int nlib_atomic_compare_exchange32(int32_t* ptr,
374  int32_t* expected,
375  int32_t desired,
376  int weak,
377  int success_memorder,
378  int failure_memorder);
379 // *ptr += val; return *ptr;
380 int32_t nlib_atomic_add_fetch32(int32_t* ptr, int32_t val, int memorder);
381 // *ptr -= val; return *ptr;
382 int32_t nlib_atomic_sub_fetch32(int32_t* ptr, int32_t val, int memorder);
383 // *ptr &= val; return *ptr;
384 int32_t nlib_atomic_and_fetch32(int32_t* ptr, int32_t val, int memorder);
385 // *ptr ^= val; return *ptr;
386 int32_t nlib_atomic_xor_fetch32(int32_t* ptr, int32_t val, int memorder);
387 // *ptr |= val; return *ptr;
388 int32_t nlib_atomic_or_fetch32(int32_t* ptr, int32_t val, int memorder);
389 // tmp = *ptr; *ptr += val; return tmp;
390 int32_t nlib_atomic_fetch_add32(int32_t* ptr, int32_t val, int memorder);
391 // tmp = *ptr; *ptr -= val; return tmp;
392 int32_t nlib_atomic_fetch_sub32(int32_t* ptr, int32_t val, int memorder);
393 // tmp = *ptr; *ptr &= val; return tmp;
394 int32_t nlib_atomic_fetch_and32(int32_t* ptr, int32_t val, int memorder);
395 // tmp = *ptr; *ptr ^= val; return tmp;
396 int32_t nlib_atomic_fetch_xor32(int32_t* ptr, int32_t val, int memorder);
397 // tmp = *ptr; *ptr |= val; return tmp;
398 int32_t nlib_atomic_fetch_or32(int32_t* ptr, int32_t val, int memorder);
399 
400 int64_t nlib_atomic_load64(const int64_t* ptr, int memorder);
401 void nlib_atomic_store64(int64_t* ptr, int64_t val, int memorder);
402 // *target = value, and returns the old value of *target
403 int64_t nlib_atomic_exchange64(int64_t* ptr, int64_t val, int memorder);
404 // *ptr = desired and return non-zero if successful
405 int nlib_atomic_compare_exchange64(int64_t* ptr, int64_t* expected,
406  int64_t desired, int weak,
407  int success_memorder, int failure_memorder);
408 // *ptr += val; return *ptr;
409 int64_t nlib_atomic_add_fetch64(int64_t* ptr, int64_t val, int memorder);
410 // *ptr -= val; return *ptr;
411 int64_t nlib_atomic_sub_fetch64(int64_t* ptr, int64_t val, int memorder);
412 // *ptr &= val; return *ptr;
413 int64_t nlib_atomic_and_fetch64(int64_t* ptr, int64_t val, int memorder);
414 // *ptr ^= val; return *ptr;
415 int64_t nlib_atomic_xor_fetch64(int64_t* ptr, int64_t val, int memorder);
416 // *ptr |= val; return *ptr;
417 int64_t nlib_atomic_or_fetch64(int64_t* ptr, int64_t val, int memorder);
418 // tmp = *ptr; *ptr += val; return tmp;
419 int64_t nlib_atomic_fetch_add64(int64_t* ptr, int64_t val, int memorder);
420 // tmp = *ptr; *ptr -= val; return tmp;
421 int64_t nlib_atomic_fetch_sub64(int64_t* ptr, int64_t val, int memorder);
422 // tmp = *ptr; *ptr &= val; return tmp;
423 int64_t nlib_atomic_fetch_and64(int64_t* ptr, int64_t val, int memorder);
424 // tmp = *ptr; *ptr ^= val; return tmp;
425 int64_t nlib_atomic_fetch_xor64(int64_t* ptr, int64_t val, int memorder);
426 // tmp = *ptr; *ptr |= val; return tmp;
427 int64_t nlib_atomic_fetch_or64(int64_t* ptr, int64_t val, int memorder);
428 
429 void* nlib_atomic_loadptr(void* const* ptr, int memorder);
430 void nlib_atomic_storeptr(void** ptr, void* val, int memorder);
431 void* nlib_atomic_exchangeptr(void** ptr, void* val, int memorder);
432 // *ptr = desired and return non-zero if successful
433 int nlib_atomic_compare_exchangeptr(void** ptr, void** expected, void* desired,
434  int weak, int success_memorder, int failure_memorder);
435 
436 void nlib_atomic_thread_fence(int memorder);
437 #endif
438 
439 //
440 // Time, Duration
441 //
442 #ifndef NLIB_TIMESPEC_HAS_NATIVE
443 struct timespec {
444  time_t tv_sec;
445  long tv_nsec; // NOLINT
446 };
447 #endif
448 
449 // 100ns => 1, 1970/01/01 == 0
450 typedef int64_t nlib_time;
451 // 100ns => 1, 1ms => 10000
452 typedef int64_t nlib_duration;
453 
454 // 100ns => 1, 1970/01/01 == 0
456 // 100ns => 1, boot time == 0, msec = *t / 10000
458 // 100ns => 1, sleep 1 msec = nlib_sleep(10000)
459 NLIB_VIS_PUBLIC errno_t nlib_sleep(nlib_duration t);
460 
461 #define NLIB_TO_TIMESPEC(tm, t) \
462  (tm)->tv_sec = (time_t)((t) / (1000 * 10000)); \
463  (tm)->tv_nsec = ((long)((t) % (1000 * 10000)) * 100) // NOLINT
464 
465 #define NLIB_FROM_TIMESPEC(tm, t) \
466  t = (int64_t)((tm)->tv_sec) * (1000 * 10000) + ((tm)->tv_nsec / 100)
467 
468 static NLIB_C_INLINE errno_t nlib_epochtime_timespec(struct timespec* tm) {
469  nlib_time t;
470  errno_t e = nlib_epochtime(&t);
471  if (NLIB_UNLIKELY(e != 0)) return e;
472  NLIB_TO_TIMESPEC(tm, t);
473  return 0;
474 }
475 
476 static NLIB_C_INLINE errno_t nlib_ticktime_timespec(struct timespec* tm) {
477  nlib_duration d;
478  errno_t e = nlib_ticktime(&d);
479  if (NLIB_UNLIKELY(e != 0)) return e;
480  NLIB_TO_TIMESPEC(tm, d);
481  return 0;
482 }
483 
484 static NLIB_C_INLINE errno_t nlib_sleep_timespec(const struct timespec* tm) {
485  nlib_duration d;
486  NLIB_FROM_TIMESPEC(tm, d);
487  return nlib_sleep(d);
488 }
489 
490 #if !defined(NLIB_TIMER_HAS_NATIVE)
491 typedef uint32_t nlib_timer;
492 #elif defined(_MSC_VER)
493 typedef HANDLE nlib_timer;
494 #elif defined(__linux__)
495 typedef int nlib_timer;
496 #else
497 # error sorry
498 #endif
499 typedef void (*nlib_timer_callback)(nlib_timer timer, void* param);
500 struct nlib_timerspec_ {
501  nlib_duration due_time;
502  nlib_duration interval;
503 };
504 typedef struct nlib_timerspec_ nlib_timerspec;
505 #ifdef NLIB_DOXYGEN
506 struct nlib_timerspec {
507  nlib_duration due_time;
508  nlib_duration interval;
509 };
510 #endif
512  void* param, uint32_t flags);
513 NLIB_VIS_PUBLIC errno_t nlib_timer_settime(nlib_timer timer, const nlib_timerspec* new_value,
514  nlib_timerspec* old_value);
515 NLIB_VIS_PUBLIC errno_t nlib_timer_gettime(nlib_timer timer, nlib_timerspec* curr_value);
516 NLIB_VIS_PUBLIC errno_t nlib_timer_delete(nlib_timer timer,
517  int wait_completion,
518  nlib_timer_callback completion_callback);
519 #define NLIB_TIMER_SHORTTERM_TASK 0x00000001
520 #define NLIB_TIMER_LONGTERM_TASK 0x00000002
521 
522 //
523 // Random
524 //
525 
526 // Store 'size' bytes of random values on 'buf'
528 
529 //
530 // Virtual Memory, Physical Memory
531 //
533 NLIB_VIS_PUBLIC errno_t nlib_virtual_alloc(void** ptr, size_t size) NLIB_NONNULL;
534 NLIB_VIS_PUBLIC errno_t nlib_virtual_free(void* ptr, size_t size) NLIB_NONNULL;
535 NLIB_VIS_PUBLIC errno_t nlib_physical_alloc(void* ptr, size_t size, int prot) NLIB_NONNULL;
537 NLIB_VIS_PUBLIC errno_t nlib_mlock(void* addr, size_t len) NLIB_NONNULL;
538 NLIB_VIS_PUBLIC errno_t nlib_munlock(void* addr, size_t len) NLIB_NONNULL;
539 
540 #define NLIB_PHYSICAL_ALLOC_PROT_NONE 0
541 #define NLIB_PHYSICAL_ALLOC_PROT_READ 1
542 #define NLIB_PHYSICAL_ALLOC_PROT_WRITE 2
543 #define NLIB_PHYSICAL_ALLOC_PROT_EXEC 4
544 
545 //
546 // TLS
547 //
548 typedef void (*nlib_tls_destructor)(void* tls_value);
549 #define NLIB_TLS_INVALID (nlib_tls)(-1)
550 
551 #ifdef NLIB_PTHREAD_nlib_tls_alloc
552 static
553 #else
555 #endif
556 // code snippets:
557 // # map tls_key on thread local storage
558 // nlib_tls tls_key;
559 // e = nlib_tls_alloc(&tls_key, NULL); # no dtor invoked if destr is NULL
560 // if (e != 0) { error ... }
561 // # unmap tls_key
562 // nlib_tls_free(tls_key);
563 // # access from a thread
564 // void* thread_local_value;
565 // nlib_tls_getvalue(tls_key, &thread_local_value);
566 // # use and update thread_local_value
567 // nlib_tls_setvalue(tls_key, thread_local_value);
570 #ifdef NLIB_PTHREAD_nlib_tls_alloc
571 static NLIB_C_INLINE errno_t nlib_tls_alloc(nlib_tls* tls, nlib_tls_destructor destr) {
572  return pthread_key_create(tls, destr);
573 }
574 #endif
575 #ifdef NLIB_PTHREAD_nlib_tls_free
576 static NLIB_C_INLINE errno_t nlib_tls_free(nlib_tls tls) {
577  return pthread_key_delete(tls);
578 }
579 #else
581 #endif
582 #ifdef NLIB_PTHREAD_nlib_tls_setvalue
583 static
584 #else
586 #endif
587 errno_t nlib_tls_setvalue(nlib_tls tls, const void* value);
588 #ifdef NLIB_PTHREAD_nlib_tls_setvalue
589 static NLIB_C_INLINE errno_t nlib_tls_setvalue(nlib_tls tls, const void* value) {
590  return pthread_setspecific(tls, value);
591 }
592 #endif
593 
594 #ifdef NLIB_PTHREAD_nlib_tls_getvalue
595 static
596 #else
598 #endif
599 
601 #ifdef NLIB_PTHREAD_nlib_tls_getvalue
602 static NLIB_C_INLINE errno_t nlib_tls_getvalue(nlib_tls tls, void** value) {
603  *value = pthread_getspecific(tls);
604  return 0;
605 }
606 #endif
607 
608 //
609 // Mutex
610 //
611 
612 #ifdef NLIB_PTHREAD_nlib_mutex_init
613 static
614 #else
616 #endif
617 
618 // you can use NLIB_MUTEX_INITIALIZER static initializer
619 errno_t nlib_mutex_init(nlib_mutex* mutex) NLIB_NONNULL NLIB_EXCLUDES(*mutex);
620 #ifdef NLIB_PTHREAD_nlib_mutex_init
621 static NLIB_C_INLINE errno_t nlib_mutex_init(nlib_mutex* mutex) NLIB_NO_THREAD_SAFETY_ANALYSIS {
622  return pthread_mutex_init(mutex, NULL);
623 }
624 #endif
625 
626 // you can use NLIB_RECURSIVE_MUTEX_INITIALIZER static initializer
628  NLIB_NONNULL NLIB_EXCLUDES(*mutex);
629 // you can use NLIB_RECURSIVE_TIMED_MUTEX_INITIALIZER static initializer
631  NLIB_NONNULL NLIB_EXCLUDES(*mutex);
632 
633 #ifdef NLIB_PTHREAD_nlib_mutex_lock
634 static
635 #else
637 #endif
638 // code snippets:
639 // nlib_mutex m;
640 // if (nlib_mutex_init(&m) != 0) { ... } # always returns 0 on almost all platforms?
641 // nlib_mutex_lock(&m);
642 // ....
643 // nlib_mutex_unlock(&m);
644 // nlib_mutex_destroy(&m);
645 errno_t nlib_mutex_lock(nlib_mutex* mutex) NLIB_NONNULL NLIB_ACQUIRE(*mutex);
646 #ifdef NLIB_PTHREAD_nlib_mutex_lock
647 static NLIB_C_INLINE errno_t nlib_mutex_lock(nlib_mutex* mutex) NLIB_NO_THREAD_SAFETY_ANALYSIS {
648  return pthread_mutex_lock(mutex);
649 }
650 #endif
651 
652 // returns EBUSY if a lock cannot be acquired
653 #ifdef NLIB_PTHREAD_nlib_mutex_trylock
654 static
655 #else
657 #endif
659 errno_t nlib_mutex_trylock(nlib_mutex* mutex) NLIB_NONNULL NLIB_TRY_ACQUIRE(0, *mutex);
660 #ifdef NLIB_PTHREAD_nlib_mutex_trylock
661 static NLIB_C_INLINE errno_t nlib_mutex_trylock(nlib_mutex* mutex) NLIB_TRY_ACQUIRE(0, *mutex) {
662  return pthread_mutex_trylock(mutex);
663 }
664 #endif
665 // returns ETIMEDOUT if timeout
668  nlib_duration delta) NLIB_NONNULL NLIB_TRY_ACQUIRE(0, *mutex);
669 #ifdef NLIB_PTHREAD_nlib_mutex_unlock
670 static
671 #else
673 #endif
674 errno_t nlib_mutex_unlock(nlib_mutex* mutex) NLIB_NONNULL NLIB_RELEASE(*mutex);
675 #ifdef NLIB_PTHREAD_nlib_mutex_unlock
676 static NLIB_C_INLINE errno_t nlib_mutex_unlock(nlib_mutex* mutex) NLIB_NO_THREAD_SAFETY_ANALYSIS {
677  return pthread_mutex_unlock(mutex);
678 }
679 #endif
680 
681 #ifdef NLIB_PTHREAD_nlib_mutex_destroy
682 static
683 #else
685 #endif
686 // don't forget to write this, some platforms require this called.
687 errno_t nlib_mutex_destroy(nlib_mutex* mutex) NLIB_NONNULL NLIB_EXCLUDES(*mutex);
688 #ifdef NLIB_PTHREAD_nlib_mutex_destroy
689 static NLIB_C_INLINE errno_t nlib_mutex_destroy(nlib_mutex* mutex) NLIB_NO_THREAD_SAFETY_ANALYSIS {
690  return pthread_mutex_destroy(mutex);
691 }
692 #endif
693 
694 static NLIB_C_INLINE errno_t nlib_mutex_trylock_for_timespec(nlib_mutex* mutex,
695  const struct timespec* tm)
696  NLIB_TRY_ACQUIRE(0, *mutex) {
697  nlib_duration delta;
698  NLIB_FROM_TIMESPEC(tm, delta);
699  return nlib_mutex_trylock_for(mutex, delta);
700 }
701 
702 //
703 // Semaphore
704 //
705 
708 // returns EAGAIN if semaphore cannot be acquired
710 // returns ETIMEDOUT if timeout
712  nlib_semaphore* sem, nlib_duration duration) NLIB_NONNULL;
714  int* __restrict previous_count) NLIB_NONNULL_1;
715 NLIB_VIS_PUBLIC errno_t nlib_semaphore_post_ex(nlib_semaphore* __restrict sem, int release_count,
716  int* __restrict previous_count) NLIB_NONNULL_1;
718 
720  nlib_semaphore* sem, const struct timespec* tm) {
721  nlib_duration duration;
722  NLIB_FROM_TIMESPEC(tm, duration);
723  return nlib_semaphore_trywait_for(sem, duration);
724 }
725 
726 //
727 // Condition Variable
728 //
729 
730 #ifdef NLIB_PTHREAD_nlib_cond_init
731 static
732 #else
734 #endif
735 
736 // you can use NLIB_COND_INITIALIZER for static initializer
738 #ifdef NLIB_PTHREAD_nlib_cond_init
739 static NLIB_C_INLINE errno_t nlib_cond_init(nlib_cond* cond) {
740  return pthread_cond_init(cond, NULL);
741 }
742 #endif
743 
744 #ifdef NLIB_PTHREAD_nlib_cond_signal
745 static
746 #else
748 #endif
750 #ifdef NLIB_PTHREAD_nlib_cond_signal
751 static NLIB_C_INLINE errno_t nlib_cond_signal(nlib_cond* cond) {
752  return pthread_cond_signal(cond);
753 }
754 #endif
755 
756 #ifdef NLIB_PTHREAD_nlib_cond_broadcast
757 static
758 #else
760 #endif
762 #ifdef NLIB_PTHREAD_nlib_cond_broadcast
763 static NLIB_C_INLINE errno_t nlib_cond_broadcast(nlib_cond* cond) {
764  return pthread_cond_broadcast(cond);
765 }
766 #endif
767 
768 #ifdef NLIB_PTHREAD_nlib_cond_wait
769 static
770 #else
772 #endif
773 // code snippets:
774 // Initialization:
775 // bool flag = false;
776 // nlib_mutex m;
777 // nlib_cond cond;
778 // nlib_mutex_init(&m);
779 // nlib_cond_init(&cond);
780 // Thread1:
781 // nlib_mutex_lock(&m);
782 // while (!flag)
783 // e = nlib_cond_wait(&cond, &m); # m to be unlocked in nlib_cond_wait
784 // # note that nlib_cond_wait may return without signal notified
785 // if (e != 0) { error .... }
786 // # do job and reset flag
787 // flag = false;
788 // nlib_mutex_unlock(&m);
789 // Thread2:
790 // nlib_mutex_lock(&m);
791 // flag = true;
792 // nlib_cond_broadcast(&cond);
793 // nlib_mutex_unlock(&m);
794 errno_t nlib_cond_wait(nlib_cond* __restrict cond, nlib_mutex* __restrict mutex)
795  NLIB_NONNULL NLIB_REQUIRES(*mutex);
796 #ifdef NLIB_PTHREAD_nlib_cond_wait
797 static NLIB_C_INLINE
798 errno_t nlib_cond_wait(nlib_cond* __restrict cond, nlib_mutex* __restrict mutex) {
799  return pthread_cond_wait(cond, mutex);
800 }
801 #endif
802 
803 // returns ETIMEDOUT if timeout, and see baloon for nlib_cond_wait()
805 errno_t nlib_cond_wait_for(nlib_cond* __restrict cond,
806  nlib_mutex* __restrict mutex,
807  nlib_duration duration) NLIB_NONNULL NLIB_REQUIRES(*mutex);
808 // returns ETIMEDOUT if timeout, and see baloon for nlib_cond_wait()
810 errno_t nlib_cond_wait_until(nlib_cond* __restrict cond,
811  nlib_mutex* __restrict mutex,
812  nlib_time abstime) NLIB_NONNULL NLIB_REQUIRES(*mutex);
813 
814 #ifdef NLIB_PTHREAD_nlib_cond_destroy
815 static
816 #else
818 #endif
820 #ifdef NLIB_PTHREAD_nlib_cond_destroy
821 static NLIB_C_INLINE errno_t nlib_cond_destroy(nlib_cond* cond) {
822  return pthread_cond_destroy(cond);
823 }
824 #endif
825 
826 static NLIB_C_INLINE
827 errno_t nlib_cond_wait_for_timespec(nlib_cond* cond, nlib_mutex* mutex, const struct timespec* tm)
828  NLIB_REQUIRES(*mutex) {
829  nlib_duration d;
830  NLIB_FROM_TIMESPEC(tm, d);
831  return nlib_cond_wait_for(cond, mutex, d);
832 }
833 
834 static NLIB_C_INLINE
836  const struct timespec* tm) NLIB_REQUIRES(*mutex) {
837  nlib_duration d;
838  NLIB_FROM_TIMESPEC(tm, d);
839  return nlib_cond_wait_until(cond, mutex, d);
840 }
841 
842 //
843 // Read/Write lock
844 //
845 #ifndef NLIB_RWLOCK_HAS_NATIVE
846 struct nlib_rwlock_ {
847  int32_t _0[3];
848  nlib_mutex _1[2];
849  nlib_cond _2;
850 };
851 NLIB_CAPABILITY("mutex")
852 typedef struct nlib_rwlock_ nlib_rwlock;
853 
854 #define NLIB_RWLOCK_INITIALIZER { \
855  { 0, 0, 0 }, \
856  { NLIB_RECURSIVE_TIMED_MUTEX_INITIALIZER, NLIB_RECURSIVE_TIMED_MUTEX_INITIALIZER }, \
857  NLIB_COND_INITIALIZER }
858 #endif
859 
860 #ifdef NLIB_PTHREAD_nlib_rwlock_init
861 static
862 #else
864 #endif
865 
866 errno_t nlib_rwlock_init(nlib_rwlock* rwlock) NLIB_NONNULL NLIB_EXCLUDES(*rwlock);
867 #ifdef NLIB_PTHREAD_nlib_rwlock_init
868 static NLIB_C_INLINE errno_t nlib_rwlock_init(nlib_rwlock* rwlock) {
869  return pthread_rwlock_init(rwlock, NULL);
870 }
871 #endif
872 
873 #ifdef NLIB_PTHREAD_nlib_rwlock_destroy
874 static
875 #else
877 #endif
878 errno_t nlib_rwlock_destroy(nlib_rwlock* rwlock) NLIB_NONNULL NLIB_EXCLUDES(*rwlock);
879 #ifdef NLIB_PTHREAD_nlib_rwlock_destroy
880 static NLIB_C_INLINE errno_t nlib_rwlock_destroy(nlib_rwlock* rwlock) {
881  return pthread_rwlock_destroy(rwlock);
882 }
883 #endif
884 
885 #ifdef NLIB_PTHREAD_nlib_rwlock_rdlock
886 static
887 #else
889 #endif
890 errno_t nlib_rwlock_rdlock(nlib_rwlock* rwlock) NLIB_NONNULL NLIB_ACQUIRE_SHARED(*rwlock);
891 #ifdef NLIB_PTHREAD_nlib_rwlock_rdlock
892 static NLIB_C_INLINE errno_t nlib_rwlock_rdlock(nlib_rwlock* rwlock)
893  NLIB_NO_THREAD_SAFETY_ANALYSIS {
894  return pthread_rwlock_rdlock(rwlock);
895 }
896 #endif
897 
898 #ifdef NLIB_PTHREAD_nlib_rwlock_tryrdlock
899 static
900 #else
902 #endif
903 errno_t nlib_rwlock_tryrdlock(nlib_rwlock* rwlock)
904  NLIB_NONNULL NLIB_TRY_ACQUIRE_SHARED(0, *rwlock);
905 #ifdef NLIB_PTHREAD_nlib_rwlock_tryrdlock
906 static NLIB_C_INLINE errno_t nlib_rwlock_tryrdlock(nlib_rwlock* rwlock)
907  NLIB_NO_THREAD_SAFETY_ANALYSIS {
908  return pthread_rwlock_tryrdlock(rwlock);
909 }
910 #endif
911 
913 errno_t nlib_rwlock_tryrdlock_for(nlib_rwlock* rwlock, nlib_duration duration)
914  NLIB_NONNULL NLIB_TRY_ACQUIRE_SHARED(0, *rwlock);
916 errno_t nlib_rwlock_tryrdlock_until(nlib_rwlock* rwlock, nlib_time abstime)
917  NLIB_NONNULL NLIB_TRY_ACQUIRE_SHARED(0, *rwlock);
918 
919 #ifdef NLIB_PTHREAD_nlib_rwlock_rdunlock
920 static
921 #else
923 #endif
924 errno_t nlib_rwlock_rdunlock(nlib_rwlock* rwlock)
925  NLIB_NONNULL NLIB_RELEASE_SHARED(*rwlock);
926 #ifdef NLIB_PTHREAD_nlib_rwlock_rdunlock
927 static NLIB_C_INLINE errno_t nlib_rwlock_rdunlock(nlib_rwlock* rwlock)
928  NLIB_NO_THREAD_SAFETY_ANALYSIS {
929  return pthread_rwlock_unlock(rwlock);
930 }
931 #endif
932 
933 #ifdef NLIB_PTHREAD_nlib_rwlock_wrlock
934 static
935 #else
937 #endif
938 errno_t nlib_rwlock_wrlock(nlib_rwlock* rwlock) NLIB_NONNULL NLIB_ACQUIRE(*rwlock);
939 #ifdef NLIB_PTHREAD_nlib_rwlock_wrlock
940 static NLIB_C_INLINE errno_t nlib_rwlock_wrlock(nlib_rwlock* rwlock)
941  NLIB_NO_THREAD_SAFETY_ANALYSIS {
942  return pthread_rwlock_wrlock(rwlock);
943 }
944 #endif
945 
946 #ifdef NLIB_PTHREAD_nlib_rwlock_trywrlock
947 static
948 #else
950 #endif
951 errno_t nlib_rwlock_trywrlock(nlib_rwlock* rwlock) NLIB_NONNULL NLIB_TRY_ACQUIRE(0, *rwlock);
952 #ifdef NLIB_PTHREAD_nlib_rwlock_trywrlock
953 static NLIB_C_INLINE errno_t nlib_rwlock_trywrlock(nlib_rwlock* rwlock)
954  NLIB_NO_THREAD_SAFETY_ANALYSIS {
955  return pthread_rwlock_trywrlock(rwlock);
956 }
957 #endif
958 
960 errno_t nlib_rwlock_trywrlock_for(nlib_rwlock* rwlock, nlib_duration duration)
961  NLIB_NONNULL NLIB_TRY_ACQUIRE(0, *rwlock);
963 errno_t nlib_rwlock_trywrlock_until(nlib_rwlock* rwlock, nlib_time abstime)
964  NLIB_NONNULL NLIB_TRY_ACQUIRE(0, *rwlock);
965 
966 #ifdef NLIB_PTHREAD_nlib_rwlock_wrunlock
967 static
968 #else
970 #endif
971 errno_t nlib_rwlock_wrunlock(nlib_rwlock* rwlock) NLIB_NONNULL NLIB_RELEASE(*rwlock);
972 #ifdef NLIB_PTHREAD_nlib_rwlock_wrunlock
973 static NLIB_C_INLINE errno_t nlib_rwlock_wrunlock(nlib_rwlock* rwlock)
974  NLIB_NO_THREAD_SAFETY_ANALYSIS {
975  return pthread_rwlock_unlock(rwlock);
976 }
977 #endif
978 
979 static NLIB_C_INLINE
980 errno_t nlib_rwlock_tryrdlock_for_timespec(nlib_rwlock* rwlock, const struct timespec* tm)
981  NLIB_TRY_ACQUIRE_SHARED(0, *rwlock) {
982  nlib_duration d;
983  NLIB_FROM_TIMESPEC(tm, d);
984  return nlib_rwlock_tryrdlock_for(rwlock, d);
985 }
986 
987 static NLIB_C_INLINE
988 errno_t nlib_rwlock_tryrdlock_until_timespec(nlib_rwlock* rwlock, const struct timespec* tm)
989  NLIB_TRY_ACQUIRE_SHARED(0, *rwlock) {
990  nlib_duration d;
991  NLIB_FROM_TIMESPEC(tm, d);
992  return nlib_rwlock_tryrdlock_until(rwlock, d);
993 }
994 
995 static NLIB_C_INLINE
996 errno_t nlib_rwlock_trywrlock_for_timespec(nlib_rwlock* rwlock, const struct timespec* tm)
997  NLIB_TRY_ACQUIRE(0, *rwlock) {
998  nlib_duration d;
999  NLIB_FROM_TIMESPEC(tm, d);
1000  return nlib_rwlock_trywrlock_for(rwlock, d);
1001 }
1002 
1003 static NLIB_C_INLINE
1004 errno_t nlib_rwlock_trywrlock_until_timespec(nlib_rwlock* rwlock, const struct timespec* tm)
1005  NLIB_TRY_ACQUIRE(0, *rwlock) {
1006  nlib_duration d;
1007  NLIB_FROM_TIMESPEC(tm, d);
1008  return nlib_rwlock_trywrlock_until(rwlock, d);
1009 }
1010 
1011 
1012 #if defined(_MSC_VER) && defined(NLIB_RWLOCK_HAS_NATIVE)
1013 typedef struct nlib_condrwlock_ {
1014  CONDITION_VARIABLE cond;
1015 } nlib_condrwlock;
1016 #define NLIB_CONDRWLOCK_INITIALIZER { CONDITION_VARIABLE_INIT }
1017 #else
1018 typedef struct nlib_condrwlock_ {
1019  nlib_cond cond;
1020  nlib_mutex mutex;
1021 } nlib_condrwlock;
1022 #define NLIB_CONDRWLOCK_INITIALIZER { NLIB_COND_INITIALIZER, NLIB_MUTEX_INITIALIZER }
1023 #endif
1024 
1030  nlib_rwlock* __restrict rwlock,
1031  int rdlock) NLIB_NONNULL;
1033  nlib_rwlock* __restrict rwlock,
1034  nlib_duration duration,
1035  int rdlock) NLIB_NONNULL;
1037  nlib_rwlock* __restrict rwlock,
1038  nlib_time abstime,
1039  int rdlock) NLIB_NONNULL;
1040 
1042  nlib_rwlock* rwlock,
1043  const struct timespec* tm,
1044  int rdlock) {
1045  nlib_duration d;
1046  NLIB_FROM_TIMESPEC(tm, d);
1047  return nlib_condrwlock_wait_for(cond, rwlock, d, rdlock);
1048 }
1049 
1051  nlib_rwlock* rwlock,
1052  const struct timespec* tm,
1053  int rdlock) {
1054  nlib_duration d;
1055  NLIB_FROM_TIMESPEC(tm, d);
1056  return nlib_condrwlock_wait_until(cond, rwlock, d, rdlock);
1057 }
1058 
1059 //
1060 // Barrier
1061 //
1062 #ifndef NLIB_BARRIER_HAS_NATIVE
1063 struct nlib_barrier_ {
1064  nlib_mutex _0;
1065  nlib_cond _1;
1066  unsigned int _2[3];
1067 };
1068 typedef struct nlib_barrier_ nlib_barrier;
1069 #endif
1070 
1071 #ifdef NLIB_PTHREAD_nlib_barrier_init
1072 static
1073 #else
1075 #endif
1076 errno_t nlib_barrier_init(nlib_barrier* barrier, unsigned int count) NLIB_NONNULL;
1077 #ifdef NLIB_PTHREAD_nlib_barrier_init
1078 static NLIB_C_INLINE errno_t nlib_barrier_init(nlib_barrier* barrier, unsigned int count) {
1079  return pthread_barrier_init(barrier, NULL, count);
1080 }
1081 #endif
1082 
1083 #ifdef NLIB_PTHREAD_nlib_barrier_destroy
1084 static
1085 #else
1087 #endif
1089 #ifdef NLIB_PTHREAD_nlib_barrier_destroy
1090 static NLIB_C_INLINE errno_t nlib_barrier_destroy(nlib_barrier* barrier) {
1091  return pthread_barrier_destroy(barrier);
1092 }
1093 #endif
1094 
1096 
1097 //
1098 // Once
1099 //
1100 #ifndef NLIB_ONCE_HAS_NATIVE
1101 struct nlib_onceflag_ {
1102  int status;
1103 };
1104 typedef struct nlib_onceflag_ nlib_onceflag;
1105 #define NLIB_ONCE_INIT { 0 }
1106 typedef void (*nlib_oncefunc)(void);
1107 
1108 // code snippets
1109 // void OnceFunc() { .... }
1110 // nlib_onceflag flag = NLIB_ONCE_INIT; // should be static initialized
1111 // nlib_once(&flag, OnceFunc); // OnceFunc executes only once
1114 #elif defined(_MSC_VER)
1115 typedef INIT_ONCE nlib_onceflag;
1116 #define NLIB_ONCE_INIT INIT_ONCE_STATIC_INIT
1117 typedef void (*nlib_oncefunc)(void);
1118 NLIB_VIS_PUBLIC errno_t nlib_once(nlib_onceflag* flag, nlib_oncefunc func);
1119 #elif defined(__APPLE__) || defined(__FreeBSD__)
1120 typedef dispatch_once_t nlib_onceflag;
1121 #define NLIB_ONCE_INIT 0
1122 typedef void (*nlib_oncefunc)(void);
1123 NLIB_VIS_PUBLIC errno_t nlib_once(nlib_onceflag* flag, nlib_oncefunc func) NLIB_NONNULL;
1124 #else
1125 typedef pthread_once_t nlib_onceflag;
1126 #define NLIB_ONCE_INIT PTHREAD_ONCE_INIT
1127 typedef void (*nlib_oncefunc)(void);
1128 static errno_t nlib_once(nlib_onceflag* flag, nlib_oncefunc func) NLIB_NONNULL;
1129 static NLIB_C_INLINE errno_t nlib_once(nlib_onceflag* flag, nlib_oncefunc func) {
1130  return pthread_once(flag, func);
1131 }
1132 #endif
1133 
1134 //
1135 // Message Queue
1136 //
1137 #ifdef NLIB_DOXYGEN
1138 typedef int32_t nlib_mq;
1139 #else
1140 typedef struct nlib_mq_ {
1141  int32_t raw_handle; // 0 for invalid handle
1142 } nlib_mq;
1143 #endif
1144 typedef void* nlib_mq_msg;
1145 
1146 #define NLIB_MQ_BLOCK 0
1147 #define NLIB_MQ_NONBLOCK 1
1148 #define NLIB_MQ_LOCKFREE 2
1149 
1151 #ifdef NLIB_DOXYGEN
1153  int32_t flag;
1154  int32_t max_msg;
1155  int32_t cur_msg;
1157 };
1158 #else
1159 typedef struct nlib_mq_attr_ {
1160  int32_t flag; // NLIB_MQ_BLOCK / NLIB_MQ_NONBLOCK
1161  int32_t max_msg; // 0 for 128
1162  int32_t cur_msg; // blocking mode only
1163  nlib_mq_msg_destructor destructor;
1164 } nlib_mq_attr;
1165 #endif
1166 
1168 errno_t nlib_mq_open(nlib_mq* mq, const nlib_mq_attr* attr) NLIB_NONNULL;
1173 NLIB_VIS_PUBLIC NLIB_CHECK_RESULT errno_t nlib_mq_send(nlib_mq mq, nlib_mq_msg msg, int prio);
1175 errno_t nlib_mq_send_until(nlib_mq mq, nlib_mq_msg msg, int prio, nlib_time abstime);
1177 errno_t nlib_mq_receive(nlib_mq mq, nlib_mq_msg* msg, int* prio) NLIB_NONNULL_2;
1179 errno_t nlib_mq_receive_until(nlib_mq mq, nlib_mq_msg* msg, int* prio, nlib_time abstime)
1182 errno_t nlib_mq_drop(nlib_mq mq, nlib_mq_msg* msg, int* prio) NLIB_NONNULL_2;
1183 
1184 //
1185 // Thread
1186 //
1188 static NLIB_ALWAYS_INLINE void nlib_pause(void) {
1189 #if defined(__x86_64__) || defined(__i386__) || defined(_M_IX86) || defined(_M_AMD64)
1190  _mm_pause();
1191 #elif defined(__ARM_ACLE)
1192  __yield();
1193 #else
1194  (void)nlib_yield();
1195 #endif
1196 }
1197 
1198 #define NLIB_THREAD_INVALID (nlib_thread)(0) // NOLINT
1199 
1200 #ifndef NLIB_SPINLOCK_HAS_NATIVE
1201 typedef int32_t nlib_spinlock;
1202 #endif
1203 
1204 #ifndef NLIB_THREAD_ATTR_HAS_NATIVE
1205 struct nlib_thread_attr_ {
1206  nlib_spinlock spin;
1207  int detach_state;
1208  int explicit_sched;
1209  int priority;
1210  uint32_t affinity;
1211  void* stack_addr;
1212  size_t stack_size;
1213 };
1214 typedef struct nlib_thread_attr_ nlib_thread_attr;
1215 #else
1216 struct nlib_thread_attr_ {
1217  pthread_attr_t attr;
1218  uint32_t affinity;
1219 };
1220 typedef struct nlib_thread_attr_ nlib_thread_attr;
1221 #endif
1222 typedef void (*nlib_thread_func)(void* arg);
1223 // -1 for invalid
1224 typedef int nlib_thread_id;
1225 
1226 // code snippets:
1227 // nlib_thread th;
1228 // if ((e = nlib_thread_create(&th, NULL, myfunc, myarg)) != 0) { error ... }
1229 // nlib_thread_join(th); # or nlib_thread_detach(th);
1231 errno_t nlib_thread_create(nlib_thread* __restrict thread, const nlib_thread_attr* __restrict attr,
1232  nlib_thread_func func, void* __restrict arg)
1233  NLIB_NONNULL_1 NLIB_NONNULL_3;
1234 #ifdef NLIB_PTHREAD_nlib_thread_join
1235 static
1236 #else
1238 #endif
1240 #ifdef NLIB_PTHREAD_nlib_thread_join
1241 static NLIB_C_INLINE errno_t nlib_thread_join(nlib_thread thread) {
1242  return pthread_join(thread, NULL);
1243 }
1244 #endif
1245 
1246 #ifdef NLIB_PTHREAD_nlib_thread_detach
1247 static
1248 #else
1250 #endif
1252 #ifdef NLIB_PTHREAD_nlib_thread_detach
1253 static NLIB_C_INLINE errno_t nlib_thread_detach(nlib_thread thread) {
1254  return pthread_detach(thread);
1255 }
1256 #endif
1257 
1258 #ifdef NLIB_PTHREAD_nlib_thread_self
1259 static
1260 #else
1262 #endif
1264 #ifdef NLIB_PTHREAD_nlib_thread_self
1265 static NLIB_C_INLINE errno_t nlib_thread_self(nlib_thread* thread) {
1266  *thread = pthread_self();
1267  return 0;
1268 }
1269 #endif
1270 
1273 
1274 #ifdef NLIB_PTHREAD_nlib_thread_equal
1275 static
1276 #else
1278 #endif
1280 #ifdef NLIB_PTHREAD_nlib_thread_equal
1281 static NLIB_C_INLINE int nlib_thread_equal(nlib_thread th1, nlib_thread th2) {
1282  return pthread_equal(th1, th2);
1283 }
1284 #endif
1285 
1287 NLIB_VIS_PUBLIC errno_t nlib_thread_setaffinity(nlib_thread thread, uint32_t affinity);
1289 
1290 #ifdef NLIB_PTHREAD_nlib_thread_getname
1291 static
1292 #else
1294 #endif
1295 errno_t nlib_thread_getname(nlib_thread thread, char* name, size_t len) NLIB_NONNULL;
1296 #ifdef NLIB_PTHREAD_nlib_thread_getname
1297 static NLIB_C_INLINE errno_t nlib_thread_getname(nlib_thread thread, char* name, size_t len) {
1298  return pthread_getname_np(thread, name, len);
1299 }
1300 #endif
1301 
1302 // NOTE:
1303 // win32 does not have GetThreadAffinityMask()
1304 // errno_t nlib_thread_get_affinify(nlib_thread thread, uint32_t* affinity);
1305 
1310 errno_t nlib_thread_attr_getint(const nlib_thread_attr* __restrict attr, int key,
1311  int* __restrict value) NLIB_NONNULL;
1313 errno_t nlib_thread_attr_setptr(nlib_thread_attr* __restrict attr, int key,
1314  void* __restrict value) NLIB_NONNULL_1;
1316 errno_t nlib_thread_attr_getptr(const nlib_thread_attr* __restrict attr, int key,
1317  void** __restrict value) NLIB_NONNULL;
1319 errno_t nlib_thread_attr_setstack(nlib_thread_attr* __restrict attr, void* __restrict stack_addr,
1320  size_t stack_size) NLIB_NONNULL;
1322 errno_t nlib_thread_attr_getstack(const nlib_thread_attr* __restrict attr,
1323  void** __restrict stack_addr, size_t* __restrict stack_size)
1324  NLIB_NONNULL;
1326 
1327 #define NLIB_THREAD_ATTR_KEY_DETACHSTATE (1)
1328 #define NLIB_THREAD_ATTR_KEY_STACKSIZE (2)
1329 #define NLIB_THREAD_ATTR_KEY_PRIORITY (4)
1330 #define NLIB_THREAD_ATTR_KEY_AFFINITY (5)
1331 #define NLIB_THREAD_ATTR_KEY_EXPLICIT_SCHED (6)
1332 
1338 
1339 #ifndef NN_PLATFORM_CTR
1340 // See also nlib_thread_exit_cpp();
1342 #endif
1343 
1344 #ifdef NLIB_DOXYGEN
1345 void nlib_thread_cleanup_push(void (*fn)(void*), void* arg);
1346 void nlib_thread_cleanup_pop(int exec);
1347 #elif defined(pthread_cleanup_push)
1348 # define nlib_thread_cleanup_push(fn, arg) pthread_cleanup_push(fn, arg)
1349 # define nlib_thread_cleanup_pop(exec) pthread_cleanup_pop(exec)
1350 #elif !defined(NN_PLATFORM_CTR)
1351 struct nlib_thread_cleanup_handler_ {
1352  void (*func)(void*);
1353  void* arg;
1354  struct nlib_thread_cleanup_handler_* next;
1355 };
1356 #define nlib_thread_cleanup_push(fn, arg) switch (0) case 0: default: { \
1357  struct nlib_thread_cleanup_handler_ _thread_cleanup_handler = { fn, arg, NULL }; \
1358  nlib_thread_cleanup_push_(&_thread_cleanup_handler)
1359 #define nlib_thread_cleanup_pop(exec) nlib_thread_cleanup_pop_(exec); }
1360 
1361 NLIB_VIS_PUBLIC void nlib_thread_cleanup_push_(struct nlib_thread_cleanup_handler_* handler);
1362 NLIB_VIS_PUBLIC void nlib_thread_cleanup_pop_(int exec);
1363 #endif
1364 
1365 //
1366 // Console/Debug
1367 //
1368 
1369 // note that buf is not null terminated
1371 errno_t nlib_write_stdout(size_t* __restrict result, const void* __restrict buf, size_t count)
1372  NLIB_NONNULL;
1373 // note that buf is not null terminated
1375 errno_t nlib_write_stderr(size_t* __restrict result, const void* __restrict buf, size_t count)
1376  NLIB_NONNULL;
1379 errno_t nlib_debug_backtrace(size_t* __restrict result, void** __restrict buffer, size_t count)
1380  NLIB_NONNULL;
1382 errno_t nlib_debug_backtrace_gettext(char* __restrict str, size_t strbufsize,
1383  void* const* __restrict buf, size_t count) NLIB_NONNULL;
1385 errno_t nlib_getenv(size_t* __restrict result, char* __restrict buf, size_t bufsize,
1386  const char* __restrict varname) NLIB_NONNULL_1 NLIB_NONNULL_4;
1387 
1388 typedef enum nlib_log_priority {
1389  kNlibLogUnknown = 0,
1390  kNlibLogDefault,
1397  kNlibLogSilent,
1401  NLIB_LOG_UNKNOWN = kNlibLogUnknown,
1402  NLIB_LOG_DEAFULT = kNlibLogDefault,
1403  NLIB_LOG_VERBOSE = kNlibLogVerbose,
1404  NLIB_LOG_DEBUG = kNlibLogDebug,
1405  NLIB_LOG_INFO = kNlibLogInfo,
1406  NLIB_LOG_WARN = kNlibLogWarn,
1407  NLIB_LOG_ERROR = kNlibLogError,
1408  NLIB_LOG_FATAL = kNlibLogFatal,
1409  NLIB_LOG_SILENT = kNlibLogSilent,
1410  NLIB_LOG_LEVEL_EQUAL_OR_ABOVE = kNlibLogLevelEqualOrAbove,
1411  NLIB_LOG_LEVEL_EQUAL_OR_BELOW = kNlibLogLevelEqualOrBelow,
1412  NLIB_LOG_LEVEL_ALL = kNlibLogLevelAll
1414 
1415 typedef enum nlib_log_key {
1416  kNlibLogAttrUnknown = 0,
1417  kNlibLogAttrStdout,
1418  kNlibLogAttrStderr,
1419  kNlibLogAttrMsvcTrace,
1420  kNlibLogAttrSyslog,
1421  kNlibLogAttrNlibFd,
1422  kNlibLogAttrMax,
1423  NLIB_LOG_ATTR_UNKNOWN = kNlibLogAttrUnknown,
1424  NLIB_LOG_ATTR_STDOUT = kNlibLogAttrStdout,
1425  NLIB_LOG_ATTR_STDERR = kNlibLogAttrStderr,
1426  NLIB_LOG_ATTR_MSVC_TRACE = kNlibLogAttrMsvcTrace,
1427  NLIB_LOG_ATTR_SYSLOG = kNlibLogAttrSyslog,
1428  NLIB_LOG_ATTR_NLIB_FD = kNlibLogAttrNlibFd,
1429  NLIB_LOG_ATTR_MAX = 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;
1544 NLIB_VIS_PUBLIC NLIB_CHECK_RESULT errno_t nlib_fd_truncate(nlib_fd fd, nlib_offset length);
1545 
1547 errno_t nlib_fd_getsize(nlib_offset* size, nlib_fd fd) NLIB_NONNULL;
1550 NLIB_VIS_PUBLIC errno_t nlib_fd_native_handle(void** native_handle, nlib_fd fd) NLIB_NONNULL;
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_VIS_PUBLIC NLIB_CHECK_RESULT errno_t nlib_unlink(const char* native_path);
1579 NLIB_VIS_PUBLIC NLIB_CHECK_RESULT errno_t nlib_mkdir(const char* native_path,
1580  unsigned int flags);
1581 NLIB_VIS_PUBLIC NLIB_CHECK_RESULT errno_t nlib_rmdir(const char* native_path);
1582 NLIB_VIS_PUBLIC NLIB_CHECK_RESULT 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> // NOLINT, 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;
1672 static errno_t nlib_spinlock_trylock(nlib_spinlock* lock) NLIB_NONNULL;
1673 static void nlib_spinlock_unlock(nlib_spinlock* lock) NLIB_NONNULL;
1674 
1675 static NLIB_ALWAYS_INLINE void nlib_spinlock_init(nlib_spinlock* lock) {
1676  *lock = 0;
1677 }
1678 static NLIB_ALWAYS_INLINE void nlib_spinlock_lock(nlib_spinlock* lock) {
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 }
1708 static NLIB_ALWAYS_INLINE errno_t nlib_spinlock_trylock(nlib_spinlock* lock) {
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 }
1739 static NLIB_ALWAYS_INLINE void nlib_spinlock_unlock(nlib_spinlock* lock) {
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)
1841  NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
1842 NLIB_VIS_PUBLIC_ALT const void* nlib_memrchr(const void* s, int c, size_t n)
1843  NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
1844 NLIB_VIS_PUBLIC_ALT const void* nlib_memchr_not(const void* s, int c, size_t n)
1845  NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
1846 NLIB_VIS_PUBLIC_ALT
1847 const void* nlib_memchr_range_not(const void* __restrict s, const char* __restrict range,
1848  size_t n) NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
1849 NLIB_VIS_PUBLIC_ALT const void* nlib_memchr_lt(const void* s, int c, size_t n)
1850  NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
1851 NLIB_VIS_PUBLIC_ALT const void* nlib_memchr_gt(const void* s, int c, size_t n)
1852  NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
1853 // find (c & 0x80) != 0
1854 NLIB_VIS_PUBLIC_ALT const void* nlib_memchr_mb(const void* s, size_t n)
1855  NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
1856 NLIB_VIS_PUBLIC size_t nlib_memspn(const void* __restrict buf, size_t len,
1857  const char* __restrict set, size_t n)
1858  NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
1859 NLIB_VIS_PUBLIC size_t nlib_memcspn(const void* __restrict buf, size_t len,
1860  const char* __restrict set, size_t n)
1861  NLIB_NONNULL NLIB_ATTRIBUTE_PURE;
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; // NOLINT
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)
2025  NLIB_NONNULL_1 NLIB_NONNULL_2;
2027 errno_t nlib_strto_int64(int64_t* result, const char* nptr, char** endptr, int base)
2028  NLIB_NONNULL_1 NLIB_NONNULL_2;
2030 errno_t nlib_strto_uint32(uint32_t* result, const char* nptr, char** endptr, int base)
2031  NLIB_NONNULL_1 NLIB_NONNULL_2;
2033 errno_t nlib_strto_uint64(uint64_t* result, const char* nptr, char** endptr, int base)
2034  NLIB_NONNULL_1 NLIB_NONNULL_2;
2036 errno_t nlib_strto_double(double* result, const char* nptr, char** endptr)
2037  NLIB_NONNULL_1 NLIB_NONNULL_2;
2039 errno_t nlib_strto_float(float* result, const char* nptr, char** endptr)
2040  NLIB_NONNULL_1 NLIB_NONNULL_2;
2042 errno_t nlib_strto_int32_fallback(int32_t* result, const char* nptr, char** endptr, int base)
2043  NLIB_NONNULL_1 NLIB_NONNULL_2;
2045 errno_t nlib_strto_int64_fallback(int64_t* result, const char* nptr, char** endptr, int base)
2046  NLIB_NONNULL_1 NLIB_NONNULL_2;
2048 errno_t nlib_strto_uint32_fallback(uint32_t* result, const char* nptr, char** endptr, int base)
2049  NLIB_NONNULL_1 NLIB_NONNULL_2;
2051 errno_t nlib_strto_uint64_fallback(uint64_t* result, const char* nptr, char** endptr, int base)
2052  NLIB_NONNULL_1 NLIB_NONNULL_2;
2054 errno_t nlib_strto_double_fallback(double* result, const char* nptr, char** endptr)
2055  NLIB_NONNULL_1 NLIB_NONNULL_2;
2057 errno_t nlib_strto_float_fallback(float* result, const char* nptr, char** endptr)
2058  NLIB_NONNULL_1 NLIB_NONNULL_2;
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; // NOLINT
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; // NOLINT
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; // NOLINT
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; // NOLINT
2109  return e;
2110 }
2111 
2113 errno_t nlib_wide_to_utf8(size_t* __restrict utf8count, nlib_utf8_t* __restrict utf8,
2114  size_t buflen, const wchar_t* __restrict wcstr) NLIB_NONNULL_4;
2116 errno_t nlib_utf8_to_wide(size_t* __restrict wccount, wchar_t* __restrict wcstr,
2117  size_t buflen, const nlib_utf8_t* __restrict utf8) NLIB_NONNULL_4;
2119 errno_t nlib_memwide_to_utf8(size_t* __restrict to_count, size_t* __restrict from_count,
2120  nlib_utf8_t* __restrict to, size_t to_size,
2121  const wchar_t* __restrict from, size_t from_size)
2122  NLIB_NONNULL_1 NLIB_NONNULL_2 NLIB_NONNULL_5;
2124 errno_t nlib_memutf8_to_wide(size_t* __restrict to_count, size_t* __restrict from_count,
2125  wchar_t* __restrict to, size_t to_size,
2126  const nlib_utf8_t* __restrict from, size_t from_size)
2127  NLIB_NONNULL_1 NLIB_NONNULL_2 NLIB_NONNULL_5;
2128 
2130 errno_t nlib_wcscplen(size_t* __restrict count, const wchar_t* __restrict str) NLIB_NONNULL_2;
2132 errno_t nlib_strcplen(size_t* __restrict codepoint_count,
2133  size_t* __restrict supplementary_codepoint_count,
2134  size_t* __restrict len,
2135  const nlib_utf8_t* __restrict str) NLIB_NONNULL_4;
2137 errno_t nlib_memcplen(size_t* __restrict codepoint_count,
2138  size_t* __restrict supplementary_codepoint_count,
2139  size_t* __restrict from_read,
2140  const nlib_utf8_t* __restrict from,
2141  size_t from_size) NLIB_NONNULL_3 NLIB_NONNULL_4;
2142 
2143 // 0 if error
2146  nlib_utf16_t lower) NLIB_NONNULL;
2147 // 0 if error
2150  nlib_utf32_t utf32) NLIB_NONNULL;
2151 // 0 if error
2154 #ifdef __cplusplus
2155 // 0 if error
2157 int nlib_utf32char_to_utf8(nlib_utf8_t (&utf8)[4], nlib_utf32_t utf32);
2158 #endif
2159 
2161 errno_t nlib_utf16_to_utf8(size_t* utf8count, nlib_utf8_t* utf8, size_t buflen,
2162  const nlib_utf16_t* utf16) NLIB_NONNULL_4;
2164 errno_t nlib_utf8_to_utf16(size_t* utf16count, nlib_utf16_t* utf16, size_t buflen,
2165  const nlib_utf8_t* utf8) NLIB_NONNULL_4;
2167 errno_t nlib_utf32_to_utf8(size_t* utf8count, nlib_utf8_t* utf8, size_t buflen,
2168  const nlib_utf32_t* utf32) NLIB_NONNULL_4;
2170 errno_t nlib_utf8_to_utf32(size_t* utf32count, nlib_utf32_t* utf32, size_t buflen,
2171  const nlib_utf8_t* utf8) NLIB_NONNULL_4;
2172 
2174 errno_t nlib_memutf16_to_utf8(size_t* __restrict to_count, size_t* __restrict from_count,
2175  nlib_utf8_t* __restrict to, size_t to_size,
2176  const nlib_utf16_t* __restrict from, size_t from_size)
2177  NLIB_NONNULL_1 NLIB_NONNULL_2 NLIB_NONNULL_5;
2179 errno_t nlib_memutf8_to_utf16(size_t* __restrict to_count, size_t* __restrict from_count,
2180  nlib_utf16_t* __restrict to, size_t to_size,
2181  const nlib_utf8_t* __restrict from, size_t from_size)
2182  NLIB_NONNULL_1 NLIB_NONNULL_2 NLIB_NONNULL_5;
2184 errno_t nlib_memutf32_to_utf8(size_t* __restrict to_count, size_t* __restrict from_count,
2185  nlib_utf8_t* __restrict to, size_t to_size,
2186  const nlib_utf32_t* __restrict from, size_t from_size)
2187  NLIB_NONNULL_1 NLIB_NONNULL_2 NLIB_NONNULL_5;
2189 errno_t nlib_memutf8_to_utf32(size_t* __restrict to_count, size_t* __restrict from_count,
2190  nlib_utf32_t* __restrict to, size_t to_size,
2191  const nlib_utf8_t* __restrict from, size_t from_size)
2192  NLIB_NONNULL_1 NLIB_NONNULL_2 NLIB_NONNULL_5;
2193 
2194 NLIB_VIS_PUBLIC_ALT
2195 size_t nlib_utf16len_(const uint16_t* str) NLIB_NONNULL;
2196 NLIB_VIS_PUBLIC_ALT
2197 size_t nlib_utf16nlen_(const uint16_t* str, size_t maxsize) NLIB_NONNULL;
2199 errno_t nlib_utf16cpy_(uint16_t* s1, size_t s1max, const uint16_t* s2) NLIB_NONNULL;
2201 errno_t nlib_utf16ncpy_(uint16_t* s1, size_t s1max, const uint16_t* s2, size_t n) NLIB_NONNULL;
2203 size_t nlib_utf16len(const nlib_utf16_t* str) {
2204  return nlib_utf16len_((const uint16_t*)str);
2205 }
2207 size_t nlib_utf16nlen(const nlib_utf16_t* str, size_t maxsize) {
2208  return nlib_utf16nlen_((const uint16_t*)str, maxsize);
2209 }
2210 static NLIB_ALWAYS_INLINE
2211 errno_t nlib_utf16cpy(nlib_utf16_t* s1, size_t s1max, const nlib_utf16_t* s2) {
2212  return nlib_utf16cpy_((uint16_t*)s1, s1max, (const uint16_t*)s2); // NOLINT
2213 }
2214 static NLIB_ALWAYS_INLINE
2215 errno_t nlib_utf16ncpy(nlib_utf16_t* s1, size_t s1max, const nlib_utf16_t* s2, size_t n) {
2216  return nlib_utf16ncpy_((uint16_t*)s1, s1max, (const uint16_t*)s2, n); // NOLINT
2217 }
2218 
2219 NLIB_VIS_PUBLIC_ALT
2220 size_t nlib_utf32len_(const uint32_t* str) NLIB_NONNULL;
2221 NLIB_VIS_PUBLIC_ALT
2222 size_t nlib_utf32nlen_(const uint32_t* str, size_t maxsize) NLIB_NONNULL;
2224 errno_t nlib_utf32cpy_(uint32_t* s1, size_t s1max, const uint32_t* s2) NLIB_NONNULL;
2226 errno_t nlib_utf32ncpy_(uint32_t* s1, size_t s1max, const uint32_t* s2, size_t n) NLIB_NONNULL;
2228 size_t nlib_utf32len(const nlib_utf32_t* str) {
2229  return nlib_utf32len_((const uint32_t*)str);
2230 }
2232 size_t nlib_utf32nlen(const nlib_utf32_t* str, size_t maxsize) {
2233  return nlib_utf32nlen_((const uint32_t*)str, maxsize);
2234 }
2235 static NLIB_ALWAYS_INLINE
2236 errno_t nlib_utf32cpy(nlib_utf32_t* s1, size_t s1max, const nlib_utf32_t* s2) {
2237  return nlib_utf32cpy_((uint32_t*)s1, s1max, (const uint32_t*)s2); // NOLINT
2238 }
2239 static NLIB_ALWAYS_INLINE
2240 errno_t nlib_utf32ncpy(nlib_utf32_t* s1, size_t s1max, const nlib_utf32_t* s2, size_t n) {
2241  return nlib_utf32ncpy_((uint32_t*)s1, s1max, (const uint32_t*)s2, n); // NOLINT
2242 }
2243 
2244 NLIB_VIS_PUBLIC_ALT NLIB_CHECK_RESULT
2245 errno_t nlib_utf16cplen_ex_(size_t* count, size_t* len, const uint16_t* str) NLIB_NONNULL_3;
2246 
2247 static NLIB_ALWAYS_INLINE
2248 errno_t nlib_utf16cplen(size_t* count, const nlib_utf16_t* str) {
2249  return nlib_utf16cplen_ex_(count, NULL, (const uint16_t*)str);
2250 }
2251 static NLIB_ALWAYS_INLINE
2252 errno_t nlib_utf16cplen_ex(size_t* count, size_t* len, const nlib_utf16_t* str) {
2253  return nlib_utf16cplen_ex_(count, len, (const uint16_t*)str);
2254 }
2256 errno_t nlib_utf32cplen(size_t* count, const nlib_utf32_t* str) NLIB_NONNULL_2;
2257 
2258 // for (0..count) { swapendian(p[count]); }
2259 NLIB_VIS_PUBLIC_ALT errno_t nlib_swapendian_16(uint16_t* p, size_t count) NLIB_NONNULL;
2260 // for (0..count) { swapendian(p[count]); }
2261 NLIB_VIS_PUBLIC_ALT errno_t nlib_swapendian_32(uint32_t* p, size_t count) NLIB_NONNULL;
2262 // for (0..count) { swapendian(p[count]); }
2263 NLIB_VIS_PUBLIC_ALT errno_t nlib_swapendian_64(uint64_t* p, size_t count) NLIB_NONNULL;
2264 
2265 //
2266 // malloc functions which nlib uses
2267 // You can redefine them.
2268 // See sample replace_malloc.cpp of nlibnx_heap.a library.
2269 //
2270 
2271 // weak function
2272 NLIB_VIS_PUBLIC_ALT NLIB_CHECK_RESULT
2273 void* nlib_malloc(size_t size) NLIB_ATTRIBUTE_MALLOC NLIB_ATTRIBUTE_ALLOC_SIZE1(1);
2274 
2275 // weak function
2276 NLIB_VIS_PUBLIC_ALT void nlib_free(void* ptr);
2277 
2278 // weak function
2279 NLIB_VIS_PUBLIC_ALT NLIB_CHECK_RESULT
2280 void* nlib_calloc(size_t nmemb, size_t size)
2281  NLIB_ATTRIBUTE_MALLOC NLIB_ATTRIBUTE_ALLOC_SIZE2(1, 2);
2282 
2283 // weak function
2284 NLIB_VIS_PUBLIC_ALT NLIB_CHECK_RESULT
2285 void* nlib_realloc(void* ptr, size_t size) NLIB_ATTRIBUTE_MALLOC NLIB_ATTRIBUTE_ALLOC_SIZE1(2);
2286 
2287 // weak function, not defined if CAFE or CTR
2288 NLIB_VIS_PUBLIC size_t nlib_malloc_size(const void* ptr) NLIB_NONNULL;
2289 
2290 // weak function(calls nlib_free(ptr) by default)
2291 NLIB_VIS_PUBLIC_ALT void nlib_free_size(void* ptr, size_t size);
2292 
2293 // weak function, not defined if WIN32 or CTR
2294 NLIB_VIS_PUBLIC_ALT NLIB_CHECK_RESULT
2295 void* nlib_memalign(size_t alignment, size_t size)
2296  NLIB_ATTRIBUTE_MALLOC NLIB_ATTRIBUTE_ALLOC_SIZE1(2) NLIB_ATTRIBUTE_ALLOC_ALIGN(1);
2297 
2298 #ifndef NLIB_MEMCPY
2299 # define NLIB_MEMCPY(a, b, c) memcpy((a), (b), (c))
2300 #endif
2301 
2302 #ifndef NLIB_MEMMOVE
2303 # define NLIB_MEMMOVE(a, b, c) memmove((a), (b), (c))
2304 #endif
2305 
2306 #ifndef NLIB_MEMSET
2307 # define NLIB_MEMSET(a, b, c) memset((a), (b), (c))
2308 #endif
2309 
2310 // ctype.h without locale
2311 static int nlib_isalnum(int ch) NLIB_ATTRIBUTE_CONST;
2312 static int nlib_isalpha(int ch) NLIB_ATTRIBUTE_CONST;
2313 static int nlib_isblank(int ch) NLIB_ATTRIBUTE_CONST;
2314 static int nlib_iscntrl(int ch) NLIB_ATTRIBUTE_CONST;
2315 static int nlib_isdigit(int ch) NLIB_ATTRIBUTE_CONST;
2316 static int nlib_isgraph(int ch) NLIB_ATTRIBUTE_CONST;
2317 static int nlib_islower(int ch) NLIB_ATTRIBUTE_CONST;
2318 static int nlib_isprint(int ch) NLIB_ATTRIBUTE_CONST;
2319 static int nlib_ispunct(int ch) NLIB_ATTRIBUTE_CONST;
2320 static int nlib_isspace(int ch) NLIB_ATTRIBUTE_CONST;
2321 static int nlib_isupper(int ch) NLIB_ATTRIBUTE_CONST;
2322 static int nlib_isxdigit(int ch) NLIB_ATTRIBUTE_CONST;
2323 static int nlib_tolower(int ch) NLIB_ATTRIBUTE_CONST;
2324 static int nlib_toupper(int ch) NLIB_ATTRIBUTE_CONST;
2325 
2326 static NLIB_C_INLINE int nlib_isalnum(int ch) {
2327  return ('0' <= ch && ch <= '9') || ('A' <= ch && ch <= 'Z') || ('a' <= ch && ch <= 'z');
2328 }
2329 static NLIB_C_INLINE int nlib_isalpha(int ch) {
2330  return ('A' <= ch && ch <= 'Z') || ('a' <= ch && ch <= 'z');
2331 }
2332 static NLIB_C_INLINE int nlib_isblank(int ch) { return ch == ' ' || ch == '\t'; }
2333 static NLIB_C_INLINE int nlib_iscntrl(int ch) { return (ch >= 0 && ch <= 0x1F) || ch == 0x7F; }
2334 static NLIB_C_INLINE int nlib_isdigit(int ch) { return ('0' <= ch && ch <= '9'); }
2335 static NLIB_C_INLINE int nlib_isgraph(int ch) { return ch >= 0x21 && ch <= 0x7E; }
2336 static NLIB_C_INLINE int nlib_islower(int ch) { return (ch >= 'a' && ch <= 'z'); }
2337 static NLIB_C_INLINE int nlib_isprint(int ch) { return ch >= 0x20 && ch <= 0x7E; }
2338 static NLIB_C_INLINE int nlib_ispunct(int ch) { return (ch >= 0x00 && ch <= 0x20) || ch == 0x7F; }
2339 static NLIB_C_INLINE int nlib_isspace(int ch) {
2340  return ((ch) == ' ' || (ch) == '\t' || (ch) == '\n');
2341 }
2342 static NLIB_C_INLINE int nlib_isupper(int ch) { return (ch >= 'A' && ch <= 'Z'); }
2343 static NLIB_C_INLINE int nlib_isxdigit(int ch) {
2344  return (unsigned int)(ch - '0') < 10u ||
2345  (unsigned int)((ch | 0x20) - 'a') < 6u;
2346 }
2347 static NLIB_C_INLINE int nlib_tolower(int ch) {
2348  return (ch >= 'A' && ch <= 'Z') ? ch + ('a' - 'A') : ch;
2349 }
2350 static NLIB_C_INLINE int nlib_toupper(int ch) {
2351  return (ch >= 'a' && ch <= 'z') ? ch - ('a' - 'A') : ch;
2352 }
2353 // no isascii, toascii
2354 
2355 // memcpy_s
2356 static NLIB_C_INLINE
2357 errno_t nlib_memcpy(void* __restrict s1, size_t s1max, const void* __restrict s2, size_t n) {
2358 #if defined(_MSC_VER) || defined(__STDC_LIB_EXT1__)
2359  return memcpy_s(s1, s1max, s2, n);
2360 #else
2361 #ifndef NLIB_NONNULL_ENABLED
2362  if (!s1 || !s2) return ERANGE;
2363 #endif
2364  if (s1max < n) {
2365  NLIB_MEMSET(s1, 0, s1max);
2366  return ERANGE;
2367  }
2368  NLIB_MEMCPY(s1, s2, n);
2369  return 0;
2370 #endif
2371 }
2372 
2373 // memmove_s
2374 static NLIB_C_INLINE
2375 errno_t nlib_memmove(void* s1, size_t s1max, const void* s2, size_t n) {
2376 #if defined(_MSC_VER) || defined(__STDC_LIB_EXT1__)
2377  return memmove_s(s1, s1max, s2, n);
2378 #else
2379 #ifndef NLIB_NONNULL_ENABLED
2380  if (!s1 || !s2) return ERANGE;
2381 #endif
2382  if (s1max < n) return ERANGE;
2383  NLIB_MEMMOVE(s1, s2, n);
2384  return 0;
2385 #endif
2386 }
2387 
2388 static NLIB_C_INLINE
2389 errno_t nlib_memset(void* buf, int ch, size_t n) {
2390  NLIB_EINVAL_IFNULL(buf);
2391  NLIB_MEMSET(buf, ch, n);
2392  return 0;
2393 }
2394 
2395 static int nlib_popcnt16(uint16_t x) NLIB_ATTRIBUTE_CONST;
2396 static int nlib_popcnt32(uint32_t x) NLIB_ATTRIBUTE_CONST;
2397 static int nlib_popcnt64(uint64_t x) NLIB_ATTRIBUTE_CONST;
2398 #if defined(NLIB_SSE42)
2399 static NLIB_ALWAYS_INLINE int nlib_popcnt16(uint16_t x) {
2400  return _mm_popcnt_u32(x);
2401 }
2402 static NLIB_ALWAYS_INLINE int nlib_popcnt32(uint32_t x) {
2403  return _mm_popcnt_u32(x);
2404 }
2405 static NLIB_ALWAYS_INLINE int nlib_popcnt64(uint64_t x) {
2406 #ifdef NLIB_64BIT
2407  return (int)_mm_popcnt_u64(x); // NOLINT
2408 #else
2409  uint32_t lo = (uint32_t)(x & 0xFFFFFFFFU); // NOLINT
2410  uint32_t hi = (uint32_t)((x >> 32) & 0xFFFFFFFFU); // NOLINT
2411  return _mm_popcnt_u32(lo) + _mm_popcnt_u32(hi); // NOLINT
2412 #endif
2413 }
2414 #elif defined(NLIB_NEON)
2415 static NLIB_ALWAYS_INLINE int nlib_popcnt16(uint16_t x) {
2416  uint8x8_t x0 = vcnt_u8(vreinterpret_u8_u64(vcreate_u64(x)));
2417 #ifdef __aarch64__
2418  return vaddv_u8(x0);
2419 #else
2420  uint8x8_t x1 = vpadd_u8(x0, x0);
2421  return vget_lane_u8(x1, 0);
2422 #endif
2423 }
2424 static NLIB_ALWAYS_INLINE int nlib_popcnt32(uint32_t x) {
2425  uint8x8_t x0 = vcnt_u8(vreinterpret_u8_u64(vcreate_u64(x)));
2426 #ifdef __aarch64__
2427  return vaddv_u8(x0);
2428 #else
2429  uint8x8_t x1 = vpadd_u8(x0, x0);
2430  uint8x8_t x2 = vpadd_u8(x1, x1);
2431  return vget_lane_u8(x2, 0);
2432 #endif
2433 }
2434 static NLIB_ALWAYS_INLINE int nlib_popcnt64(uint64_t x) {
2435  uint8x8_t x0 = vcnt_u8(vreinterpret_u8_u64(vcreate_u64(x)));
2436 #ifdef __aarch64__
2437  return vaddv_u8(x0);
2438 #else
2439  uint8x8_t x1 = vpadd_u8(x0, x0);
2440  uint8x8_t x2 = vpadd_u8(x1, x1);
2441  uint8x8_t x3 = vpadd_u8(x2, x2);
2442  return vget_lane_u8(x3, 0);
2443 #endif
2444 }
2445 #else
2446 extern NLIB_VIS_PUBLIC const unsigned char _nlib_popcnt_array[];
2447 static NLIB_ALWAYS_INLINE int nlib_popcnt32(uint32_t x) {
2448  return _nlib_popcnt_array[(x >> 24) & 0xFF] + _nlib_popcnt_array[(x >> 16) & 0xFF] +
2449  _nlib_popcnt_array[(x >> 8) & 0xFF] + _nlib_popcnt_array[(x)& 0xFF];
2450 }
2451 static NLIB_ALWAYS_INLINE int nlib_popcnt64(uint64_t x) {
2452  return _nlib_popcnt_array[(x >> 56) & 0xFF] + _nlib_popcnt_array[(x >> 48) & 0xFF] +
2453  _nlib_popcnt_array[(x >> 40) & 0xFF] + _nlib_popcnt_array[(x >> 32) & 0xFF] +
2454  _nlib_popcnt_array[(x >> 24) & 0xFF] + _nlib_popcnt_array[(x >> 16) & 0xFF] +
2455  _nlib_popcnt_array[(x >> 8) & 0xFF] + _nlib_popcnt_array[(x)& 0xFF];
2456 }
2457 static NLIB_ALWAYS_INLINE int nlib_popcnt16(uint16_t x) {
2458  return _nlib_popcnt_array[(x >> 8) & 0xFF] + _nlib_popcnt_array[(x)& 0xFF];
2459 }
2460 #endif
2461 
2462 // nlib_clz32(0x80000000) -> 0, nlib_clz32(1) -> 31
2463 static int nlib_clz32(uint32_t x) NLIB_ATTRIBUTE_CONST;
2464 // nlib_ctz32(0x80000000) -> 31, nlib_ctz32(1) -> 0
2465 static int nlib_ctz32(uint32_t x) NLIB_ATTRIBUTE_CONST;
2466 // nlib_clz64(INT64_MIN) -> 0, nlib_clz64(1) -> 63
2467 static int nlib_clz64(uint64_t x) NLIB_ATTRIBUTE_CONST;
2468 // nlib_ctz64(INT64_MIN) -> 63, nlib_ctz64(1) -> 0
2469 static int nlib_ctz64(uint64_t x) NLIB_ATTRIBUTE_CONST;
2470 #if defined(_MSC_VER)
2471 static NLIB_ALWAYS_INLINE int nlib_clz32(uint32_t x) {
2472  DWORD cnt;
2473  return _BitScanReverse(&cnt, x) ? (int)(31 - cnt) : 32; // NOLINT
2474  // return (int)(__lzcnt(x)); // needs haswell+
2475 }
2476 static NLIB_ALWAYS_INLINE int nlib_ctz32(uint32_t x) {
2477  DWORD cnt;
2478  return _BitScanForward(&cnt, x) ? cnt : 32;
2479 }
2480 static NLIB_ALWAYS_INLINE int nlib_clz64(uint64_t x) {
2481 #ifdef NLIB_64BIT
2482  DWORD cnt;
2483  return _BitScanReverse64(&cnt, x) ? (int)(63 - cnt) : 64; // NOLINT
2484  // return (int)(__lzcnt64(x)); // needs haswell+
2485 #else
2486  DWORD cnt;
2487  DWORD dw = (DWORD)(x >> 32);
2488  if (_BitScanReverse(&cnt, dw)) {
2489  return (int)(31 - cnt); // NOLINT
2490  } else {
2491  dw = (DWORD)(x);
2492  return _BitScanReverse(&cnt, dw) ?
2493  (int)(63 - cnt) : 64; // NOLINT
2494  }
2495 #endif
2496 }
2497 static NLIB_ALWAYS_INLINE int nlib_ctz64(uint64_t x) {
2498 #ifdef NLIB_64BIT
2499  DWORD cnt;
2500  return _BitScanForward64(&cnt, x) ? cnt : 64;
2501 #else
2502  DWORD cnt;
2503  DWORD dw = (DWORD)(x);
2504  if (_BitScanForward(&cnt, dw)) {
2505  return (int)(cnt); // NOLINT
2506  } else {
2507  dw = (DWORD)(x >> 32);
2508  return _BitScanForward(&cnt, dw) ?
2509  (int)(32 + cnt) : 64; // NOLINT
2510  }
2511 #endif
2512 }
2513 #elif defined(CAFE)
2514 static NLIB_ALWAYS_INLINE int nlib_clz32(uint32_t x) { return __CLZ32(x); }
2515 static NLIB_ALWAYS_INLINE int nlib_ctz32(uint32_t x) { return 32 - nlib_clz32(~x & (x - 1)); }
2516 static NLIB_ALWAYS_INLINE int nlib_clz64(uint64_t x) {
2517  int cnt;
2518  unsigned int dw = (unsigned int)(x >> 32); // NOLINT
2519  cnt = __CLZ32(dw);
2520  if (cnt < 32) {
2521  return cnt;
2522  } else {
2523  dw = (unsigned int)(x); // NOLINT
2524  cnt = __CLZ32(dw);
2525  return 32 + cnt;
2526  }
2527 }
2528 static NLIB_ALWAYS_INLINE int nlib_ctz64(uint64_t x) { return 64 - nlib_clz64(~x & (x - 1)); }
2529 #elif defined(NN_PLATFORM_CTR)
2530 static NLIB_ALWAYS_INLINE int nlib_clz32(uint32_t x) { return x != 0 ? __builtin_clz(x) : 32; }
2531 static NLIB_ALWAYS_INLINE int nlib_ctz32(uint32_t x) { return 32 - nlib_clz32(~x & (x - 1)); }
2532 static NLIB_ALWAYS_INLINE int nlib_clz64(uint64_t x) { return x != 0 ? __builtin_clzll(x) : 64; }
2533 static NLIB_ALWAYS_INLINE int nlib_ctz64(uint64_t x) { return 64 - nlib_clz64(~x & (x - 1)); }
2534 #else
2535 static NLIB_ALWAYS_INLINE int nlib_clz32(uint32_t x) { return x != 0 ? __builtin_clz(x) : 32; }
2536 static NLIB_ALWAYS_INLINE int nlib_ctz32(uint32_t x) { return x != 0 ? __builtin_ctz(x) : 32; }
2537 static NLIB_ALWAYS_INLINE int nlib_clz64(uint64_t x) { return x != 0 ? __builtin_clzll(x) : 64; }
2538 static NLIB_ALWAYS_INLINE int nlib_ctz64(uint64_t x) { return x != 0 ? __builtin_ctzll(x) : 64; }
2539 #endif
2540 
2541 static size_t nlib_strlcpy(char* __restrict s1, const char* __restrict s2, size_t s1max)
2542  NLIB_NONNULL;
2543 static NLIB_C_INLINE
2544 size_t nlib_strlcpy(char* __restrict s1, const char* __restrict s2, size_t s1max) {
2545 #if defined(__FreeBSD__)
2546  return strlcpy(s1, s2, s1max);
2547 #else
2548  size_t len = nlib_strlen(s2);
2549  if (NLIB_LIKELY(len < s1max)) {
2550  NLIB_MEMCPY(s1, s2, len + 1);
2551  } else if (NLIB_LIKELY(s1max > 0)) {
2552  NLIB_MEMCPY(s1, s2, s1max - 1);
2553  s1[s1max - 1] = '\0';
2554  }
2555  return len;
2556 #endif
2557 }
2558 
2559 static uint32_t nlib_bitreverse32(uint32_t x) NLIB_ATTRIBUTE_CONST;
2560 static uint64_t nlib_bitreverse64(uint64_t x) NLIB_ATTRIBUTE_CONST;
2561 
2562 static NLIB_ALWAYS_INLINE uint32_t nlib_bitreverse32(uint32_t x) {
2563 #if __has_builtin(__builtin_bitreverse32)
2564  return __builtin_bitreverse32(x);
2565 #elif __has_builtin(__builtin_arm_rbit)
2566  return __builtin_arm_rbit(x);
2567 #elif defined(__arm__) && !defined(NN_PLATFORM_CTR)
2568  return __rbit(x);
2569 #else
2570  x = ((x & 0x55555555U) << 1) | ((x >> 1) & 0x55555555U);
2571  x = ((x & 0x33333333U) << 2) | ((x >> 2) & 0x33333333U);
2572  x = ((x & 0x0F0F0F0FU) << 4) | ((x >> 4) & 0x0F0F0F0FU);
2573 #ifdef _MSC_VER
2574  x = _byteswap_ulong(x);
2575 #elif defined(CAFE) || defined(NN_PLATFORM_CTR)
2576  x = (x << 24) | ((x & 0xFF00) << 8) |
2577  ((x >> 8) & 0xFF00) | (x >> 24);
2578 #else
2579  x = __builtin_bswap32(x);
2580 #endif
2581  return x;
2582 #endif
2583 }
2584 
2585 static NLIB_ALWAYS_INLINE uint64_t nlib_bitreverse64(uint64_t x) {
2586 #if __has_builtin(__builtin_bitreverse64)
2587  return __builtin_bitreverse64(x);
2588 #elif __has_builtin(__builtin_arm_rbit64)
2589  return __builtin_arm_rbit64(x);
2590 #elif __has_builtin(__builtin_arm_rbit)
2591  return __builtin_arm_rbit(x >> 32) |
2592  (((uint64_t)__builtin_arm_rbit(x)) << 32);
2593 #elif defined(__arm__) && !defined(NN_PLATFORM_CTR)
2594  return __rbit(x >> 32) |
2595  (((uint64_t)__rbit(x)) << 32);
2596 #else
2597  x = ((x & 0x5555555555555555ULL) << 1) | ((x >> 1) & 0x5555555555555555ULL);
2598  x = ((x & 0x3333333333333333ULL) << 2) | ((x >> 2) & 0x3333333333333333ULL);
2599  x = ((x & 0x0F0F0F0F0F0F0F0FULL) << 4) | ((x >> 4) & 0x0F0F0F0F0F0F0F0FULL);
2600 #ifdef _MSC_VER
2601  x = _byteswap_uint64(x);
2602 #elif defined(CAFE) || defined(NN_PLATFORM_CTR)
2603  x =
2604  (x << 56) |
2605  ((x & 0xFF00U) << 40) |
2606  ((x & 0xFF0000U) << 24) |
2607  ((x & 0xFF000000U) << 8) |
2608  ((x >> 8) & 0xFF000000U) |
2609  ((x >> 24) & 0xFF0000U) |
2610  ((x >> 40) & 0xFF00U) |
2611  (x >> 56);
2612 #else
2613  x = __builtin_bswap64(x);
2614 #endif
2615  return x;
2616 #endif
2617 }
2618 
2619 #undef NLIB_MEMCPY
2620 #undef NLIB_MEMMOVE
2621 #undef NLIB_MEMSET
2622 
2623 #ifdef __cplusplus
2624 }
2625 #endif
2626 
2627 #if defined(_MSC_VER)
2628 #if defined(n_EXPORTS)
2629 #undef NLIB_VIS_PUBLIC
2630 #define NLIB_VIS_PUBLIC NLIB_WINIMPORT
2631 #elif defined(nx_misc_EXPORTS)
2632 # undef NLIB_VIS_PUBLIC
2633 # define NLIB_VIS_PUBLIC NLIB_WINEXPORT
2634 #endif
2635 #endif
2636 
2637 #endif // INCLUDE_NN_NLIB_PLATFORM_H_
errno_t nlib_rwlock_rdunlock(nlib_rwlock *rwlock) NLIB_RELEASE_SHARED(*rwlock)
読み込みロックを解放します。
全ての優先度を指定します。nlib_log_attr_setint()で利用することができます。
Definition: Platform.h:1400
int32_t nlib_atomic_xor_fetch32(int32_t *ptr, int32_t val, int memorder)
アトミックな値の排他的論理和の計算を行います。動作はgccの__atomic_xor_fetch()に準じます。 ...
errno_t nlib_debug_backtrace_gettext(char *str, size_t strbufsize, void *const *buf, size_t count)
nlib_debug_backtrace()で得られた情報から文字列情報を作成します。
errno_t nlib_utf8_to_utf32(size_t *utf32count, nlib_utf32_t *utf32, size_t buflen, const nlib_utf8_t *utf8)
UTF-8文字列からUTF-32文字列に変換します。
errno_t nlib_thread_priority_max(int *priority)
実行優先度に指定できる数値の最大値を取得します。
errno_t nlib_log_attr_setint(int prio, int key, int value)
優先度ごとの出力先の指定を行います。
errno_t nlib_strto_uint64_fallback(uint64_t *result, const char *nptr, char **endptr, int base)
C標準関数を使わずに文字列をuint64_t型に変換します。詳しくはnlib_strto_int32()を参照してください。 ...
int64_t nlib_atomic_fetch_and64(int64_t *ptr, int64_t val, int memorder)
アトミックな値の論理積の計算を行います。動作はgccの__atomic_fetch_and()に準じます。 ...
errno_t nlib_readlink(size_t *len, const char *native_path, char *buf, size_t bufsize)
シンボリックリンクを解決します。
const char * nlib_strrchr(const char *s, int c)
文字列の末尾から文字を検索します。
void * nlib_atomic_exchangeptr(void **ptr, void *val, int memorder)
アトミックに値を入れ替えます。動作はgccの__atomic_exchange_n()に準じます。
errno_t nlib_strto_double_fallback(double *result, const char *nptr, char **endptr)
C標準関数を使わずに文字列をdouble型に変換します。詳しくはnlib_strto_int32()を参照してください。 ...
int nlib_thread_equal(nlib_thread th1, nlib_thread th2)
2つのスレッドが同一スレッドを指すかどうかチェックします。
static void nlib_spinlock_unlock(nlib_spinlock *lock)
スピンロックをアンロックします。
Definition: Platform.h:1739
#define NLIB_NORETURN
関数がリターンしないことを示します。
errno_t nlib_semaphore_post_ex(nlib_semaphore *sem, int release_count, int *previous_count)
セマフォカウントをreleaseCount 増加させる。
void(* nlib_timer_callback)(nlib_timer timer, void *param)
nlib_timer_create()で設定するコールバック関数の型です。
Definition: Platform.h:499
#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:2215
static NLIB_CHECK_RESULT size_t nlib_utf16len(const nlib_utf16_t *str)
ヌル文字を含まないnlib_utf16_tの数を数えます。
Definition: Platform.h:2203
NLIB_CHECK_RESULT errno_t nlib_wcscplen(size_t *count, const wchar_t *str)
文字列中のコードポイントの数を取得します。
NLIB_CHECK_RESULT errno_t nlib_fd_write(size_t *result, nlib_fd fd, const void *buf, size_t count)
ファイルディスクリプタへ、(最大)count バイトをbuf から書きこみます。
int nlib_atomic_compare_exchangeptr(void **ptr, void **expected, void *desired, int weak, int success_memorder, int failure_memorder)
アトミックな値の比較と入れ替えを行います。動作はgccの__atomic_compare_exchange_n()に準じます。 ...
int32_t nlib_atomic_load32(const int32_t *ptr, int memorder)
アトミックに値をロードします。動作はgccの__atomic_load_n()に準じます。
errno_t nlib_virtual_alloc(void **ptr, size_t size)
仮想メモリアドレス空間を割り当てます。
警告レベルのメッセージを出力するときに指定します。
Definition: Platform.h:1394
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:2342
errno_t nlib_vdwprintf(nlib_fd fd, size_t *count, const wchar_t *fmt, va_list args)
ファイルディスクリプタに出力するvsnwprintfです。
static NLIB_CHECK_RESULT 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:2389
NLIB_CHECK_RESULT 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()と同様です。
NLIB_CHECK_RESULT void * nlib_calloc(size_t nmemb, size_t size)
C標準関数のcalloc()を呼び出すweak関数です。nlibはこの関数を経由してcalloc()を呼び出します。 ...
#define NLIB_ALWAYS_INLINE
コンパイラに関数をインライン展開するように強く示します。
Definition: Platform_unix.h:97
int nlib_wprintf(const wchar_t *fmt,...)
wprintf()の代替です。
errno_t nlib_condrwlock_wait_until(nlib_condrwlock *cond, nlib_rwlock *rwlock, nlib_time abstime, int rdlock)
rwlockをアンロックし、条件変数を待機します。実行が再開したらrwlockを再ロックします。 ...
errno_t nlib_strto_double(double *result, const char *nptr, char **endptr)
文字列をdouble型に変換します。詳しくはnlib_strto_int32()を参照してください。
int64_t nlib_atomic_fetch_add64(int64_t *ptr, int64_t val, int memorder)
アトミックな値の加算を行います。動作はgccの__atomic_fetch_add()に準じます。
static errno_t nlib_sleep_timespec(const struct timespec *tm)
nlib_sleep()の引数にtimespec構造体を取るバージョンです。
Definition: Platform.h:484
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:852
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:1156
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:2329
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)
ブートからの経過時間を取得します。
NLIB_CHECK_RESULT 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
NLIB_CHECK_RESULT 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_mutex_recursive_timed_init(nlib_mutex *mutex) NLIB_EXCLUDES(*mutex)
再帰かつタイムアウト可能なミューテックスを初期化します。
NLIB_CHECK_RESULT errno_t nlib_fd_readv(size_t *result, nlib_fd fd, const nlib_fd_iovec *iov, int iovcnt)
fdに関連付けられたファイルから複数の非連続なバッファへの読み込みを行います。
errno_t nlib_mlock(void *addr, size_t len)
指定したメモリ領域がスワップアウトされないようにします。
デバッグレベルのメッセージを出力するときに指定します。
Definition: Platform.h:1392
NLIB_CHECK_RESULT errno_t nlib_semaphore_trywait_for(nlib_semaphore *sem, nlib_duration duration)
セマフォカウントが0でなければ、セマフォカウントを1減少させる。0の場合はduration の期間だけ待つ。 ...
NLIB_CHECK_RESULT errno_t nlib_memcplen(size_t *codepoint_count, size_t *supplementary_codepoint_count, size_t *from_read, const nlib_utf8_t *from, size_t from_size)
文字列中のコードポイントの数と補助文字の数を取得します。
エラーレベルのメッセージを出力するときに指定します。
Definition: Platform.h:1395
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として比較します。
nlib_log_priority
出力の優先度(種類)を定義しています。
Definition: Platform.h:1388
#define NLIB_ATOMIC_RELEASE
gccの__ATOMIC_RELEASEやC++11のstd::memory_order_releaseに準じます。
errno_t nlib_exist_path(int *result, const char *native_path)
パスが存在するかどうかを検査します。
指定した優先度との論理和をとると、指定した優先度かそれ以下の優先度を指定したことになります。 nlib_log...
Definition: Platform.h:1399
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
関数の呼び出し元が戻り値をチェックする必要があることを示します。
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:2337
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:508
errno_t nlib_fd_fileid(nlib_fileid *result, nlib_fd fd)
errno_t nlib_cond_init(nlib_cond *cond)
条件変数を初期化します。
static int nlib_toupper(int ch)
chがASCII文字の&#39;a&#39;-&#39;z&#39;である場合に大文字にしたものを、そうでない場合にchを返します。 ...
Definition: Platform.h:2350
struct nlib_thread_attr_ nlib_thread_attr
新しく作られるスレッドに適用されるスレッド属性
Definition: Platform.h:1214
NLIB_CHECK_RESULT 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:2343
static int nlib_popcnt64(uint64_t x)
1となっているビットの数を返します。
Definition: Platform.h:2405
int64_t nlib_atomic_fetch_sub64(int64_t *ptr, int64_t val, int memorder)
アトミックな値の減算を行います。動作はgccの__atomic_fetch_sub()に準じます。
errno_t nlib_thread_self(nlib_thread *thread)
実行中のスレッドに対応するnlib_threadの値を格納する。
void nlib_thread_cleanup_push(void(*fn)(void *), void *arg)
fnを専用のスタックにプッシュします。
#define NLIB_UNLIKELY(x)
条件xが偽になる傾向が高いことをコンパイラに示します。
void nlib_free_size(void *ptr, size_t size)
サイズを指定してメモリを解放します。デフォルトではnlib_free()を呼び出します。
NLIB_CHECK_RESULT errno_t nlib_mq_receive_until(nlib_mq mq, nlib_mq_msg *msg, int *prio, nlib_time abstime)
メッセージをキューからタイムアウトつきで受信します。受信したメッセージはユーザーがデストラクタ関数で...
NLIB_CHECK_RESULT errno_t nlib_rename(const char *old_path, const char *new_path)
ファイル名の変更する
NLIB_CHECK_RESULT 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)
書き込みロックを取得しクリティカルセクションに入ります。取得できるまでブロックします。 ...
NLIB_CHECK_RESULT errno_t nlib_dir_read(nlib_dirent *ent, nlib_dir dir)
ディレクトリエントリがあればそれをを1つ読み込む。
uint32_t nlib_ulong_compatible_t
unsigned longと互換性のある整数型がtypedefされています。
Definition: Platform.h:322
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()に準じます。 ...
NLIB_CHECK_RESULT 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:450
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 NLIB_CHECK_RESULT size_t nlib_utf32len(const nlib_utf32_t *str)
ヌル文字を含まないnlib_utf32_tの数を数えます。
Definition: Platform.h:2228
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:476
NLIB_CHECK_RESULT 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:2535
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:827
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:1106
errno_t nlib_physical_free(void *ptr, size_t size)
物理メモリの割り当てを解除します。
#define NLIB_ATTRIBUTE_CONST
利用可能であれば__attribute__((const))が定義されます。
#define NLIB_VIS_PUBLIC
関数やクラス等のシンボルをライブラリの外部に公開します。
Definition: Platform_unix.h:89
static errno_t nlib_utf32cpy(nlib_utf32_t *s1, size_t s1max, const nlib_utf32_t *s2)
nlib_strcpy()のUTF-32版です。
Definition: Platform.h:2236
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:468
NLIB_CHECK_RESULT errno_t nlib_mq_drop(nlib_mq mq, nlib_mq_msg *msg, int *prio)
キューに存在する最低の優先度のメッセージをキューから受信します。受信したメッセージはユーザーがデスト...
#define NLIB_ATTRIBUTE_PURE
利用可能であれば__attribute__((pure))が定義されます。
NLIB_CHECK_RESULT errno_t nlib_gen_random(void *buf, size_t size)
ランダムな値をsize バイト生成してbuf に格納します。
NLIB_CHECK_RESULT 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()に準じます。 ...
NLIB_CHECK_RESULT errno_t nlib_fd_flush(nlib_fd fd)
ファイルディスクリプタへの書き込みをフラッシュします。
int32_t max_msg
メッセージキューの作成の際に最大メッセージ数を設定することができます。
Definition: Platform.h:1154
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:256
NLIB_CHECK_RESULT 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:835
errno_t nlib_is_dir(int *result, const char *native_path)
パスがディレクトリかどうかを検査します。パスが存在しない場合は*resultに0を設定し、0を返します。 ...
#define NLIB_FD_O_WRONLY
nlib_fd_open()のflags 引数で使われます。
Definition: Platform.h:1457
NLIB_CHECK_RESULT 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)
ハンドルで示されるメッセージキューを受信専用にします。
NLIB_CHECK_RESULT 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:286
static errno_t nlib_utf16cpy(nlib_utf16_t *s1, size_t s1max, const nlib_utf16_t *s2)
nlib_strcpy()のUTF-16版です。
Definition: Platform.h:2211
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)
標準出力に文字列を書き出します。
NLIB_CHECK_RESULT errno_t nlib_tls_alloc(nlib_tls *tls, nlib_tls_destructor destr)
TLSスロットに対する新しいIDを確保します。
int nlib_fd
(nlib独自の)ファイルディスクリプタで、32bit整数です。
Definition: Platform.h:1513
情報レベルのメッセージを出力するときに指定します。
Definition: Platform.h:1393
NLIB_CHECK_RESULT errno_t nlib_utf32cplen(size_t *count, const nlib_utf32_t *str)
文字列中のコードポイントの数を取得します。
int32_t nlib_mq
メッセージキューに関連付けられるハンドルです。ハンドルがゼロクリア(memset()を利用してください)された...
Definition: Platform.h:1138
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()に準じます。
int64_t nlib_atomic_exchange64(int64_t *ptr, int64_t val, int memorder)
アトミックに値を入れ替えます。動作はgccの__atomic_exchange_n()に準じます。
NLIB_CHECK_RESULT 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:2252
NLIB_CHECK_RESULT 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:285
static int nlib_ctz64(uint64_t x)
LSB(least significant bit)から見て連続する0ビットの数を返します。
Definition: Platform.h:2538
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文字列に変換します。
NLIB_CHECK_RESULT errno_t nlib_mkdir(const char *native_path, unsigned int flags)
ディレクトリを作成する
int nlib_printf(const char *fmt,...)
printf()の代替です。
errno_t nlib_strto_int32_fallback(int32_t *result, const char *nptr, char **endptr, int base)
C標準関数を使わずに文字列をint32_t型に変換します。詳しくはnlib_strto_int32()を参照してください。 ...
errno_t nlib_disk_freespace(const char *native_path, uint64_t *free_bytes_available, uint64_t *total_bytes, uint64_t *total_free_bytes)
指定されたパスが属するストレージの容量に関する情報を取得します。
static int nlib_popcnt16(uint16_t x)
1となっているビットの数を返します。
Definition: Platform.h:2399
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:1041
const void * nlib_memrchr(const void *s, int c, size_t n)
メモリ領域[s, s + n)の後方からn バイトを検索して、バイトc があるポインタを返します。 ...
int64_t nlib_atomic_sub_fetch64(int64_t *ptr, int64_t val, int memorder)
アトミックな値の減算を行います。動作はgccの__atomic_sub_fetch()に準じます。
#define NLIB_LIKELY(x)
条件xが真になる傾向が高いことをコンパイラに示します。
Definition: Platform_unix.h:99
uint32_t nlib_crc32c(uint32_t crc32c, const void *p, size_t n)
データのCRC-32Cチェックサムを計算する関数です。
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:2326
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:2240
uint32_t nlib_timer
nlib_timer_create()とnlib_timer_delete()で利用するタイマーのIDです。
Definition: Platform.h:491
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:1068
static void nlib_spinlock_init(nlib_spinlock *lock)
スピンロックを初期化します。
Definition: Platform.h:1675
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()に準じます。
NLIB_CHECK_RESULT errno_t nlib_semaphore_trywait(nlib_semaphore *sem)
セマフォカウントが0でなければ、セマフォカウントを1減少させる。
static errno_t nlib_memcpy(void *s1, size_t s1max, const void *s2, size_t n)
N1078のmemcpy_sに相当する実装です。
Definition: Platform.h:2357
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:2536
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
NLIB_CHECK_RESULT 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:1050
指定した優先度との論理和をとると、指定した優先度かそれ以上の優先度を指定したことになります。 nlib_log...
Definition: Platform.h:1398
errno_t nlib_cond_destroy(nlib_cond *cond)
条件変数オブジェクトを破壊します。
static uint32_t nlib_bitreverse32(uint32_t x)
32ビット整数のビットの並び順を反転させます。
Definition: Platform.h:2562
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:2585
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:2339
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
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:2332
致命的なレベルのメッセージを出力するときに指定します。
Definition: Platform.h:1396
#define nlib_yield
スレッドの実行権を手放す。
void nlib_atomic_thread_fence(int memorder)
指定されたメモリバリアを配置します。
メッセージキューの設定や現在の状態を格納する構造体です。
Definition: Platform.h:1152
NLIB_CHECK_RESULT 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:1222
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:1188
errno_t nlib_semaphore_init(nlib_semaphore *sem, int initial_count)
sem で指定されるセマフォオブジェクトを初期化する。
#define nlib_debug_break
ブレークポイントになります。
errno_t nlib_condrwlock_destroy(nlib_condrwlock *cond)
リードライトロック用条件変数を破壊します。
static int nlib_isgraph(int ch)
chがASCII文字の33から126である場合に非0、そうでない場合に0を返します。
Definition: Platform.h:2335
static int nlib_islower(int ch)
chがASCII文字の&#39;a&#39;-&#39;z&#39;である場合に非0、そうでない場合に0を返します。
Definition: Platform.h:2336
errno_t nlib_rwlock_trywrlock_for(nlib_rwlock *rwlock, nlib_duration duration) NLIB_TRY_ACQUIRE(0
書き込みロックを取得しクリティカルセクションに入ることを試みます。タイムアウトします。 ...
errno_t nlib_wcsncpy(wchar_t *s1, size_t s1max, const wchar_t *s2, size_t n)
N1078のwcsncpy_sに相当する実装です。
errno_t nlib_sleep(nlib_duration t)
t の間スリープする。
errno_t nlib_mkostemps(nlib_fd *fd, char *templ, int suffixlen, int flags)
ユニークで推測されにくい名前を持つ一時ファイルを作成します。
errno_t nlib_semaphore_wait(nlib_semaphore *sem)
セマフォカウントが0でなくなるまで待って、セマフォカウントを1減少させる。
errno_t nlib_getenv(size_t *result, char *buf, size_t bufsize, const char *varname)
環境変数の値を文字列で取得します。
#define nlib_get_native_last_error
最後に発生したネイティブのエラーコードを返します。
errno_t nlib_strto_uint64(uint64_t *result, const char *nptr, char **endptr, int base)
文字列をuint64_t型に変換します。詳しくはnlib_strto_int32()を参照してください。
errno_t nlib_rwlock_trywrlock(nlib_rwlock *rwlock) NLIB_TRY_ACQUIRE(0
書き込みロックを取得しクリティカルセクションに入ることを試みます。
errno_t nlib_utf8_to_wide(size_t *wccount, wchar_t *wcstr, size_t buflen, const nlib_utf8_t *utf8)
UTF-8文字列からUTF-16/UTF-32文字列に変換します。
static int nlib_ispunct(int ch)
chがASCII文字の0から32、または127である場合に非0、そうでない場合に0を返します。
Definition: Platform.h:2338
errno_t nlib_thread_attr_getptr(const nlib_thread_attr *attr, int key, void **value)
スレッドの属性オブジェクトのキーに対応するポインタを取得する。現在のところEINVALのみを返します。 ...
static NLIB_CHECK_RESULT size_t nlib_utf32nlen(const nlib_utf32_t *str, size_t maxsize)
nlib_strnlen()のUTF-32版です。
Definition: Platform.h:2232
NLIB_CHECK_RESULT void * nlib_realloc(void *ptr, size_t size)
C標準関数のrealloc()を呼び出すweak関数です。nlibはこの関数を経由してrealloc()を呼び出します。 ...
NLIB_CHECK_RESULT errno_t nlib_mq_send(nlib_mq mq, nlib_mq_msg msg, int prio)
メッセージをキューに送信します。
NLIB_CHECK_RESULT 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:1201
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)
スレッドの実行優先度を設定します。数値の意味は実装依存です。
NLIB_CHECK_RESULT 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)
ネイティブのファイルハンドル(に相当するもの)を取得する。
NLIB_CHECK_RESULT 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:2248
size_t nlib_malloc_size(const void *ptr)
アロケートされたメモリのサイズを返します。
詳細レベルのメッセージを出力するときに指定します。
Definition: Platform.h:1391
#define NLIB_NONNULL_4
4番目の引数にNULLを指定することができないことを示します。
int nlib_thread_id
スレッド毎にユニークな整数値
Definition: Platform.h:1224
#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
読み込みロックを取得しクリティカルセクションに入ることを試みます。タイムアウトします。 ...
NLIB_CHECK_RESULT 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 NLIB_CHECK_RESULT size_t nlib_utf16nlen(const nlib_utf16_t *str, size_t maxsize)
nlib_strnlen()のUTF-16版です。
Definition: Platform.h:2207
static int nlib_iscntrl(int ch)
chがASCIIコードの0から31、または127である場合に非0、そうでない場合に0を返します。 ...
Definition: Platform.h:2333
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_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()に準じます。 ...
NLIB_CHECK_RESULT errno_t nlib_mutex_trylock_for(nlib_mutex *mutex, nlib_duration delta) NLIB_TRY_ACQUIRE(0
与えられたmutexをロックします。タイムアウトします。
NLIB_CHECK_RESULT 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:548
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()を参照してください。
NLIB_CHECK_RESULT errno_t nlib_fd_truncate(nlib_fd fd, nlib_offset length)
指定した長さにファイルを延長、もしくは切り詰める。
const void * nlib_memchr_gt(const void *s, int c, size_t n)
メモリ領域[s, s + n)の先頭からn バイトを検索して、バイトc より大きいの文字があるデータへのポインタを...
int32_t nlib_atomic_and_fetch32(int32_t *ptr, int32_t val, int memorder)
アトミックな値の論理積の計算を行います。動作はgccの__atomic_and_fetch()に準じます。 ...
int nlib_atomic_compare_exchange32(int32_t *ptr, int32_t *expected, int32_t desired, int weak, int success_memorder, int failure_memorder)
アトミックな値の比較と入れ替えを行います。動作はgccの__atomic_compare_exchange_n()に準じます。 ...
errno_t nlib_vsnwprintf(size_t *count, wchar_t *buf, size_t size, const wchar_t *fmt, va_list args)
より安全な形式のvswprintfで、各種vswprintfの動作の違いも吸収します。
errno_t nlib_thread_getcpu(int *result)
呼び出したスレッドが実行されているCPUを取得します。
errno_t nlib_thread_getpriority(nlib_thread thread, int *priority)
スレッドの現在の実行優先度を取得します。数値の意味は実装依存です。
#define NLIB_NONNULL_3
3番目の引数にNULLを指定することができないことを示します。
NLIB_CHECK_RESULT 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:1104
errno_t nlib_thread_attr_setstack(nlib_thread_attr *attr, void *stack_addr, size_t stack_size)
スレッドの属性オブジェクトのスタック設定を設定します。
NLIB_CHECK_RESULT 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:652
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)
エンディアンを変換します。
static errno_t nlib_rwlock_trywrlock_until_timespec(nlib_rwlock *rwlock, const struct timespec *tm) NLIB_TRY_ACQUIRE(0
nlib_rwlock_trywrlock_until()の引数にtimespec構造体を取るバージョンです。
errno_t nlib_barrier_wait(nlib_barrier *barrier)
スレッドの待ち合わせを行います。
int32_t cur_msg
ロックフリーなキュー以外の場合、現在メッセージキューに存在するメッセージ数を取得できます。 ...
Definition: Platform.h:1155
int32_t nlib_long_compatible_t
longと互換性のある整数型がtypedefされています。
Definition: Platform.h:321
int64_t nlib_atomic_or_fetch64(int64_t *ptr, int64_t val, int memorder)
アトミックな値の論理和の計算を行います。動作はgccの__atomic_or_fetch()に準じます。 ...
unsigned char nlib_byte_t
C++17以降でstd::byteにtypedefされる型です。
Definition: Platform.h:309
static errno_t nlib_memmove(void *s1, size_t s1max, const void *s2, size_t n)
N1078のmemmove_sに相当する実装です。
Definition: Platform.h:2375
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:2402
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:719
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:1150
errno_t nlib_tls_getvalue(nlib_tls tls, void **value)
TLSスロットから値を取り出します。
NLIB_CHECK_RESULT 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()に準じます。 ...
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:1153
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
呼び出しスレッドを終了します。
NLIB_CHECK_RESULT errno_t nlib_cond_wait_until(nlib_cond *cond, nlib_mutex *mutex, nlib_time abstime) NLIB_REQUIRES(*mutex)
mutexをアンロックし、条件変数をabstimeまで待機します。実行が再開したらmutexを再ロックします。 ...
errno_t nlib_semaphore_destroy(nlib_semaphore *sem)
セマフォオブジェクトを破壊する。
pthread_t nlib_thread
スレッドを指し示す識別子
int64_t nlib_duration
100ns刻みで時間を表現する型です。64bit符号付き整数です。
Definition: Platform.h:452
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:1144
static int nlib_clz64(uint64_t x)
MSB(most significant bit)から見て連続する0ビットの数を返します。
Definition: Platform.h:2537
nlib_duration due_time
タイマーが最初に起動するまでの時間を指定します。
Definition: Platform.h:507
char nlib_utf8_t
charのtypedefです。文字列がUTF-8であることを示します。
Definition: Platform.h:300
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
書き込みロックを取得しクリティカルセクションに入ることを試みます。タイムアウトします。 ...
NLIB_CHECK_RESULT errno_t nlib_unlink(const char *native_path)
ファイルを削除する
NLIB_CHECK_RESULT 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:2347
NLIB_CHECK_RESULT 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:2334
int errno_t
intのtypedefで、戻り値としてPOSIXのエラー値を返すことを示します。
Definition: NMalloc.h:37