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 #include <sal.h>
70 
71 #if WINVER < 0x0603
72 # pragma message(__FILE__ ": Please update your Windows SDK")
73 #endif
74 
75 #if (!defined(_M_IX86_FP) || _M_IX86_FP < 2) && !defined(_M_X64) && !defined(_M_AMD64)
76 # error /arch:SSE2 or higher must be set
77 #endif
78 
79 #ifndef NLIB_SSE41
80 # define NLIB_SSE41
81 #endif
82 
83 #ifndef NLIB_SSE42
84 # define NLIB_SSE42
85 #endif
86 
87 #ifdef __cplusplus
88 #define NLIB_CXX11_SWAPHEADER
89 #define NLIB_CXX11_STATIC_ASSERTIONS
90 #define NLIB_CXX11_NULL_POINTER_CONSTANT
91 #define NLIB_CXX11_RVALUE_REFERENCES
92 #define NLIB_CXX11_LAMBDAS
93 #define NLIB_CXX11_UNIQUEPTR
94 #define NLIB_CXX11_EXPLICIT_VIRTUAL_OVERRIDES
95 #define NLIB_CXX11_RANGE_BASED_FOR
96 #define NLIB_CXX11_STDLIB_CHRONO
97 #define NLIB_CXX11_STDLIB_ATOMIC
98 #define NLIB_CXX11_STDLIB_ARRAY
99 #define NLIB_CXX11_STDLIB_UNORDERED
100 #define NLIB_CXX11_STDLIB_TUPLE
101 
102 #define NLIB_HAS_NATIVE_TYPETRAITS
103 
104 #define NLIB_CXX11_EXPLICIT_CONVERSION_OPERATORS
105 #define NLIB_CXX11_TEMPLATE_ALIAS
106 #define NLIB_CXX11_VARIADIC_TEMPLATES
107 #define NLIB_CXX11_DELEGATING_CONSTRUCTORS
108 #define NLIB_CXX11_STDLIB_RANDOM
109 #define NLIB_CXX11_DEFAULT_TEMPLATE_ARGUMENT_FOR_FUNCTION_TEMPLATES
110 #if _MSC_VER >= 1900
111 # define NLIB_CXX11_CONSTEXPR
112 # define NLIB_CXX11_NOEXCEPT
113 # define NLIB_CXX11_NEW_CHARACTER_TYPES
114 # define NLIB_CXX11_ALIGNMENT_SUPPORT
115 # define NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS
116 #endif
117 #endif
118 
119 #include <stdint.h>
120 #include <inttypes.h>
121 #if (_MSC_VER < 1900)
122 # ifndef __func__
123 # define __func__ __FUNCTION__
124 # endif
125 #endif
126 
127 #ifdef __cplusplus
128 extern "C" {
129 #endif
130 
131 #ifndef va_copy
132 # define va_copy(dest, src) (dest = src)
133 #endif
134 #define NLIB_ALWAYS_INLINE __forceinline
135 #define NLIB_NEVER_INLINE __declspec(noinline)
136 #define NLIB_LIKELY(x) (x)
137 #define NLIB_UNLIKELY(x) (x)
138 #define NLIB_EXPECT(var, exp_value) (var)
139 #define NLIB_CHECK_RESULT
140 #define NLIB_NORETURN
141 #define NLIB_NONNULL
142 #define NLIB_NONNULL_1
143 #define NLIB_NONNULL_2
144 #define NLIB_NONNULL_3
145 #define NLIB_NONNULL_4
146 #define NLIB_NONNULL_5
147 #define NLIB_ATTRIBUTE_MALLOC
148 #define NLIB_ATTRIBUTE_PURE
149 #define NLIB_ATTRIBUTE_CONST
150 #define NLIB_ATTRIBUTE_ALLOC_SIZE1(n)
151 #define NLIB_ATTRIBUTE_ALLOC_SIZE2(n0, n1)
152 #define NLIB_ATTRIBUTE_ALLOC_ALIGN(algn)
153 #define NLIB_ATTRIBUTE_ASSUME_ALIGNED(n)
154 #ifndef NLIB_DEPRECATED
155 #define NLIB_DEPRECATED __declspec(deprecated)
156 #endif
157 #ifndef NLIB_DEPRECATED_MSG
158 #define NLIB_DEPRECATED_MSG(msg) __declspec(deprecated(msg))
159 #endif
160 #define NLIB_WEAKSYMBOL
161 #define NLIB_VIS_HIDDEN
162 #ifdef NLIB_WINDLL
163 # define NLIB_EXPIMP_TEMPLATE_(x) template class NLIB_VIS_PUBLIC x
164 # define NLIB_WINEXPORT __declspec(dllexport)
165 # define NLIB_WINIMPORT __declspec(dllimport)
166 # define NLIB_VIS_PUBLIC NLIB_WINIMPORT
167 # define NLIB_EXPIMP_TEMPLATE(x) extern NLIB_EXPIMP_TEMPLATE_(x)
168 #else
169 # define NLIB_VIS_PUBLIC
170 # define NLIB_EXPIMP_TEMPLATE(x)
171 #endif
172 
173 #if defined(n_EXPORTS)
174 # undef NLIB_VIS_PUBLIC
175 # define NLIB_VIS_PUBLIC NLIB_WINEXPORT
176 #elif defined(nx_misc_EXPORTS)
177 # undef NLIB_EXPIMP_TEMPLATE
178 # define NLIB_EXPIMP_TEMPLATE(x) NLIB_EXPIMP_TEMPLATE_(x)
179 #endif
180 
181 #define NLIB_VIS_PUBLIC_ALT
182 
183 #define NLIB_LITTLE_ENDIAN
184 
185 // NOTE:
186 // _WriteBarrier() for the compiler, _mm_sfence() for the processor, ...
187 // NOTE:
188 // You have to comment out error lines in intrin.h if you use VC++2005.
189 // See:
190 // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=262047
191 // http://www.hydrogenaudio.org/forums/index.php?showtopic=50972
192 #define NLIB_MEMORY_ORDER_RELEASE \
193  __pragma(warning(push)) \
194  __pragma(warning(disable:4127)) \
195  do { _WriteBarrier(); _mm_sfence(); } while (0) \
196  __pragma(warning(pop))
197 #define NLIB_MEMORY_ORDER_ACQUIRE \
198  __pragma(warning(push)) \
199  __pragma(warning(disable:4127)) \
200  do { _ReadBarrier(); _mm_lfence(); } while (0) \
201  __pragma(warning(pop))
202 #define NLIB_MEMORY_ORDER_ACQ_REL \
203  __pragma(warning(push)) \
204  __pragma(warning(disable:4127)) \
205  do { _ReadWriteBarrier(); _mm_mfence(); } while (0) \
206  __pragma(warning(pop))
207 #define NLIB_MEMORY_ORDER_SEQ_CST NLIB_MEMORY_ORDER_ACQ_REL
208 
209 // because "%zu" not supported ...
210 #ifdef NLIB_64BIT
211 # define __PRIS_PREFIX "ll"
212 #else
213 # define __PRIS_PREFIX
214 #endif
215 #define NLIB_WARN__(x) #x
216 #define NLIB_WARN_(x) NLIB_WARN__(x)
217 #define NLIB_WARN(exp) (__FILE__ "(" NLIB_WARN_(__LINE__) ") : WARNING: " exp)
218 
219 typedef unsigned int nlib_tls;
220 
221 #if _MSC_VER >= 1900
222 #define NLIB_TIMESPEC_HAS_NATIVE
223 #endif
224 
225 #pragma pack(push, 8)
226 typedef struct nlib_mutex_ {
227  int32_t mark;
228  uint32_t cat;
229  union {
230  HANDLE h;
231  CRITICAL_SECTION cs;
232  } data;
233 } nlib_mutex;
234 #pragma pack(pop)
235 #define NLIB_MUTEX_INITIALIZER { 0x6768696AU, 0 }
236 #define NLIB_RECURSIVE_MUTEX_INITIALIZER { 0x6768696AU, 1 }
237 #define NLIB_RECURSIVE_TIMED_MUTEX_INITIALIZER { 0x6768696AU, 2 }
238 
239 typedef HANDLE nlib_semaphore;
240 
241 typedef struct nlib_cond_ {
242  CONDITION_VARIABLE cond;
243  nlib_mutex mutex;
244 } nlib_cond;
245 #define NLIB_COND_INITIALIZER { 0, NLIB_MUTEX_INITIALIZER }
246 
247 typedef HANDLE nlib_thread;
248 
249 #define NLIB_ATTRIBUTE_PRINTF(x, y)
250 
251 #define NLIB_ASSUME(cond) __assume(cond)
252 
253 #define NLIB_RWLOCK_HAS_NATIVE
254 #ifdef NLIB_RWLOCK_HAS_NATIVE
255 typedef SRWLOCK nlib_rwlock;
256 #define NLIB_RWLOCK_INITIALIZER SRWLOCK_INIT
257 #endif
258 #define NLIB_TIMER_HAS_NATIVE
259 #define NLIB_ONCE_HAS_NATIVE
260 
261 NLIB_VIS_PUBLIC void nlib_free_size_(void* ptr, size_t size);
262 
263 #define NLIB_LIBC_nlib_memcmp
264 #define NLIB_LIBC_nlib_strlen
265 #define NLIB_LIBC_nlib_strnlen
266 #define NLIB_LIBC_nlib_wcslen
267 #define NLIB_LIBC_nlib_wcsnlen
268 #define NLIB_LIBC_nlib_strcpy
269 #define NLIB_LIBC_nlib_strncpy
270 #define NLIB_LIBC_nlib_wcscpy
271 #define NLIB_LIBC_nlib_wcsncpy
272 #define NLIB_LIBC_nlib_strchr
273 #define NLIB_LIBC_nlib_strrchr
274 
275 #if !defined(__INTELLISENSE__)
276 #define NLIB_ATOMIC_RELAXED (0)
277 #define NLIB_ATOMIC_ACQUIRE (1)
278 #define NLIB_ATOMIC_RELEASE (2)
279 #define NLIB_ATOMIC_ACQ_REL (3)
280 #define NLIB_ATOMIC_SEQ_CST (7)
281 
282 //
283 // NOTE:
284 // Windows 8 has xxxNoFence version
285 //
286 
287 static __inline int32_t nlib_atomic_load32(const int32_t* ptr, int memorder) {
288  int32_t result;
289  _ReadWriteBarrier();
290  result = *ptr;
291  (void)memorder;
292  // if (memorder & NLIB_ATOMIC_ACQUIRE)
293  // NLIB_MEMORY_ORDER_ACQUIRE;
294  _ReadWriteBarrier();
295  return result;
296 }
297 
298 static __inline void nlib_atomic_store32(int32_t* ptr, int32_t val, int memorder) {
299  _ReadWriteBarrier();
300  if (memorder != NLIB_ATOMIC_SEQ_CST) {
301  // if (memorder & NLIB_ATOMIC_RELEASE)
302  // NLIB_MEMORY_ORDER_RELEASE;
303  *ptr = val;
304  } else {
305  _InterlockedExchange((volatile long*)ptr, val); // NOLINT
306  }
307  _ReadWriteBarrier();
308 }
309 
310 static __inline int32_t nlib_atomic_exchange32(int32_t* ptr, int32_t val,
311  int memorder) {
312  int32_t result;
313  (void)memorder;
314  _ReadWriteBarrier();
315  result = (int32_t)_InterlockedExchange((volatile long*)ptr, val); // NOLINT
316  _ReadWriteBarrier();
317  return result;
318 }
319 
320 static __inline int nlib_atomic_compare_exchange32(int32_t* ptr, int32_t* expected,
321  int32_t desired, int weak,
322  int success_memorder, int failure_memorder) {
323  int32_t result;
324  _ReadWriteBarrier();
325  result = _InterlockedCompareExchange((volatile long*)ptr, desired, *expected); // NOLINT
326  _ReadWriteBarrier();
327  (void)weak;
328  (void)success_memorder;
329  (void)failure_memorder;
330  if (result == *expected) {
331  return 1;
332  } else {
333  *expected = result;
334  return 0;
335  }
336 }
337 
338 static __inline int32_t nlib_atomic_add_fetch32(int32_t* ptr, int32_t val,
339  int memorder) {
340  int32_t result;
341  (void)memorder;
342  _ReadWriteBarrier();
343  result = _InterlockedExchangeAdd((volatile long*)ptr, val) + val; // NOLINT
344  _ReadWriteBarrier();
345  return result;
346 }
347 
348 static __inline int32_t nlib_atomic_sub_fetch32(int32_t* ptr, int32_t val,
349  int memorder) {
350  int32_t result;
351  (void)memorder;
352  _ReadWriteBarrier();
353  result = _InterlockedExchangeAdd((volatile long*)ptr, -val) - val; // NOLINT
354  _ReadWriteBarrier();
355  return result;
356 }
357 
358 static __inline int32_t nlib_atomic_and_fetch32(int32_t* ptr, int32_t val,
359  int memorder) {
360  int32_t result;
361  (void)memorder;
362  _ReadWriteBarrier();
363  result = _InterlockedAnd((volatile long*)ptr, val) & val; // NOLINT
364  _ReadWriteBarrier();
365  return result;
366 }
367 
368 static __inline int32_t nlib_atomic_xor_fetch32(int32_t* ptr, int32_t val,
369  int memorder) {
370  int32_t result;
371  (void)memorder;
372  _ReadWriteBarrier();
373  result = _InterlockedXor((volatile long*)ptr, val) ^ val; // NOLINT
374  _ReadWriteBarrier();
375  return result;
376 }
377 
378 static __inline int32_t nlib_atomic_or_fetch32(int32_t* ptr, int32_t val,
379  int memorder) {
380  int32_t result;
381  (void)memorder;
382  _ReadWriteBarrier();
383  result = _InterlockedOr((volatile long*)ptr, val) | val; // NOLINT
384  _ReadWriteBarrier();
385  return result;
386 }
387 
388 static __inline int32_t nlib_atomic_fetch_add32(int32_t* ptr, int32_t val,
389  int memorder) {
390  int32_t result;
391  (void)memorder;
392  _ReadWriteBarrier();
393  result = _InterlockedExchangeAdd((volatile long*)ptr, val); // NOLINT
394  _ReadWriteBarrier();
395  return result;
396 }
397 
398 static __inline int32_t nlib_atomic_fetch_sub32(int32_t* ptr, int32_t val,
399  int memorder) {
400  int32_t result;
401  (void)memorder;
402  _ReadWriteBarrier();
403  result = _InterlockedExchangeAdd((volatile long*)ptr, -val); // NOLINT
404  _ReadWriteBarrier();
405  return result;
406 }
407 
408 static __inline int32_t nlib_atomic_fetch_and32(int32_t* ptr, int32_t val,
409  int memorder) {
410  int32_t result;
411  (void)memorder;
412  _ReadWriteBarrier();
413  result = _InterlockedAnd((volatile long*)ptr, val); // NOLINT
414  _ReadWriteBarrier();
415  return result;
416 }
417 
418 static __inline int32_t nlib_atomic_fetch_xor32(int32_t* ptr, int32_t val,
419  int memorder) {
420  int32_t result;
421  (void)memorder;
422  _ReadWriteBarrier();
423  result = _InterlockedXor((volatile long*)ptr, val); // NOLINT
424  _ReadWriteBarrier();
425  return result;
426 }
427 
428 static __inline int32_t nlib_atomic_fetch_or32(int32_t* ptr, int32_t val,
429  int memorder) {
430  int32_t result;
431  (void)memorder;
432  _ReadWriteBarrier();
433  result = _InterlockedOr((volatile long*)ptr, val); // NOLINT
434  _ReadWriteBarrier();
435  return result;
436 }
437 
438 static __inline int64_t nlib_atomic_load64(const int64_t* ptr, int memorder) {
439  int64_t result;
440  _ReadWriteBarrier();
441  result = *ptr;
442  _ReadWriteBarrier();
443  (void)memorder;
444  // if (memorder & NLIB_ATOMIC_ACQUIRE)
445  // NLIB_MEMORY_ORDER_ACQUIRE;
446  return result;
447 }
448 
449 static __inline void nlib_atomic_store64(int64_t* ptr, int64_t val, int memorder) {
450  _ReadWriteBarrier();
451  if (memorder != NLIB_ATOMIC_SEQ_CST) {
452  // if (memorder & NLIB_ATOMIC_RELEASE)
453  // NLIB_MEMORY_ORDER_RELEASE;
454  *ptr = val;
455  } else {
456 #ifndef NLIB_64BIT
457  InterlockedExchange64((volatile long long*)ptr, val); // NOLINT
458 #else
459  _InterlockedExchange64((volatile long long*)ptr, val); // NOLINT
460 #endif
461  }
462  _ReadWriteBarrier();
463 }
464 
465 static __inline int64_t nlib_atomic_exchange64(int64_t* ptr, int64_t val,
466  int memorder) {
467  int64_t result;
468  (void)memorder;
469  _ReadWriteBarrier();
470 #ifndef NLIB_64BIT
471  result = (int64_t)InterlockedExchange64((volatile long long*)ptr, val); // NOLINT
472 #else
473  result = (int64_t)_InterlockedExchange64((volatile long long*)ptr, val); // NOLINT
474 #endif
475  _ReadWriteBarrier();
476  return result;
477 }
478 
479 static __inline void* nlib_atomic_exchangeptr(void** ptr, void* val, int memorder) {
480 #ifndef NLIB_64BIT
481  return (void*)nlib_atomic_exchange32((int32_t*)ptr, (int32_t)val, memorder); // NOLINT
482 #else
483  return (void*)nlib_atomic_exchange64((int64_t*)ptr, (int64_t)val, memorder); // NOLINT
484 #endif
485 }
486 
487 static __inline int nlib_atomic_compare_exchange64(int64_t* ptr, int64_t* expected,
488  int64_t desired, int weak,
489  int success_memorder, int failure_memorder) {
490  int64_t result;
491  _ReadWriteBarrier();
492 #ifndef NLIB_64BIT
493  result = InterlockedCompareExchange64((volatile long long*)ptr, desired, *expected); // NOLINT
494 #else
495  result = _InterlockedCompareExchange64((volatile long long*)ptr, desired, *expected); // NOLINT
496 #endif
497  _ReadWriteBarrier();
498  (void)weak;
499  (void)success_memorder;
500  (void)failure_memorder;
501  if (result == *expected) {
502  return 1;
503  } else {
504  *expected = result;
505  return 0;
506  }
507 }
508 
509 static __inline int64_t nlib_atomic_add_fetch64(int64_t* ptr, int64_t val,
510  int memorder) {
511  int64_t result;
512  (void)memorder;
513  _ReadWriteBarrier();
514 #ifndef NLIB_64BIT
515  result = InterlockedExchangeAdd64((volatile long long*)ptr, val) + val; // NOLINT
516 #else
517  result = _InterlockedExchangeAdd64((volatile long long*)ptr, val) + val; // NOLINT
518 #endif
519  _ReadWriteBarrier();
520  return result;
521 }
522 
523 static __inline int64_t nlib_atomic_sub_fetch64(int64_t* ptr, int64_t val,
524  int memorder) {
525  int64_t result;
526  (void)memorder;
527  _ReadWriteBarrier();
528 #ifndef NLIB_64BIT
529  result = InterlockedExchangeAdd64((volatile long long*)ptr, -val) - val; // NOLINT
530 #else
531  result = _InterlockedExchangeAdd64((volatile long long*)ptr, -val) - val; // NOLINT
532 #endif
533  _ReadWriteBarrier();
534  return result;
535 }
536 
537 static __inline int64_t nlib_atomic_and_fetch64(int64_t* ptr, int64_t val,
538  int memorder) {
539  int64_t result;
540  (void)memorder;
541  _ReadWriteBarrier();
542 #ifndef NLIB_64BIT
543  result = InterlockedAnd64((volatile long long*)ptr, val) & val; // NOLINT
544 #else
545  result = _InterlockedAnd64((volatile long long*)ptr, val) & val; // NOLINT
546 #endif
547  _ReadWriteBarrier();
548  return result;
549 }
550 
551 static __inline int64_t nlib_atomic_xor_fetch64(int64_t* ptr, int64_t val,
552  int memorder) {
553  int64_t result;
554  (void)memorder;
555  _ReadWriteBarrier();
556 #ifndef NLIB_64BIT
557  result = InterlockedXor64((volatile long long*)ptr, val) ^ val; // NOLINT
558 #else
559  result = _InterlockedXor64((volatile long long*)ptr, val) ^ val; // NOLINT
560 #endif
561  _ReadWriteBarrier();
562  return result;
563 }
564 
565 static __inline int64_t nlib_atomic_or_fetch64(int64_t* ptr, int64_t val,
566  int memorder) {
567  int64_t result;
568  (void)memorder;
569  _ReadWriteBarrier();
570 #ifndef NLIB_64BIT
571  result = InterlockedOr64((volatile long long*)ptr, val) | val; // NOLINT
572 #else
573  result = _InterlockedOr64((volatile long long*)ptr, val) | val; // NOLINT
574 #endif
575  _ReadWriteBarrier();
576  return result;
577 }
578 
579 static __inline int64_t nlib_atomic_fetch_add64(int64_t* ptr, int64_t val,
580  int memorder) {
581  int64_t result;
582  (void)memorder;
583  _ReadWriteBarrier();
584 #ifndef NLIB_64BIT
585  result = InterlockedExchangeAdd64((volatile long long*)ptr, val); // NOLINT
586 #else
587  result = _InterlockedExchangeAdd64((volatile long long*)ptr, val); // NOLINT
588 #endif
589  _ReadWriteBarrier();
590  return result;
591 }
592 
593 static __inline int64_t nlib_atomic_fetch_sub64(int64_t* ptr, int64_t val,
594  int memorder) {
595  int64_t result;
596  (void)memorder;
597  _ReadWriteBarrier();
598 #ifndef NLIB_64BIT
599  result = InterlockedExchangeAdd64((volatile long long*)ptr, -val); // NOLINT
600 #else
601  result = _InterlockedExchangeAdd64((volatile long long*)ptr, -val); // NOLINT
602 #endif
603  _ReadWriteBarrier();
604  return result;
605 }
606 
607 static __inline int64_t nlib_atomic_fetch_and64(int64_t* ptr, int64_t val,
608  int memorder) {
609  int64_t result;
610  (void)memorder;
611  _ReadWriteBarrier();
612 #ifndef NLIB_64BIT
613  result = InterlockedAnd64((volatile long long*)ptr, val); // NOLINT
614 #else
615  result = _InterlockedAnd64((volatile long long*)ptr, val); // NOLINT
616 #endif
617  _ReadWriteBarrier();
618  return result;
619 }
620 
621 static __inline int64_t nlib_atomic_fetch_xor64(int64_t* ptr, int64_t val,
622  int memorder) {
623  int64_t result;
624  (void)memorder;
625  _ReadWriteBarrier();
626 #ifndef NLIB_64BIT
627  result = InterlockedXor64((volatile long long*)ptr, val); // NOLINT
628 #else
629  result = _InterlockedXor64((volatile long long*)ptr, val); // NOLINT
630 #endif
631  _ReadWriteBarrier();
632  return result;
633 }
634 
635 static __inline int64_t nlib_atomic_fetch_or64(int64_t* ptr, int64_t val,
636  int memorder) {
637  int64_t result;
638  (void)memorder;
639  _ReadWriteBarrier();
640 #ifndef NLIB_64BIT
641  result = InterlockedOr64((volatile long long*)ptr, val); // NOLINT
642 #else
643  result = _InterlockedOr64((volatile long long*)ptr, val); // NOLINT
644 #endif
645  _ReadWriteBarrier();
646  return result;
647 }
648 
649 static __inline void* nlib_atomic_loadptr(void* const* ptr, int memorder) {
650  void* result;
651  _ReadWriteBarrier();
652  result = *ptr;
653  _ReadWriteBarrier();
654  (void)memorder;
655  // if (memorder & NLIB_ATOMIC_ACQUIRE)
656  // NLIB_MEMORY_ORDER_ACQUIRE;
657  return result;
658 }
659 
660 static __inline void nlib_atomic_storeptr(void** ptr, void* val, int memorder) {
661  _ReadWriteBarrier();
662  if (memorder != NLIB_ATOMIC_SEQ_CST) {
663  // if (memorder & NLIB_ATOMIC_RELEASE)
664  // NLIB_MEMORY_ORDER_RELEASE;
665  *ptr = val;
666  } else {
667 #if (_MSC_VER == 1800 && !defined(NLIB_64BIT))
668  InterlockedExchangePointer((void* volatile*)ptr, val); // NOLINT
669 #else
670  _InterlockedExchangePointer((void* volatile*)ptr, val); // NOLINT
671 #endif
672  }
673  _ReadWriteBarrier();
674 }
675 
676 static __inline int nlib_atomic_compare_exchangeptr(void** ptr, void** expected,
677  void* desired, int weak,
678  int success_memorder, int failure_memorder) {
679  void* result;
680  _ReadWriteBarrier();
681  result = _InterlockedCompareExchangePointer((void* volatile *)ptr, desired, *expected);
682  _ReadWriteBarrier();
683  (void)weak;
684  (void)success_memorder;
685  (void)failure_memorder;
686  if (result == *expected) {
687  return 1;
688  } else {
689  *expected = result;
690  return 0;
691  }
692 }
693 
694 static __inline void nlib_atomic_thread_fence(int memorder) {
695  switch (memorder) {
696  case NLIB_ATOMIC_RELAXED:
697  break;
698  case NLIB_ATOMIC_ACQUIRE:
700  break;
701  case NLIB_ATOMIC_RELEASE:
703  break;
704  default:
706  break;
707  }
708 }
709 #endif
710 
711 #ifdef __cplusplus
712 }
713 #endif
714 
715 #ifndef _WIN64
716 #define NLIB_ALTNAME(func1, func2) \
717  __pragma(comment(linker, "/alternatename:_" NLIB_STRINGIFY(func1) "=_" NLIB_STRINGIFY(func2)))
718 #else
719 #define NLIB_ALTNAME(func1, func2) \
720  __pragma(comment(linker, "/alternatename:" NLIB_STRINGIFY(func1) "=" NLIB_STRINGIFY(func2)))
721 #endif
722 
723 NLIB_ALTNAME(nlib_malloc, malloc)
724 NLIB_ALTNAME(nlib_free, free)
725 NLIB_ALTNAME(nlib_calloc, calloc)
726 NLIB_ALTNAME(nlib_realloc, realloc)
727 NLIB_ALTNAME(nlib_free_size, nlib_free_size_)
728 
729 #if defined(NLIB_SIMD)
730 # ifndef NLIB_LIBC_nlib_strlen
731 NLIB_ALTNAME(nlib_strlen, nlib_strlen_simd)
732 # endif
733 # ifndef NLIB_LIBC_nlib_strlen
734 NLIB_ALTNAME(nlib_strnlen, nlib_strnlen_simd)
735 # endif
736 NLIB_ALTNAME(nlib_utf16len_, nlib_utf16len_simd)
737 NLIB_ALTNAME(nlib_utf16nlen_, nlib_utf16nlen_simd)
738 NLIB_ALTNAME(nlib_utf32len_, nlib_utf32len_generic)
739 NLIB_ALTNAME(nlib_utf32nlen_, nlib_utf32nlen_generic)
740 NLIB_ALTNAME(nlib_utf16cplen_ex_, nlib_utf16cplen_ex_simd)
741 NLIB_ALTNAME(nlib_strchr, nlib_strchr_simd)
742 NLIB_ALTNAME(nlib_strrchr, strrchr)
743 NLIB_ALTNAME(nlib_strchr_mb, nlib_strchr_mb_simd)
744 NLIB_ALTNAME(nlib_memcmp, nlib_memcmp_simd)
745 NLIB_ALTNAME(nlib_memchr, nlib_memchr_simd)
746 NLIB_ALTNAME(nlib_memrchr, nlib_memrchr_simd)
747 NLIB_ALTNAME(nlib_memchr_not, nlib_memchr_not_simd)
748 NLIB_ALTNAME(nlib_memchr_range_not, nlib_memchr_range_not_simd)
749 NLIB_ALTNAME(nlib_memchr_lt, nlib_memchr_lt_simd)
750 NLIB_ALTNAME(nlib_memchr_gt, nlib_memchr_gt_simd)
751 NLIB_ALTNAME(nlib_memchr_mb, nlib_memchr_mb_simd)
752 NLIB_ALTNAME(nlib_skipws, nlib_skipws_simd)
753 NLIB_ALTNAME(nlib_swapendian_16, nlib_swapendian_16_simd)
754 NLIB_ALTNAME(nlib_swapendian_32, nlib_swapendian_32_simd)
755 NLIB_ALTNAME(nlib_swapendian_64, nlib_swapendian_64_simd)
756 #else
757 # ifndef NLIB_LIBC_nlib_strlen
758 NLIB_ALTNAME(nlib_strlen, nlib_strlen_generic)
759 # endif
760 # ifndef NLIB_LIBC_nlib_strlen
761 NLIB_ALTNAME(nlib_strnlen, nlib_strnlen_generic)
762 # endif
763 NLIB_ALTNAME(nlib_utf16len_, nlib_utf16len_generic)
764 NLIB_ALTNAME(nlib_utf16nlen_, nlib_utf16nlen_generic)
765 NLIB_ALTNAME(nlib_utf32len_, nlib_utf32len_generic)
766 NLIB_ALTNAME(nlib_utf32nlen_, nlib_utf32nlen_generic)
767 NLIB_ALTNAME(nlib_utf16cplen_ex_, nlib_utf16cplen_ex_generic)
768 NLIB_ALTNAME(nlib_strchr, nlib_strchr_generic)
769 NLIB_ALTNAME(nlib_strrchr, nlib_strrchr_generic)
770 NLIB_ALTNAME(nlib_strchr_mb, nlib_strchr_mb_generic)
771 NLIB_ALTNAME(nlib_memcmp, nlib_memcmp_generic)
772 NLIB_ALTNAME(nlib_memchr, nlib_memchr_generic)
773 NLIB_ALTNAME(nlib_memrchr, nlib_memrchr_generic)
774 NLIB_ALTNAME(nlib_memchr_not, nlib_memchr_not_generic)
775 NLIB_ALTNAME(nlib_memchr_range_not, nlib_memchr_range_not_generic)
776 NLIB_ALTNAME(nlib_memchr_lt, nlib_memchr_lt_generic)
777 NLIB_ALTNAME(nlib_memchr_gt, nlib_memchr_gt_generic)
778 NLIB_ALTNAME(nlib_memchr_mb, nlib_memchr_mb_generic)
779 NLIB_ALTNAME(nlib_skipws, nlib_skipws_generic)
780 NLIB_ALTNAME(nlib_swapendian_16, nlib_swapendian_16_generic)
781 NLIB_ALTNAME(nlib_swapendian_32, nlib_swapendian_32_generic)
782 NLIB_ALTNAME(nlib_swapendian_64, nlib_swapendian_64_generic)
783 #endif
784 
785 #endif
786 #endif // INCLUDE_NN_NLIB_PLATFORM_WIN32_H_
int32_t nlib_atomic_xor_fetch32(int32_t *ptr, int32_t val, int memorder)
アトミックな値の排他的論理和の計算を行います。動作はgccの__atomic_xor_fetch()に準じます。 ...
int64_t nlib_atomic_fetch_and64(int64_t *ptr, int64_t val, int memorder)
アトミックな値の論理積の計算を行います。動作はgccの__atomic_fetch_and()に準じます。 ...
const char * nlib_strrchr(const char *s, int c)
文字列の末尾から文字を検索します。
void * nlib_atomic_exchangeptr(void **ptr, void *val, int memorder)
アトミックに値を入れ替えます。動作はgccの__atomic_exchange_n()に準じます。
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()に準じます。
NLIB_CHECK_RESULT void * nlib_calloc(size_t nmemb, size_t size)
C標準関数のcalloc()を呼び出すweak関数です。nlibはこの関数を経由してcalloc()を呼び出します。 ...
int64_t nlib_atomic_fetch_add64(int64_t *ptr, int64_t val, int memorder)
アトミックな値の加算を行います。動作はgccの__atomic_fetch_add()に準じます。
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
sem_t nlib_semaphore
セマフォオブジェクトの型です。
#define NLIB_MEMORY_ORDER_ACQUIRE
メモリフェンスです。C++11ではatomic_thread_fence(memory_order_acquire)に一致します。 ...
size_t nlib_strnlen(const char *s, size_t maxsize)
N1078のstrnlen_sに相当する実装です。
int nlib_memcmp(const void *buf1, const void *buf2, size_t n)
buf1 とbuf2 を先頭からn バイト分unsigned charとして比較します。
#define NLIB_ATOMIC_RELEASE
gccの__ATOMIC_RELEASEやC++11のstd::memory_order_releaseに準じます。
const void * nlib_memchr_not(const void *s, int c, size_t n)
メモリ領域[s, s + n)の先頭からn バイトを検索して、バイトc でないポインタを返します。 ...
int32_t nlib_atomic_or_fetch32(int32_t *ptr, int32_t val, int memorder)
アトミックな値の論理和の計算を行います。動作はgccの__atomic_or_fetch()に準じます。 ...
const char * nlib_skipws(size_t *cnt_lf, const char **last_lf, const char *s, size_t n)
n 個の文字から成る文字列を探索して最初の空白でない文字へのポインタを返します。
int64_t nlib_atomic_fetch_sub64(int64_t *ptr, int64_t val, int memorder)
アトミックな値の減算を行います。動作はgccの__atomic_fetch_sub()に準じます。
void nlib_free_size(void *ptr, size_t size)
サイズを指定してメモリを解放します。デフォルトではnlib_free()を呼び出します。
int64_t nlib_atomic_and_fetch64(int64_t *ptr, int64_t val, int memorder)
アトミックな値の論理積の計算を行います。動作はgccの__atomic_and_fetch()に準じます。 ...
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()に準じます。 ...
#define NLIB_VIS_PUBLIC
関数やクラス等のシンボルをライブラリの外部に公開します。
Definition: Platform_unix.h:89
const char * nlib_strchr(const char *s, int c)
文字列の先頭から文字を検索します。
int64_t nlib_atomic_fetch_or64(int64_t *ptr, int64_t val, int memorder)
アトミックな値の論理和の計算を行います。動作はgccの__atomic_fetch_or()に準じます。 ...
const void * nlib_memchr(const void *s, int c, size_t n)
メモリ領域[s, s + n)の先頭からn バイトを検索して、バイトc があるポインタを返します。 ...
NLIB_CHECK_RESULT void * nlib_malloc(size_t size)
C標準関数のmalloc()を呼び出すweak関数です。nlibはこの関数を経由してmalloc()を呼び出します。 ...
#define NLIB_ATOMIC_ACQUIRE
gccの__ATOMIC_ACQUIREやC++11のstd::memory_order_acquireに準じます。
pthread_key_t nlib_tls
TLSスロットのIDを示す型です。
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()に準じます。
#define NLIB_MEMORY_ORDER_SEQ_CST
メモリフェンスです。C++11ではatomic_thread_fence(memory_order_seq_cst)に一致します。 ...
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()に準じます。
int32_t nlib_atomic_fetch_xor32(int32_t *ptr, int32_t val, int memorder)
アトミックな値の排他的論理和の計算を行います。動作はgccの__atomic_fetch_xor()に準じます。 ...
int32_t nlib_atomic_sub_fetch32(int32_t *ptr, int32_t val, int memorder)
アトミックな値の減算を行います。動作はgccの__atomic_sub_fetch()に準じます。
int32_t nlib_atomic_fetch_sub32(int32_t *ptr, int32_t val, int memorder)
アトミックな値の減算を行います。動作はgccの__atomic_fetch_sub()に準じます。
int32_t nlib_atomic_add_fetch32(int32_t *ptr, int32_t val, int memorder)
アトミックな値の加算を行います。動作はgccの__atomic_add_fetch()に準じます。
void nlib_atomic_storeptr(void **ptr, void *val, int memorder)
アトミックに値をストアします。動作はgccの__atomic_store_n()に準じます。
void nlib_atomic_thread_fence(int memorder)
指定されたメモリバリアを配置します。
int32_t nlib_atomic_fetch_and32(int32_t *ptr, int32_t val, int memorder)
アトミックな値の論理積の計算を行います。動作はgccの__atomic_fetch_and()に準じます。 ...
pthread_cond_t nlib_cond
条件変数オブジェクトの型です。
NLIB_CHECK_RESULT void * nlib_realloc(void *ptr, size_t size)
C標準関数のrealloc()を呼び出すweak関数です。nlibはこの関数を経由してrealloc()を呼び出します。 ...
errno_t nlib_swapendian_32(uint32_t *p, size_t count)
エンディアンを変換します。
#define NLIB_ATOMIC_RELAXED
gccの__ATOMIC_RELAXEDやC++11のstd::memory_order_relaxedに準じます。
size_t nlib_strlen(const char *s)
内部でstrlen()を呼び出します。独自の実装が動作する場合もあります。
pthread_mutex_t nlib_mutex
ミューテックス変数の型です。
const void * nlib_memchr_range_not(const void *s, const char *range, size_t n)
メモリ領域[s, s + n)の先頭からn バイトを検索して、最初のrange に含まない文字へのポインタを返します。 ...
int64_t nlib_atomic_xor_fetch64(int64_t *ptr, int64_t val, int memorder)
アトミックな値の排他的論理和の計算を行います。動作はgccの__atomic_xor_fetch()に準じます。 ...
#define NLIB_MEMORY_ORDER_RELEASE
メモリフェンスです。C++11ではatomic_thread_fence(memory_order_release)に一致します。 ...
int64_t nlib_atomic_add_fetch64(int64_t *ptr, int64_t val, int memorder)
アトミックな値の加算を行います。動作はgccの__atomic_add_fetch()に準じます。
errno_t nlib_swapendian_16(uint16_t *p, size_t count)
エンディアンを変換します。
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()に準じます。 ...
void nlib_atomic_store64(int64_t *ptr, int64_t val, int memorder)
アトミックに値をストアします。動作はgccの__atomic_store_n()に準じます。
void nlib_free(void *ptr)
C標準関数のfree()を呼び出すweak関数です。nlibはこの関数を経由してfree()を呼び出します。 ...
errno_t nlib_swapendian_64(uint64_t *p, size_t count)
エンディアンを変換します。
int64_t nlib_atomic_or_fetch64(int64_t *ptr, int64_t val, int memorder)
アトミックな値の論理和の計算を行います。動作はgccの__atomic_or_fetch()に準じます。 ...
#define NLIB_ATOMIC_SEQ_CST
gccの__ATOMIC_SEQ_CSTやC++11のstd::memory_order_seq_cstに準じます。
int32_t nlib_atomic_fetch_or32(int32_t *ptr, int32_t val, int memorder)
アトミックな値の論理和の計算を行います。動作はgccの__atomic_fetch_or()に準じます。 ...
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()に準じます。
void nlib_atomic_store32(int32_t *ptr, int32_t val, int memorder)
アトミックに値をストアします。動作はgccの__atomic_store_n()に準じます。
int32_t nlib_atomic_exchange32(int32_t *ptr, int32_t val, int memorder)
アトミックに値を入れ替えます。動作はgccの__atomic_exchange_n()に準じます。
pthread_t nlib_thread
スレッドを指し示す識別子
int64_t nlib_atomic_load64(const int64_t *ptr, int memorder)
アトミックに値をロードします。動作はgccの__atomic_load_n()に準じます。