nlib
Platform_win32.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_WIN32_H_
17 #define INCLUDE_NN_NLIB_PLATFORM_WIN32_H_
18 #ifndef INCLUDE_NN_NLIB_PLATFORM_H_
19 #error do not include directly
20 #endif
21 
22 #if defined(_MSC_VER)
23 
24 #if !defined(_M_IX86) && !defined(_M_X64) && !defined(_M_AMD64)
25 #error Sorry, not supported
26 #endif
27 
28 #if _MSC_VER < 1800
29 #error Use Visual Studio 2013 or later
30 #endif
31 
32 #ifndef WIN32_LEAN_AND_MEAN
33 #pragma message(__FILE__ ": WIN32_LEAN_AND_MEAN not defined, compile may fail")
34 #define WIN32_LEAN_AND_MEAN
35 #endif
36 
37 #ifndef NOMINMAX
38 #pragma message(__FILE__ ": NOMINMAX not defined, compile may fail")
39 #define NOMINMAX
40 #endif
41 
42 #ifndef _USE_MATH_DEFINES
43 #pragma message(__FILE__ ": _USE_MATH_DEFINES not defined, compile may fail")
44 #define _USE_MATH_DEFINES
45 #endif
46 
47 #ifdef _WIN64
48 #define NLIB_64BIT
49 #endif
50 
51 #include <intrin.h>
52 
53 #pragma intrinsic(_BitScanReverse)
54 #pragma intrinsic(_BitScanForward)
55 #ifdef NLIB_64BIT
56 #pragma intrinsic(_BitScanReverse64)
57 #pragma intrinsic(_BitScanForward64)
58 #endif
59 
60 #include <stdlib.h> // for malloc, free, calloc, realloc
61 #include <limits.h> // for RSIZE_MAX
62 #include <WinSock2.h>
63 #include <MSWsock.h>
64 #include <Windows.h> // for HANDLE, CONDITION_VARIABLE, ....
65 #include <fcntl.h> // for O_RDONLY, O_RDWR, O_CREAT, ....
66 
67 #include <in6addr.h>
68 #include <ws2ipdef.h>
69 
70 #if WINVER < 0x0603
71 #pragma message(__FILE__ ": Please update your Windows SDK")
72 #endif
73 
74 #if (!defined(_M_IX86_FP) || _M_IX86_FP < 2) && !defined(_M_X64) && !defined(_M_AMD64)
75 #error /arch:SSE2 or higher must be set
76 #endif
77 
78 #ifndef NLIB_SSE41
79 #define NLIB_SSE41
80 #endif
81 
82 #ifndef NLIB_SSE42
83 #define NLIB_SSE42
84 #endif
85 
86 // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0096r3.html
87 // http://en.cppreference.com/w/cpp/compiler_support
88 // http://en.cppreference.com/w/User:D41D8CD98F/feature_testing_macros
89 // https://blogs.msdn.microsoft.com/vcblog/2016/01/22/vs-2015-update-2s-stl-is-c17-so-far-feature-complete/
90 #ifdef __cplusplus
91 #define NLIB_CXX11_SWAPHEADER
92 #define NLIB_CXX11_STDLIB_CHRONO
93 #define NLIB_CXX11_STDLIB_ATOMIC
94 #define NLIB_CXX11_STDLIB_ARRAY
95 #define NLIB_CXX11_STDLIB_UNORDERED
96 #define NLIB_CXX11_STDLIB_TUPLE
97 #define NLIB_HAS_NATIVE_TYPETRAITS
98 #define NLIB_CXX11_UNIQUEPTR
99 #define NLIB_CXX11_EXPLICIT_VIRTUAL_OVERRIDES
100 #define NLIB_CXX11_EXPLICIT_CONVERSION_OPERATORS
101 #define NLIB_CXX11_STDLIB_RANDOM
102 #define NLIB_CXX11_DEFAULT_TEMPLATE_ARGUMENT_FOR_FUNCTION_TEMPLATES
103 #define NLIB_CXX11_NULL_POINTER_CONSTANT
104 
105 #ifndef __cpp_static_assert
106 #define __cpp_static_assert 200410L // N1720
107 #endif
108 
109 #ifndef __cpp_rvalue_references
110 #define __cpp_rvalue_references 200610L // N2118
111 #endif
112 
113 #ifndef __cpp_lambdas
114 #define __cpp_lambdas 200907L // N2927
115 #endif
116 
117 #ifndef __cpp_range_based_for
118 #define __cpp_range_based_for 200907L // N2930
119 #endif
120 
121 #ifndef __cpp_alias_templates
122 #define __cpp_alias_templates 200704L // N2258
123 #endif
124 
125 #ifndef __cpp_variadic_templates
126 #define __cpp_variadic_templates 200704L // N2242
127 #endif
128 
129 #ifndef __cpp_delegating_constructors
130 #define __cpp_delegating_constructors 200604L // N1986
131 #endif
132 
133 #ifndef __cpp_lib_make_unique
134 #define __cpp_lib_make_unique 201304L // N3656
135 #endif
136 #ifndef __cpp_lib_transparent_operators
137 #define __cpp_lib_transparent_operators 201210L // N3421
138 #endif
139 #ifndef __cpp_lib_transformation_trait_aliases
140 #define __cpp_lib_transformation_trait_aliases 201304L // N3655
141 #endif
142 #ifndef __cpp_lib_incomplete_container_elements
143 #define __cpp_lib_incomplete_container_elements 201505L // N4510
144 #endif
145 
146 #if _MSC_VER >= 1900
147 #define NLIB_CXX11_NOEXCEPT
148 #define NLIB_CXX11_ALIGNMENT_SUPPORT
149 #define NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS
150 
151 #ifndef __cpp_constexpr
152 #define __cpp_constexpr 200704 // N2235
153 #endif
154 
155 #ifndef __cpp_unicode_characters
156 #define __cpp_unicode_characters 200704L // N2249
157 #endif
158 
159 // C++11
160 #ifndef __cpp_raw_strings
161 #define __cpp_raw_strings 200710L // N2442
162 #endif
163 #ifndef __cpp_unicode_literals
164 #define __cpp_unicode_literals 200710L // N2442
165 #endif
166 #ifndef __cpp_user_defined_literals
167 #define __cpp_user_defined_literals 200809L // N2765
168 #endif
169 #ifndef __cpp_decltype
170 #define __cpp_decltype 200707L // N2343
171 #endif
172 #ifndef __cpp_attributes
173 #define __cpp_attributes 200809L // N2761
174 #endif
175 #ifndef __cpp_initializer_lists
176 #define __cpp_initializer_lists 200806L // N2672
177 #endif
178 #ifndef __cpp_nsdmi
179 #define __cpp_nsdmi 200809L // N2756
180 #endif
181 #ifndef __cpp_inheriting_constructors
182 #define __cpp_inheriting_constructors 200802L // N2540
183 #endif
184 #ifndef __cpp_ref_qualifiers
185 #define __cpp_ref_qualifiers 200710L // N2439
186 #endif
187 
188 // C++14
189 #ifndef __cpp_binary_literals
190 #define __cpp_binary_literals 201304L // N3472
191 #endif
192 #ifndef __cpp_init_captures
193 #define __cpp_init_captures 201304L // N3648
194 #endif
195 #ifndef __cpp_generic_lambdas
196 #define __cpp_generic_lambdas 201304L // N3649
197 #endif
198 #ifndef __cpp_sized_deallocation
199 #define __cpp_sized_deallocation 201309L // N3778
200 #endif
201 #ifndef __cpp_decltype_auto
202 #define __cpp_decltype_auto 201304L // N3638
203 #endif
204 #ifndef __cpp_return_type_deduction
205 #define __cpp_return_type_deduction 201304L // N3638
206 #endif
207 #ifndef __cpp_variable_templates
208 #define __cpp_variable_templates 201304L // N3651
209 #endif
210 #ifndef __cpp_lib_is_null_pointer
211 #define __cpp_lib_is_null_pointer 201309L // LWG2247
212 #endif
213 #ifndef __cpp_lib_integer_sequence
214 #define __cpp_lib_integer_sequence 201304L // N3658
215 #endif
216 #ifndef __cpp_lib_exchange_function
217 #define __cpp_lib_exchange_function 201304L // N3668
218 #endif
219 #ifndef __cpp_lib_tuples_by_type
220 #define __cpp_lib_tuples_by_type 201304L // N3670
221 #endif
222 #ifndef __cpp_lib_tuple_element_t
223 #define __cpp_lib_tuple_element_t 201402L // N3887
224 #endif
225 #ifndef __cpp_lib_integral_constant_callable
226 #define __cpp_lib_integral_constant_callable 201304L // N3545
227 #endif
228 #ifndef __cpp_lib_result_of_sfinae
229 #define __cpp_lib_result_of_sfinae 201210L // N3642
230 #endif
231 #ifndef __cpp_lib_is_final
232 #define __cpp_lib_is_final 201402L // LWG2112
233 #endif
234 #ifndef __cpp_lib_chrono_udls
235 #define __cpp_lib_chrono_udls 201304L // N3642
236 #endif
237 #ifndef __cpp_lib_string_udls
238 #define __cpp_lib_string_udls 201304L // N3642
239 #endif
240 #ifndef __cpp_lib_generic_associative_lookup
241 #define __cpp_lib_generic_associative_lookup 201304L // N3657
242 #endif
243 #ifndef __cpp_lib_null_iterators
244 #define __cpp_lib_null_iterators 201304L // N3644
245 #endif
246 #ifndef __cpp_lib_make_reverse_iterator
247 #define __cpp_lib_make_reverse_iterator 201402L // LWG2285
248 #endif
249 #ifndef __cpp_lib_robust_nonmodifying_seq_ops
250 #define __cpp_lib_robust_nonmodifying_seq_ops 201304L // N3671
251 #endif
252 #ifndef __cpp_lib_complex_udls
253 #define __cpp_lib_complex_udls 201309L // N3779
254 #endif
255 #ifndef __cpp_lib_quoted_string_io
256 #define __cpp_lib_quoted_string_io 201304L // N3654
257 #endif
258 #ifndef __cpp_lib_shared_timed_mutex
259 #define __cpp_lib_shared_timed_mutex 201402L // N3891
260 #endif
261 #if _MSVC_LANG > 201402L
262 #ifndef __cpp_namespace_attributes
263 #define __cpp_namespace_attributes 201411L // N4266
264 #endif
265 #ifndef __cpp_enumerator_attributes
266 #define __cpp_enumerator_attributes 201411L // N4266
267 #endif
268 #ifndef __cpp_lib_type_trait_variable_templates
269 #define __cpp_lib_type_trait_variable_templates // P0006R0
270 #endif
271 #ifndef __cpp_lib_logical_traits
272 #define __cpp_lib_logical_traits 201510 // P0013R1
273 #endif
274 #ifndef __cpp_lib_as_const
275 #define __cpp_lib_as_const 201510 // P0007R1
276 #endif
277 #ifndef __cpp_lib_transparent_operators
278 #define __cpp_lib_transparent_operators 201510L // P0074R0
279 #endif
280 #ifndef __cpp_lib_chrono
281 #define __cpp_lib_chrono 201510 // P0092R1
282 #endif
283 #ifndef __cpp_lib_lock_guard_variadic
284 #define __cpp_lib_lock_guard_variadic 201510L // P0156R0
285 #endif
286 #ifndef __cpp_lib_uncaught_exceptions
287 #define __cpp_lib_uncaught_exceptions 201411L // N4259
288 #endif
289 #ifndef __cpp_lib_shared_mutex
290 #define __cpp_lib_shared_mutex 201505L // N4508
291 #endif
292 #endif
293 
294 #endif
295 #if _MSC_VER >= 1910
296 #undef __cpp_constexpr
297 #define __cpp_constexpr 201304L // N3652
298 #ifndef __cpp_aggregate_nsdmi
299 #define __cpp_aggregate_nsdmi 201304L // N3653
300 #endif
301 #if _MSVC_LANG > 201402L
302 // #define __cpp_hex_float 201603L // P0245R1
303 // #define __cpp_noexcept_function_type 201510L // P0012R1
304 // #define __cpp_fold_expressions 201411L // N4295
305 // #ifndef __cpp_capture_star_this
306 // #define __cpp_capture_star_this 201603L // P0018R3
307 // #endif
308 // #undef __cpp_constexpr
309 // #define __cpp_constexpr 201603L // P0170R1
310 #undef __cpp_range_based_for
311 #define __cpp_range_based_for 201603L // P0184R0
312 #undef __cpp_static_assert
313 #define __cpp_static_assert 201411L // N3928
314 #ifndef __cpp_nested_namespace_definitions
315 #define __cpp_nested_namespace_definitions 201411L // N4230
316 #endif
317 // #define __cpp_inheriting_constructors 201511L // P0136R1
318 // #define __cpp_aggregate_bases 201603L // P0017R1
319 // #define __cpp_nontype_template_args 201411L // N4268
320 // #define __cpp_fold_expressions 201603L // P0036R0
321 // #define __cpp_lib_hardware_interference_size 201603L // P0154R1
322 #endif
323 #endif
324 #endif
325 
326 #include <stdint.h>
327 #include <inttypes.h>
328 #if (_MSC_VER < 1900)
329 #ifndef __func__
330 #define __func__ __FUNCTION__
331 #endif
332 #endif
333 
334 #ifdef __cplusplus
335 extern "C" {
336 #endif
337 
338 #ifndef va_copy
339 #define va_copy(dest, src) (dest = src)
340 #endif
341 #define NLIB_ALWAYS_INLINE __forceinline
342 #define NLIB_NEVER_INLINE __declspec(noinline)
343 #define NLIB_LIKELY(x) (x)
344 #define NLIB_UNLIKELY(x) (x)
345 #define NLIB_EXPECT(var, exp_value) (var)
346 #define NLIB_CHECK_RESULT
347 #if defined(__cplusplus) && _MSC_VER >= 1900
348 #define NLIB_NORETURN [[noreturn]]
349 #else
350 #define NLIB_NORETURN
351 #endif
352 #if defined(__cplusplus) && _MSC_VER >= 1910 && _MSVC_LANG > 201402L
353 #define NLIB_FALLTHROUGH [[fallthrough]]
354 #else
355 #define NLIB_FALLTHROUGH
356 #endif
357 #define NLIB_NONNULL
358 #define NLIB_NONNULL_1
359 #define NLIB_NONNULL_2
360 #define NLIB_NONNULL_3
361 #define NLIB_NONNULL_4
362 #define NLIB_NONNULL_5
363 #define NLIB_ATTRIBUTE_MALLOC
364 #define NLIB_ATTRIBUTE_PURE
365 #define NLIB_ATTRIBUTE_CONST
366 #define NLIB_ATTRIBUTE_ALLOC_SIZE1(n)
367 #define NLIB_ATTRIBUTE_ALLOC_SIZE2(n0, n1)
368 #define NLIB_ATTRIBUTE_ALLOC_ALIGN(algn)
369 #define NLIB_ATTRIBUTE_ASSUME_ALIGNED(n)
370 #ifndef NLIB_DEPRECATED
371 #if defined(__cplusplus) && _MSC_VER >= 1910
372 #define NLIB_DEPRECATED [[deprecated]]
373 #else
374 #define NLIB_DEPRECATED __declspec(deprecated)
375 #endif
376 #endif
377 #ifndef NLIB_DEPRECATED_MSG
378 #if defined(__cplusplus) && _MSC_VER >= 1910
379 #define NLIB_DEPRECATED_MSG(msg) [[deprecated(msg)]]
380 #else
381 #define NLIB_DEPRECATED_MSG(msg) __declspec(deprecated(msg))
382 #endif
383 #endif
384 #define NLIB_WEAKSYMBOL
385 #define NLIB_VIS_HIDDEN
386 #ifdef NLIB_WINDLL
387 #define NLIB_EXPIMP_TEMPLATE_(x) template class NLIB_VIS_PUBLIC x
388 #define NLIB_WINEXPORT __declspec(dllexport)
389 #define NLIB_WINIMPORT __declspec(dllimport)
390 #define NLIB_VIS_PUBLIC NLIB_WINIMPORT
391 #define NLIB_EXPIMP_TEMPLATE(x) extern NLIB_EXPIMP_TEMPLATE_(x)
392 #else
393 #define NLIB_VIS_PUBLIC
394 #define NLIB_EXPIMP_TEMPLATE(x)
395 #endif
396 
397 #if defined(n_EXPORTS)
398 #undef NLIB_VIS_PUBLIC
399 #define NLIB_VIS_PUBLIC NLIB_WINEXPORT
400 #elif defined(nx_misc_EXPORTS)
401 #undef NLIB_EXPIMP_TEMPLATE
402 #define NLIB_EXPIMP_TEMPLATE(x) NLIB_EXPIMP_TEMPLATE_(x)
403 #endif
404 
405 #define NLIB_VIS_PUBLIC_ALT
406 
407 #define NLIB_LITTLE_ENDIAN
408 
409 // NOTE:
410 // _WriteBarrier() for the compiler, _mm_sfence() for the processor, ...
411 // NOTE:
412 // You have to comment out error lines in intrin.h if you use VC++2005.
413 // See:
414 // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=262047
415 // http://www.hydrogenaudio.org/forums/index.php?showtopic=50972
416 #define NLIB_MEMORY_ORDER_RELEASE \
417  __pragma(warning(push)) __pragma(warning(disable : 4127)) do { \
418  _WriteBarrier(); \
419  _mm_sfence(); \
420  } \
421  while (0) __pragma(warning(pop))
422 #define NLIB_MEMORY_ORDER_ACQUIRE \
423  __pragma(warning(push)) __pragma(warning(disable : 4127)) do { \
424  _ReadBarrier(); \
425  _mm_lfence(); \
426  } \
427  while (0) __pragma(warning(pop))
428 #define NLIB_MEMORY_ORDER_ACQ_REL \
429  __pragma(warning(push)) __pragma(warning(disable : 4127)) do { \
430  _ReadWriteBarrier(); \
431  _mm_mfence(); \
432  } \
433  while (0) __pragma(warning(pop))
434 #define NLIB_MEMORY_ORDER_SEQ_CST NLIB_MEMORY_ORDER_ACQ_REL
435 
436 // because "%zu" not supported ...
437 #ifdef NLIB_64BIT
438 #define __PRIS_PREFIX "ll"
439 #else
440 #define __PRIS_PREFIX
441 #endif
442 #define NLIB_WARN__(x) #x
443 #define NLIB_WARN_(x) NLIB_WARN__(x)
444 #define NLIB_WARN(exp) (__FILE__ "(" NLIB_WARN_(__LINE__) ") : WARNING: " exp)
445 
446 typedef unsigned int nlib_tls;
447 
448 #if _MSC_VER >= 1900
449 #define NLIB_TIMESPEC_HAS_NATIVE
450 #endif
451 
452 #pragma pack(push, 8)
453 typedef struct nlib_mutex_ {
454  int32_t mark;
455  uint32_t cat;
456  union {
457  HANDLE h;
458  CRITICAL_SECTION cs;
459  } data;
460 } nlib_mutex;
461 #pragma pack(pop)
462 #define NLIB_MUTEX_INITIALIZER \
463  { 0x6768696AU, 0 }
464 #define NLIB_RECURSIVE_MUTEX_INITIALIZER \
465  { 0x6768696AU, 1 }
466 #define NLIB_RECURSIVE_TIMED_MUTEX_INITIALIZER \
467  { 0x6768696AU, 2 }
468 
469 typedef HANDLE nlib_semaphore;
470 
471 typedef struct nlib_cond_ {
472  CONDITION_VARIABLE cond;
473  nlib_mutex mutex;
474 } nlib_cond;
475 #define NLIB_COND_INITIALIZER \
476  { 0, NLIB_MUTEX_INITIALIZER }
477 
478 typedef HANDLE nlib_thread;
479 
480 #define NLIB_ATTRIBUTE_PRINTF(x, y)
481 
482 #define NLIB_ASSUME(cond) __assume(cond)
483 
484 #define NLIB_RWLOCK_HAS_NATIVE
485 #ifdef NLIB_RWLOCK_HAS_NATIVE
486 typedef SRWLOCK nlib_rwlock;
487 #define NLIB_RWLOCK_INITIALIZER SRWLOCK_INIT
488 #endif
489 #define NLIB_TIMER_HAS_NATIVE
490 #define NLIB_ONCE_HAS_NATIVE
491 
492 NLIB_VIS_PUBLIC void nlib_free_size_(void* ptr, size_t size);
493 
494 #define NLIB_LIBC_nlib_memcmp
495 #define NLIB_LIBC_nlib_strlen
496 #define NLIB_LIBC_nlib_strnlen
497 #define NLIB_LIBC_nlib_wcslen
498 #define NLIB_LIBC_nlib_wcsnlen
499 #define NLIB_LIBC_nlib_strcpy
500 #define NLIB_LIBC_nlib_strncpy
501 #define NLIB_LIBC_nlib_wcscpy
502 #define NLIB_LIBC_nlib_wcsncpy
503 #define NLIB_LIBC_nlib_strchr
504 #define NLIB_LIBC_nlib_strrchr
505 
506 #if !defined(__INTELLISENSE__)
507 #define NLIB_ATOMIC_RELAXED (0)
508 #define NLIB_ATOMIC_ACQUIRE (1)
509 #define NLIB_ATOMIC_RELEASE (2)
510 #define NLIB_ATOMIC_ACQ_REL (3)
511 #define NLIB_ATOMIC_SEQ_CST (7)
512 
513 //
514 // NOTE:
515 // Windows 8 has xxxNoFence version
516 //
517 
518 static __inline int32_t nlib_atomic_load32(const int32_t* ptr, int memorder) {
519  int32_t result;
520  _ReadWriteBarrier();
521  result = *ptr;
522  (void)memorder;
523  // if (memorder & NLIB_ATOMIC_ACQUIRE)
524  // NLIB_MEMORY_ORDER_ACQUIRE;
525  _ReadWriteBarrier();
526  return result;
527 }
528 
529 static __inline void nlib_atomic_store32(int32_t* ptr, int32_t val, int memorder) {
530  _ReadWriteBarrier();
531  if (memorder != NLIB_ATOMIC_SEQ_CST) {
532  // if (memorder & NLIB_ATOMIC_RELEASE)
533  // NLIB_MEMORY_ORDER_RELEASE;
534  *ptr = val;
535  } else {
536  _InterlockedExchange((volatile long*)ptr, val);
537  }
538  _ReadWriteBarrier();
539 }
540 
541 static __inline int32_t nlib_atomic_exchange32(int32_t* ptr, int32_t val, int memorder) {
542  int32_t result;
543  (void)memorder;
544  _ReadWriteBarrier();
545  result = (int32_t)_InterlockedExchange((volatile long*)ptr, val);
546  _ReadWriteBarrier();
547  return result;
548 }
549 
550 static __inline int
551 nlib_atomic_compare_exchange32(int32_t* ptr, int32_t* expected, int32_t desired, int weak,
552  int success_memorder, int failure_memorder) {
553  int32_t result;
554  _ReadWriteBarrier();
555  result = _InterlockedCompareExchange((volatile long*)ptr, desired, *expected);
556  _ReadWriteBarrier();
557  (void)weak;
558  (void)success_memorder;
559  (void)failure_memorder;
560  if (result == *expected) {
561  return 1;
562  } else {
563  *expected = result;
564  return 0;
565  }
566 }
567 
568 static __inline int32_t nlib_atomic_add_fetch32(int32_t* ptr, int32_t val, int memorder) {
569  int32_t result;
570  (void)memorder;
571  _ReadWriteBarrier();
572  result = _InterlockedExchangeAdd((volatile long*)ptr, val) + val;
573  _ReadWriteBarrier();
574  return result;
575 }
576 
577 static __inline int32_t nlib_atomic_sub_fetch32(int32_t* ptr, int32_t val, int memorder) {
578  int32_t result;
579  (void)memorder;
580  _ReadWriteBarrier();
581  result = _InterlockedExchangeAdd((volatile long*)ptr, -val) - val;
582  _ReadWriteBarrier();
583  return result;
584 }
585 
586 static __inline int32_t nlib_atomic_and_fetch32(int32_t* ptr, int32_t val, int memorder) {
587  int32_t result;
588  (void)memorder;
589  _ReadWriteBarrier();
590  result = _InterlockedAnd((volatile long*)ptr, val) & val;
591  _ReadWriteBarrier();
592  return result;
593 }
594 
595 static __inline int32_t nlib_atomic_xor_fetch32(int32_t* ptr, int32_t val, int memorder) {
596  int32_t result;
597  (void)memorder;
598  _ReadWriteBarrier();
599  result = _InterlockedXor((volatile long*)ptr, val) ^ val;
600  _ReadWriteBarrier();
601  return result;
602 }
603 
604 static __inline int32_t nlib_atomic_or_fetch32(int32_t* ptr, int32_t val, int memorder) {
605  int32_t result;
606  (void)memorder;
607  _ReadWriteBarrier();
608  result = _InterlockedOr((volatile long*)ptr, val) | val;
609  _ReadWriteBarrier();
610  return result;
611 }
612 
613 static __inline int32_t nlib_atomic_fetch_add32(int32_t* ptr, int32_t val, int memorder) {
614  int32_t result;
615  (void)memorder;
616  _ReadWriteBarrier();
617  result = _InterlockedExchangeAdd((volatile long*)ptr, val);
618  _ReadWriteBarrier();
619  return result;
620 }
621 
622 static __inline int32_t nlib_atomic_fetch_sub32(int32_t* ptr, int32_t val, int memorder) {
623  int32_t result;
624  (void)memorder;
625  _ReadWriteBarrier();
626  result = _InterlockedExchangeAdd((volatile long*)ptr, -val);
627  _ReadWriteBarrier();
628  return result;
629 }
630 
631 static __inline int32_t nlib_atomic_fetch_and32(int32_t* ptr, int32_t val, int memorder) {
632  int32_t result;
633  (void)memorder;
634  _ReadWriteBarrier();
635  result = _InterlockedAnd((volatile long*)ptr, val);
636  _ReadWriteBarrier();
637  return result;
638 }
639 
640 static __inline int32_t nlib_atomic_fetch_xor32(int32_t* ptr, int32_t val, int memorder) {
641  int32_t result;
642  (void)memorder;
643  _ReadWriteBarrier();
644  result = _InterlockedXor((volatile long*)ptr, val);
645  _ReadWriteBarrier();
646  return result;
647 }
648 
649 static __inline int32_t nlib_atomic_fetch_or32(int32_t* ptr, int32_t val, int memorder) {
650  int32_t result;
651  (void)memorder;
652  _ReadWriteBarrier();
653  result = _InterlockedOr((volatile long*)ptr, val);
654  _ReadWriteBarrier();
655  return result;
656 }
657 
658 static __inline int64_t nlib_atomic_load64(const int64_t* ptr, int memorder) {
659  int64_t result;
660  _ReadWriteBarrier();
661  result = *ptr;
662  _ReadWriteBarrier();
663  (void)memorder;
664  // if (memorder & NLIB_ATOMIC_ACQUIRE)
665  // NLIB_MEMORY_ORDER_ACQUIRE;
666  return result;
667 }
668 
669 static __inline void nlib_atomic_store64(int64_t* ptr, int64_t val, int memorder) {
670  _ReadWriteBarrier();
671  if (memorder != NLIB_ATOMIC_SEQ_CST) {
672  // if (memorder & NLIB_ATOMIC_RELEASE)
673  // NLIB_MEMORY_ORDER_RELEASE;
674  *ptr = val;
675  } else {
676 #ifndef NLIB_64BIT
677  InterlockedExchange64((volatile long long*)ptr, val);
678 #else
679  _InterlockedExchange64((volatile long long*)ptr, val);
680 #endif
681  }
682  _ReadWriteBarrier();
683 }
684 
685 static __inline int64_t nlib_atomic_exchange64(int64_t* ptr, int64_t val, int memorder) {
686  int64_t result;
687  (void)memorder;
688  _ReadWriteBarrier();
689 #ifndef NLIB_64BIT
690  result = (int64_t)InterlockedExchange64((volatile long long*)ptr, val);
691 #else
692  result = (int64_t)_InterlockedExchange64((volatile long long*)ptr, val);
693 #endif
694  _ReadWriteBarrier();
695  return result;
696 }
697 
698 static __inline void* nlib_atomic_exchangeptr(void** ptr, void* val, int memorder) {
699 #ifndef NLIB_64BIT
700  return (void*)nlib_atomic_exchange32((int32_t*)ptr, (int32_t)val, memorder);
701 #else
702  return (void*)nlib_atomic_exchange64((int64_t*)ptr, (int64_t)val, memorder);
703 #endif
704 }
705 
706 static __inline int
707 nlib_atomic_compare_exchange64(int64_t* ptr, int64_t* expected, int64_t desired, int weak,
708  int success_memorder, int failure_memorder) {
709  int64_t result;
710  _ReadWriteBarrier();
711 #ifndef NLIB_64BIT
712  result = InterlockedCompareExchange64((volatile long long*)ptr, desired, *expected);
713 #else
714  result = _InterlockedCompareExchange64((volatile long long*)ptr, desired, *expected);
715 #endif
716  _ReadWriteBarrier();
717  (void)weak;
718  (void)success_memorder;
719  (void)failure_memorder;
720  if (result == *expected) {
721  return 1;
722  } else {
723  *expected = result;
724  return 0;
725  }
726 }
727 
728 static __inline int64_t nlib_atomic_add_fetch64(int64_t* ptr, int64_t val, int memorder) {
729  int64_t result;
730  (void)memorder;
731  _ReadWriteBarrier();
732 #ifndef NLIB_64BIT
733  result = InterlockedExchangeAdd64((volatile long long*)ptr, val) + val;
734 #else
735  result = _InterlockedExchangeAdd64((volatile long long*)ptr, val) + val;
736 #endif
737  _ReadWriteBarrier();
738  return result;
739 }
740 
741 static __inline int64_t nlib_atomic_sub_fetch64(int64_t* ptr, int64_t val, int memorder) {
742  int64_t result;
743  (void)memorder;
744  _ReadWriteBarrier();
745 #ifndef NLIB_64BIT
746  result = InterlockedExchangeAdd64((volatile long long*)ptr, -val) - val;
747 #else
748  result = _InterlockedExchangeAdd64((volatile long long*)ptr, -val) - val;
749 #endif
750  _ReadWriteBarrier();
751  return result;
752 }
753 
754 static __inline int64_t nlib_atomic_and_fetch64(int64_t* ptr, int64_t val, int memorder) {
755  int64_t result;
756  (void)memorder;
757  _ReadWriteBarrier();
758 #ifndef NLIB_64BIT
759  result = InterlockedAnd64((volatile long long*)ptr, val) & val;
760 #else
761  result = _InterlockedAnd64((volatile long long*)ptr, val) & val;
762 #endif
763  _ReadWriteBarrier();
764  return result;
765 }
766 
767 static __inline int64_t nlib_atomic_xor_fetch64(int64_t* ptr, int64_t val, int memorder) {
768  int64_t result;
769  (void)memorder;
770  _ReadWriteBarrier();
771 #ifndef NLIB_64BIT
772  result = InterlockedXor64((volatile long long*)ptr, val) ^ val;
773 #else
774  result = _InterlockedXor64((volatile long long*)ptr, val) ^ val;
775 #endif
776  _ReadWriteBarrier();
777  return result;
778 }
779 
780 static __inline int64_t nlib_atomic_or_fetch64(int64_t* ptr, int64_t val, int memorder) {
781  int64_t result;
782  (void)memorder;
783  _ReadWriteBarrier();
784 #ifndef NLIB_64BIT
785  result = InterlockedOr64((volatile long long*)ptr, val) | val;
786 #else
787  result = _InterlockedOr64((volatile long long*)ptr, val) | val;
788 #endif
789  _ReadWriteBarrier();
790  return result;
791 }
792 
793 static __inline int64_t nlib_atomic_fetch_add64(int64_t* ptr, int64_t val, int memorder) {
794  int64_t result;
795  (void)memorder;
796  _ReadWriteBarrier();
797 #ifndef NLIB_64BIT
798  result = InterlockedExchangeAdd64((volatile long long*)ptr, val);
799 #else
800  result = _InterlockedExchangeAdd64((volatile long long*)ptr, val);
801 #endif
802  _ReadWriteBarrier();
803  return result;
804 }
805 
806 static __inline int64_t nlib_atomic_fetch_sub64(int64_t* ptr, int64_t val, int memorder) {
807  int64_t result;
808  (void)memorder;
809  _ReadWriteBarrier();
810 #ifndef NLIB_64BIT
811  result = InterlockedExchangeAdd64((volatile long long*)ptr, -val);
812 #else
813  result = _InterlockedExchangeAdd64((volatile long long*)ptr, -val);
814 #endif
815  _ReadWriteBarrier();
816  return result;
817 }
818 
819 static __inline int64_t nlib_atomic_fetch_and64(int64_t* ptr, int64_t val, int memorder) {
820  int64_t result;
821  (void)memorder;
822  _ReadWriteBarrier();
823 #ifndef NLIB_64BIT
824  result = InterlockedAnd64((volatile long long*)ptr, val);
825 #else
826  result = _InterlockedAnd64((volatile long long*)ptr, val);
827 #endif
828  _ReadWriteBarrier();
829  return result;
830 }
831 
832 static __inline int64_t nlib_atomic_fetch_xor64(int64_t* ptr, int64_t val, int memorder) {
833  int64_t result;
834  (void)memorder;
835  _ReadWriteBarrier();
836 #ifndef NLIB_64BIT
837  result = InterlockedXor64((volatile long long*)ptr, val);
838 #else
839  result = _InterlockedXor64((volatile long long*)ptr, val);
840 #endif
841  _ReadWriteBarrier();
842  return result;
843 }
844 
845 static __inline int64_t nlib_atomic_fetch_or64(int64_t* ptr, int64_t val, int memorder) {
846  int64_t result;
847  (void)memorder;
848  _ReadWriteBarrier();
849 #ifndef NLIB_64BIT
850  result = InterlockedOr64((volatile long long*)ptr, val);
851 #else
852  result = _InterlockedOr64((volatile long long*)ptr, val);
853 #endif
854  _ReadWriteBarrier();
855  return result;
856 }
857 
858 static __inline void* nlib_atomic_loadptr(void* const* ptr, int memorder) {
859  void* result;
860  _ReadWriteBarrier();
861  result = *ptr;
862  _ReadWriteBarrier();
863  (void)memorder;
864  // if (memorder & NLIB_ATOMIC_ACQUIRE)
865  // NLIB_MEMORY_ORDER_ACQUIRE;
866  return result;
867 }
868 
869 static __inline void nlib_atomic_storeptr(void** ptr, void* val, int memorder) {
870  _ReadWriteBarrier();
871  if (memorder != NLIB_ATOMIC_SEQ_CST) {
872  // if (memorder & NLIB_ATOMIC_RELEASE)
873  // NLIB_MEMORY_ORDER_RELEASE;
874  *ptr = val;
875  } else {
876 #if (_MSC_VER == 1800 && !defined(NLIB_64BIT))
877  InterlockedExchangePointer((void* volatile*)ptr, val);
878 #else
879  _InterlockedExchangePointer((void* volatile*)ptr, val);
880 #endif
881  }
882  _ReadWriteBarrier();
883 }
884 
885 static __inline int
886 nlib_atomic_compare_exchangeptr(void** ptr, void** expected, void* desired, int weak,
887  int success_memorder, int failure_memorder) {
888  void* result;
889  _ReadWriteBarrier();
890  result = _InterlockedCompareExchangePointer((void* volatile*)ptr, desired, *expected);
891  _ReadWriteBarrier();
892  (void)weak;
893  (void)success_memorder;
894  (void)failure_memorder;
895  if (result == *expected) {
896  return 1;
897  } else {
898  *expected = result;
899  return 0;
900  }
901 }
902 
903 static __inline void nlib_atomic_thread_fence(int memorder) {
904  switch (memorder) {
905  case NLIB_ATOMIC_RELAXED:
906  break;
907  case NLIB_ATOMIC_ACQUIRE:
909  break;
910  case NLIB_ATOMIC_RELEASE:
912  break;
913  default:
915  break;
916  }
917 }
918 #endif
919 
920 #ifdef __cplusplus
921 }
922 #endif
923 
924 #ifndef _WIN64
925 #define NLIB_ALTNAME(func1, func2) \
926  __pragma(comment(linker, "/alternatename:_" NLIB_STRINGIFY(func1) "=_" NLIB_STRINGIFY(func2)))
927 #else
928 #define NLIB_ALTNAME(func1, func2) \
929  __pragma(comment(linker, "/alternatename:" NLIB_STRINGIFY(func1) "=" NLIB_STRINGIFY(func2)))
930 #endif
931 
932 NLIB_ALTNAME(nlib_malloc, malloc)
933 NLIB_ALTNAME(nlib_free, free)
934 NLIB_ALTNAME(nlib_calloc, calloc)
935 NLIB_ALTNAME(nlib_realloc, realloc)
936 NLIB_ALTNAME(nlib_free_size, nlib_free_size_)
937 
938 #if defined(NLIB_SIMD)
939 #ifndef NLIB_LIBC_nlib_strlen
940 NLIB_ALTNAME(nlib_strlen, nlib_strlen_simd)
941 #endif
942 #ifndef NLIB_LIBC_nlib_strlen
943 NLIB_ALTNAME(nlib_strnlen, nlib_strnlen_simd)
944 #endif
945 NLIB_ALTNAME(nlib_utf16len_, nlib_utf16len_simd)
946 NLIB_ALTNAME(nlib_utf16nlen_, nlib_utf16nlen_simd)
947 NLIB_ALTNAME(nlib_utf32len_, nlib_utf32len_generic)
948 NLIB_ALTNAME(nlib_utf32nlen_, nlib_utf32nlen_generic)
949 NLIB_ALTNAME(nlib_utf16cplen_ex_, nlib_utf16cplen_ex_simd)
950 NLIB_ALTNAME(nlib_strchr, nlib_strchr_simd)
951 NLIB_ALTNAME(nlib_strrchr, strrchr)
952 NLIB_ALTNAME(nlib_strchr_mb, nlib_strchr_mb_simd)
953 NLIB_ALTNAME(nlib_memcmp, nlib_memcmp_simd)
954 NLIB_ALTNAME(nlib_memchr, nlib_memchr_simd)
955 NLIB_ALTNAME(nlib_memrchr, nlib_memrchr_simd)
956 NLIB_ALTNAME(nlib_memchr_not, nlib_memchr_not_simd)
957 NLIB_ALTNAME(nlib_memchr_range_not, nlib_memchr_range_not_simd)
958 NLIB_ALTNAME(nlib_memchr_lt, nlib_memchr_lt_simd)
959 NLIB_ALTNAME(nlib_memchr_gt, nlib_memchr_gt_simd)
960 NLIB_ALTNAME(nlib_memchr_mb, nlib_memchr_mb_simd)
961 NLIB_ALTNAME(nlib_skipws, nlib_skipws_simd)
962 NLIB_ALTNAME(nlib_swapendian_16, nlib_swapendian_16_simd)
963 NLIB_ALTNAME(nlib_swapendian_32, nlib_swapendian_32_simd)
964 NLIB_ALTNAME(nlib_swapendian_64, nlib_swapendian_64_simd)
965 #else
966 #ifndef NLIB_LIBC_nlib_strlen
967 NLIB_ALTNAME(nlib_strlen, nlib_strlen_generic)
968 #endif
969 #ifndef NLIB_LIBC_nlib_strlen
970 NLIB_ALTNAME(nlib_strnlen, nlib_strnlen_generic)
971 #endif
972 NLIB_ALTNAME(nlib_utf16len_, nlib_utf16len_generic)
973 NLIB_ALTNAME(nlib_utf16nlen_, nlib_utf16nlen_generic)
974 NLIB_ALTNAME(nlib_utf32len_, nlib_utf32len_generic)
975 NLIB_ALTNAME(nlib_utf32nlen_, nlib_utf32nlen_generic)
976 NLIB_ALTNAME(nlib_utf16cplen_ex_, nlib_utf16cplen_ex_generic)
977 NLIB_ALTNAME(nlib_strchr, nlib_strchr_generic)
978 NLIB_ALTNAME(nlib_strrchr, nlib_strrchr_generic)
979 NLIB_ALTNAME(nlib_strchr_mb, nlib_strchr_mb_generic)
980 NLIB_ALTNAME(nlib_memcmp, nlib_memcmp_generic)
981 NLIB_ALTNAME(nlib_memchr, nlib_memchr_generic)
982 NLIB_ALTNAME(nlib_memrchr, nlib_memrchr_generic)
983 NLIB_ALTNAME(nlib_memchr_not, nlib_memchr_not_generic)
984 NLIB_ALTNAME(nlib_memchr_range_not, nlib_memchr_range_not_generic)
985 NLIB_ALTNAME(nlib_memchr_lt, nlib_memchr_lt_generic)
986 NLIB_ALTNAME(nlib_memchr_gt, nlib_memchr_gt_generic)
987 NLIB_ALTNAME(nlib_memchr_mb, nlib_memchr_mb_generic)
988 NLIB_ALTNAME(nlib_skipws, nlib_skipws_generic)
989 NLIB_ALTNAME(nlib_swapendian_16, nlib_swapendian_16_generic)
990 NLIB_ALTNAME(nlib_swapendian_32, nlib_swapendian_32_generic)
991 NLIB_ALTNAME(nlib_swapendian_64, nlib_swapendian_64_generic)
992 #endif
993 
994 #endif
995 #endif // INCLUDE_NN_NLIB_PLATFORM_WIN32_H_
int32_t nlib_atomic_xor_fetch32(int32_t *ptr, int32_t val, int memorder)
Calculates XOR of atomic values. Its behavior is similar to the one for __atomic_xor_fetch() of gcc...
int64_t nlib_atomic_fetch_and64(int64_t *ptr, int64_t val, int memorder)
Calculates AND of atomic values. Its behavior is similar to the one for __atomic_fetch_and() of gcc...
const char * nlib_strrchr(const char *s, int c)
Searches for a character from the end of a string.
void * nlib_atomic_exchangeptr(void **ptr, void *val, int memorder)
Swaps values in an atomic manner. Its behavior is similar to the one for __atomic_exchange_n() of gcc...
int nlib_atomic_compare_exchangeptr(void **ptr, void **expected, void *desired, int weak, int success_memorder, int failure_memorder)
Compares and swaps atomic values. Its behavior is similar to the one for __atomic_compare_exchange_n(...
int32_t nlib_atomic_load32(const int32_t *ptr, int memorder)
Loads a value in an atomic operation. Its behavior is similar to the one for __atomic_load_n() of gcc...
void * nlib_calloc(size_t nmemb, size_t size)
A weak function that calls the C standard function calloc. nlib calls calloc via this function...
int64_t nlib_atomic_fetch_add64(int64_t *ptr, int64_t val, int memorder)
Adds atomic values. Its behavior is similar to the one for __atomic_fetch_add() of gcc...
const void * nlib_memchr_lt(const void *s, int c, size_t n)
Searches the n bytes from the start of memory region (s, s + n) and returns a pointer to data having ...
struct nlib_rwlock_ nlib_rwlock
The type for a read-write lock object.
Definition: Platform.h:871
sem_t nlib_semaphore
The type for a semaphore object.
#define NLIB_MEMORY_ORDER_ACQUIRE
A memory fence. Corresponds to atomic_thread_fence(memory_order_acquire) in C++11.
size_t nlib_strnlen(const char *s, size_t maxsize)
An implementation corresponding to N1078 strnlen_s.
int nlib_memcmp(const void *buf1, const void *buf2, size_t n)
Compares the n bytes from the starts of buf1 and buf2 as unsigned char data.
#define NLIB_ATOMIC_RELEASE
Similar to __ATOMIC_RELEASE of gcc or std::memory_order_release of C++11.
const void * nlib_memchr_not(const void *s, int c, size_t n)
Searches the n bytes from the start of memory region(s, s + n) and returns a pointer that does not po...
int32_t nlib_atomic_or_fetch32(int32_t *ptr, int32_t val, int memorder)
Calculates OR of atomic values. Its behavior is similar to the one for __atomic_or_fetch() of gcc...
const char * nlib_skipws(size_t *cnt_lf, const char **last_lf, const char *s, size_t n)
Searches a string made up of n characters and returns the pointer to the first character found that i...
int64_t nlib_atomic_fetch_sub64(int64_t *ptr, int64_t val, int memorder)
Subtracts atomic values. Its behavior is similar to the one for __atomic_fetch_sub() of gcc...
void nlib_free_size(void *ptr, size_t size)
Frees memory of a specified size. The default action is to call the nlib_free function.
int64_t nlib_atomic_and_fetch64(int64_t *ptr, int64_t val, int memorder)
Calculates AND of atomic values. Its behavior is similar to the one for __atomic_and_fetch() of gcc...
int nlib_atomic_compare_exchange64(int64_t *ptr, int64_t *expected, int64_t desired, int weak, int success_memorder, int failure_memorder)
Compares and swaps atomic values. Its behavior is similar to the one for __atomic_compare_exchange_n(...
#define NLIB_VIS_PUBLIC
Symbols for functions and classes are made available outside of the library.
Definition: Platform_unix.h:87
const char * nlib_strchr(const char *s, int c)
Searches for a character from the start of a string.
int64_t nlib_atomic_fetch_or64(int64_t *ptr, int64_t val, int memorder)
Calculates OR of atomic values. Its behavior is similar to the one for __atomic_fetch_or() of gcc...
const void * nlib_memchr(const void *s, int c, size_t n)
Searches the n bytes from the start of the memory region (s, s + n) and returns a pointer to byte c...
void * nlib_malloc(size_t size)
A weak function that calls the C standard function malloc. nlib calls malloc via this function...
#define NLIB_ATOMIC_ACQUIRE
Similar to __ATOMIC_ACQUIRE of gcc or std::memory_order_acquire of C++11.
pthread_key_t nlib_tls
The type for TLS slot IDs.
void * nlib_atomic_loadptr(void *const *ptr, int memorder)
Loads a value in an atomic operation. Its behavior is similar to the one for __atomic_load_n() of gcc...
int64_t nlib_atomic_exchange64(int64_t *ptr, int64_t val, int memorder)
Swaps values in an atomic operation. Its behavior is similar to the one for __atomic_exchange_n() of ...
#define NLIB_MEMORY_ORDER_SEQ_CST
A memory fence. Corresponds to atomic_thread_fence(memory_order_seq_cst) in C++11.
const void * nlib_memrchr(const void *s, int c, size_t n)
Searches the n bytes from the end of memory region (s, s + n) and returns a pointer to byte c...
int64_t nlib_atomic_sub_fetch64(int64_t *ptr, int64_t val, int memorder)
Subtracts atomic values. Its behavior is similar to the one for __atomic_sub_fetch() of gcc...
int32_t nlib_atomic_fetch_xor32(int32_t *ptr, int32_t val, int memorder)
Calculates XOR of atomic values. Its behavior is similar to the one for __atomic_fetch_xor() of gcc...
int32_t nlib_atomic_sub_fetch32(int32_t *ptr, int32_t val, int memorder)
Subtracts atomic values. Its behavior is similar to the one for __atomic_sub_fetch() of gcc...
int32_t nlib_atomic_fetch_sub32(int32_t *ptr, int32_t val, int memorder)
Subtracts atomic values. Its behavior is similar to the one for __atomic_fetch_sub() of gcc...
int32_t nlib_atomic_add_fetch32(int32_t *ptr, int32_t val, int memorder)
Adds atomic values. Its behavior is similar to the one for __atomic_add_fetch() of gcc...
void nlib_atomic_storeptr(void **ptr, void *val, int memorder)
Stores a value in an atomic operation. Its behavior is similar to the one for __atomic_store_n() of g...
void nlib_atomic_thread_fence(int memorder)
Places the specified memory barrier.
int32_t nlib_atomic_fetch_and32(int32_t *ptr, int32_t val, int memorder)
Calculates AND of atomic values. Its behavior is similar to the one for __atomic_fetch_and() of gcc...
pthread_cond_t nlib_cond
The type for a condition variable object.
void * nlib_realloc(void *ptr, size_t size)
A weak function that calls the C standard function realloc. nlib calls realloc via this function...
errno_t nlib_swapendian_32(uint32_t *p, size_t count)
Swaps the endianness.
#define NLIB_ATOMIC_RELAXED
Similar to __ATOMIC_RELAXED of gcc or std::memory_order_relaxed of C++11.
size_t nlib_strlen(const char *s)
Internally calls strlen(). In some cases, it may operate as an independent implementation.
pthread_mutex_t nlib_mutex
The type for mutex variables.
const void * nlib_memchr_range_not(const void *s, const char *range, size_t n)
Searches the n bytes from the start of memory region (s, s + n) and returns a pointer to a character ...
int64_t nlib_atomic_xor_fetch64(int64_t *ptr, int64_t val, int memorder)
Calculates XOR of atomic values. Its behavior is similar to the one for __atomic_xor_fetch() of gcc...
#define NLIB_MEMORY_ORDER_RELEASE
A memory fence. Corresponds to atomic_thread_fence(memory_order_release) in C++11.
int64_t nlib_atomic_add_fetch64(int64_t *ptr, int64_t val, int memorder)
Adds atomic values. Its behavior is similar to the one for __atomic_add_fetch() of gcc...
errno_t nlib_swapendian_16(uint16_t *p, size_t count)
Swaps the endianness.
const void * nlib_memchr_gt(const void *s, int c, size_t n)
Searches the n bytes from the start of memory region (s, s + n) and returns a pointer to data having ...
int32_t nlib_atomic_and_fetch32(int32_t *ptr, int32_t val, int memorder)
Calculates AND of atomic values. Its behavior is similar to the one for __atomic_and_fetch() of gcc...
int nlib_atomic_compare_exchange32(int32_t *ptr, int32_t *expected, int32_t desired, int weak, int success_memorder, int failure_memorder)
Compares and swaps atomic values. Its behavior is similar to the one for __atomic_compare_exchange_n(...
void nlib_atomic_store64(int64_t *ptr, int64_t val, int memorder)
Stores a value in an atomic operation. Its behavior is similar to the one for __atomic_store_n() of g...
void nlib_free(void *ptr)
A weak function that calls the C standard function free. nlib calls free via this function...
errno_t nlib_swapendian_64(uint64_t *p, size_t count)
Swaps the endianness.
int64_t nlib_atomic_or_fetch64(int64_t *ptr, int64_t val, int memorder)
Calculates OR of atomic values. Its behavior is similar to the one for __atomic_or_fetch() of gcc...
#define NLIB_ATOMIC_SEQ_CST
Similar to __ATOMIC_SEQ_CST of gcc or std::memory_order_seq_cst of C++11.
int32_t nlib_atomic_fetch_or32(int32_t *ptr, int32_t val, int memorder)
Calculates OR of atomic values. Its behavior is similar to the one for __atomic_fetch_or() of gcc...
int64_t nlib_atomic_fetch_xor64(int64_t *ptr, int64_t val, int memorder)
Calculates XOR of atomic values. Its behavior is similar to the one for __atomic_fetch_xor() of gcc...
const void * nlib_memchr_mb(const void *s, size_t n)
Searches the n bytes from the start of memory region (s, s + n) and returns a pointer to the location...
int32_t nlib_atomic_fetch_add32(int32_t *ptr, int32_t val, int memorder)
Adds atomic values. Its behavior is similar to the one for __atomic_fetch_add() of gcc...
void nlib_atomic_store32(int32_t *ptr, int32_t val, int memorder)
Stores a value in an atomic operation. Its behavior is similar to the one for __atomic_store_n() of g...
int32_t nlib_atomic_exchange32(int32_t *ptr, int32_t val, int memorder)
Swaps values in an atomic operation. Its behavior is similar to the one for __atomic_exchange_n() of ...
pthread_t nlib_thread
The identifier for threads.
int64_t nlib_atomic_load64(const int64_t *ptr, int memorder)
Loads a value in an atomic operation. Its behavior is similar to the one for __atomic_load_n() of gcc...