nlib
Platform_win32.h
1 
2 #pragma once
3 #ifndef INCLUDE_NN_NLIB_PLATFORM_WIN32_H_
4 #define INCLUDE_NN_NLIB_PLATFORM_WIN32_H_
5 #ifndef INCLUDE_NN_NLIB_PLATFORM_H_
6 # error do not include directly
7 #endif
8 
9 #if defined(_MSC_VER)
10 
11 #if !defined(_M_IX86) && !defined(_M_X64)
12 #error Sorry, not supported
13 #endif
14 
15 #if _MSC_VER < 1700
16 # error Use Visual Studio 2012 or later
17 #endif
18 
19 #ifndef WIN32_LEAN_AND_MEAN
20 # pragma message(__FILE__ ": WIN32_LEAN_AND_MEAN not defined, compile may fail")
21 # define WIN32_LEAN_AND_MEAN
22 #endif
23 
24 #ifndef NOMINMAX
25 # pragma message(__FILE__ ": NOMINMAX not defined, compile may fail")
26 # define NOMINMAX
27 #endif
28 
29 #ifndef _USE_MATH_DEFINES
30 # pragma message(__FILE__ ": _USE_MATH_DEFINES not defined, compile may fail")
31 # define _USE_MATH_DEFINES
32 #endif
33 
34 #ifdef _WIN64
35 # define NLIB_64BIT
36 #endif
37 
38 #include <intrin.h>
39 
40 #pragma intrinsic(_BitScanReverse)
41 #pragma intrinsic(_BitScanForward)
42 #ifdef NLIB_64BIT
43 # pragma intrinsic(_BitScanReverse64)
44 # pragma intrinsic(_BitScanForward64)
45 #endif
46 
47 #include <stdlib.h> // for malloc, free, calloc, realloc
48 #include <limits.h> // for RSIZE_MAX
49 #include <WinSock2.h>
50 #include <Windows.h> // for HANDLE, CONDITION_VARIABLE, ....
51 #include <fcntl.h> // for O_RDONLY, O_RDWR, O_CREAT, ....
52 
53 #include <in6addr.h>
54 #include <ws2ipdef.h>
55 #include <sal.h>
56 
57 #if _MSC_VER == 1800 && WINVER < 0x0603
58 # pragma message(__FILE__ ": Please update your Windows SDK")
59 #endif
60 
61 #if _MSC_VER == 1700 && WINVER < 0x0602
62 # pragma message(__FILE__ ": Please update your Windows SDK")
63 #endif
64 
65 #if (!defined(_M_IX86_FP) || _M_IX86_FP < 2) && !defined(_M_X64) && !defined(_M_AMD64)
66 # error /arch:SSE2 or higher must be set
67 #endif
68 
69 #ifndef NLIB_SSE41
70 # define NLIB_SSE41
71 #endif
72 
73 #ifndef NLIB_SSE42
74 # define NLIB_SSE42
75 #endif
76 
77 #define NLIB_HAS_STDHEADER_STDINT
78 #include <stdint.h>
79 #if (_MSC_VER >= 1800)
80 # define NLIB_HAS_STDHEADER_INTTYPES
81 # include <inttypes.h>
82 #endif
83 #if (_MSC_VER < 1900)
84 # ifndef __func__
85 # define __func__ __FUNCTION__
86 # endif
87 #endif
88 
89 #ifndef NLIB_HAS_STDHEADER_INTTYPES
90 # include "nn/nlib/IntTypes.h"
91 #endif
92 
93 #ifdef __cplusplus
94 extern "C" {
95 #endif
96 
97 #ifndef va_copy
98 # define va_copy(dest, src) (dest = src)
99 #endif
100 #define NLIB_ALWAYS_INLINE __forceinline
101 #define NLIB_NEVER_INLINE __declspec(noinline)
102 #define NLIB_LIKELY(x) (x)
103 #define NLIB_UNLIKELY(x) (x)
104 #define NLIB_EXPECT(var, exp_value) (var)
105 #define NLIB_CHECK_RESULT
106 #define NLIB_NORETURN
107 #define NLIB_NONNULL
108 #define NLIB_NONNULL_1
109 #define NLIB_NONNULL_2
110 #define NLIB_NONNULL_3
111 #define NLIB_NONNULL_4
112 #define NLIB_NONNULL_5
113 #define NLIB_ATTRIBUTE_MALLOC
114 #define NLIB_ATTRIBUTE_PURE
115 #define NLIB_ATTRIBUTE_CONST
116 #define NLIB_ATTRIBUTE_ALLOC_SIZE1(n)
117 #define NLIB_ATTRIBUTE_ALLOC_SIZE2(n0, n1)
118 #define NLIB_ATTRIBUTE_ALLOC_ALIGN(algn)
119 #define NLIB_ATTRIBUTE_ASSUME_ALIGNED(n)
120 #ifndef NLIB_DEPRECATED
121 #define NLIB_DEPRECATED __declspec(deprecated)
122 #endif
123 #ifndef NLIB_DEPRECATED_MSG
124 #define NLIB_DEPRECATED_MSG(msg) __declspec(deprecated(msg))
125 #endif
126 #define NLIB_WEAKSYMBOL
127 #define NLIB_VIS_HIDDEN
128 #ifdef NLIB_WINDLL
129 # define NLIB_EXPIMP_TEMPLATE_(x) template class NLIB_VIS_PUBLIC x
130 # define NLIB_WINEXPORT __declspec(dllexport)
131 # define NLIB_WINIMPORT __declspec(dllimport)
132 # define NLIB_VIS_PUBLIC NLIB_WINIMPORT
133 # define NLIB_EXPIMP_TEMPLATE(x) extern NLIB_EXPIMP_TEMPLATE_(x)
134 #else
135 # define NLIB_VIS_PUBLIC
136 # define NLIB_EXPIMP_TEMPLATE(x)
137 #endif
138 
139 #if defined(n_EXPORTS)
140 # undef NLIB_VIS_PUBLIC
141 # define NLIB_VIS_PUBLIC NLIB_WINEXPORT
142 #elif defined(nx_misc_EXPORTS)
143 # undef NLIB_EXPIMP_TEMPLATE
144 # define NLIB_EXPIMP_TEMPLATE(x) NLIB_EXPIMP_TEMPLATE_(x)
145 #endif
146 
147 #define NLIB_VIS_PUBLIC_ALT
148 
149 #define NLIB_LITTLE_ENDIAN
150 
151 // NOTE:
152 // _WriteBarrier() for the compiler, _mm_sfence() for the processor, ...
153 // NOTE:
154 // You have to comment out error lines in intrin.h if you use VC++2005.
155 // See:
156 // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=262047
157 // http://www.hydrogenaudio.org/forums/index.php?showtopic=50972
158 #define NLIB_MEMORY_ORDER_RELEASE \
159  __pragma(warning(push)) \
160  __pragma(warning(disable:4127)) \
161  do { _WriteBarrier(); _mm_sfence(); } while (0) \
162  __pragma(warning(pop))
163 #define NLIB_MEMORY_ORDER_ACQUIRE \
164  __pragma(warning(push)) \
165  __pragma(warning(disable:4127)) \
166  do { _ReadBarrier(); _mm_lfence(); } while (0) \
167  __pragma(warning(pop))
168 #define NLIB_MEMORY_ORDER_ACQ_REL \
169  __pragma(warning(push)) \
170  __pragma(warning(disable:4127)) \
171  do { _ReadWriteBarrier(); _mm_mfence(); } while (0) \
172  __pragma(warning(pop))
173 #define NLIB_MEMORY_ORDER_SEQ_CST NLIB_MEMORY_ORDER_ACQ_REL
174 
175 // because "%zu" not supported ...
176 #ifdef NLIB_64BIT
177 # define __PRIS_PREFIX "ll"
178 #else
179 # define __PRIS_PREFIX
180 #endif
181 #define NLIB_WARN__(x) #x
182 #define NLIB_WARN_(x) NLIB_WARN__(x)
183 #define NLIB_WARN(exp) (__FILE__ "(" NLIB_WARN_(__LINE__) ") : WARNING: " exp)
184 
185 typedef unsigned int nlib_tls;
186 
187 #if _MSC_VER >= 1900
188 #define NLIB_TIMESPEC_HAS_NATIVE
189 #endif
190 
191 #pragma pack(push, 8)
192 typedef struct nlib_mutex_ {
193  int32_t mark;
194  uint32_t cat;
195  union {
196  HANDLE h;
197  CRITICAL_SECTION cs;
198  } data;
199 } nlib_mutex;
200 #pragma pack(pop)
201 #define NLIB_MUTEX_INITIALIZER { 0x6768696AU, 0 }
202 #define NLIB_RECURSIVE_MUTEX_INITIALIZER { 0x6768696AU, 1 }
203 #define NLIB_RECURSIVE_TIMED_MUTEX_INITIALIZER { 0x6768696AU, 2 }
204 
205 typedef HANDLE nlib_semaphore;
206 
207 typedef struct nlib_cond_ {
208  CONDITION_VARIABLE cond;
209  nlib_mutex mutex;
210 } nlib_cond;
211 #define NLIB_COND_INITIALIZER { 0, NLIB_MUTEX_INITIALIZER }
212 
213 typedef HANDLE nlib_thread;
214 
215 #define NLIB_ATTRIBUTE_PRINTF(x, y)
216 
217 #define NLIB_ASSUME(cond) __assume(cond)
218 
219 #define NLIB_RWLOCK_HAS_NATIVE
220 #ifdef NLIB_RWLOCK_HAS_NATIVE
221 typedef SRWLOCK nlib_rwlock;
222 #define NLIB_RWLOCK_INITIALIZER SRWLOCK_INIT
223 #endif
224 
225 NLIB_VIS_PUBLIC void nlib_free_size_(void* ptr, size_t size);
226 
227 #define NLIB_LIBC_nlib_memcmp
228 #define NLIB_LIBC_nlib_strlen
229 #define NLIB_LIBC_nlib_strnlen
230 #define NLIB_LIBC_nlib_wcslen
231 #define NLIB_LIBC_nlib_wcsnlen
232 #define NLIB_LIBC_nlib_strcpy
233 #define NLIB_LIBC_nlib_strncpy
234 #define NLIB_LIBC_nlib_wcscpy
235 #define NLIB_LIBC_nlib_wcsncpy
236 #define NLIB_LIBC_nlib_strchr
237 #define NLIB_LIBC_nlib_strrchr
238 
239 #if !defined(__INTELLISENSE__)
240 #define NLIB_ATOMIC_RELAXED (0)
241 #define NLIB_ATOMIC_ACQUIRE (1)
242 #define NLIB_ATOMIC_RELEASE (2)
243 #define NLIB_ATOMIC_ACQ_REL (3)
244 #define NLIB_ATOMIC_SEQ_CST (7)
245 
246 //
247 // NOTE:
248 // Windows 8 has xxxNoFence version
249 //
250 
251 static __inline int32_t nlib_atomic_load32(const int32_t* ptr, int memorder) {
252  int32_t result;
253  _ReadWriteBarrier();
254  result = *ptr;
255  (void)memorder;
256  // if (memorder & NLIB_ATOMIC_ACQUIRE)
257  // NLIB_MEMORY_ORDER_ACQUIRE;
258  _ReadWriteBarrier();
259  return result;
260 }
261 
262 static __inline void nlib_atomic_store32(int32_t* ptr, int32_t val, int memorder) {
263  _ReadWriteBarrier();
264  if (memorder != NLIB_ATOMIC_SEQ_CST) {
265  // if (memorder & NLIB_ATOMIC_RELEASE)
266  // NLIB_MEMORY_ORDER_RELEASE;
267  *ptr = val;
268  } else {
269  _InterlockedExchange((volatile long*)ptr, val); // NOLINT
270  }
271  _ReadWriteBarrier();
272 }
273 
274 static __inline int32_t nlib_atomic_exchange32(int32_t* ptr, int32_t val,
275  int memorder) {
276  int32_t result;
277  (void)memorder;
278  _ReadWriteBarrier();
279  result = (int32_t)_InterlockedExchange((volatile long*)ptr, val); // NOLINT
280  _ReadWriteBarrier();
281  return result;
282 }
283 
284 static __inline int nlib_atomic_compare_exchange32(int32_t* ptr, int32_t* expected,
285  int32_t desired, int weak,
286  int success_memorder, int failure_memorder) {
287  int32_t result;
288  _ReadWriteBarrier();
289  result = _InterlockedCompareExchange((volatile long*)ptr, desired, *expected); // NOLINT
290  _ReadWriteBarrier();
291  (void)weak;
292  (void)success_memorder;
293  (void)failure_memorder;
294  if (result == *expected) {
295  return 1;
296  } else {
297  *expected = result;
298  return 0;
299  }
300 }
301 
302 static __inline int32_t nlib_atomic_add_fetch32(int32_t* ptr, int32_t val,
303  int memorder) {
304  int32_t result;
305  (void)memorder;
306  _ReadWriteBarrier();
307  result = _InterlockedExchangeAdd((volatile long*)ptr, val) + val; // NOLINT
308  _ReadWriteBarrier();
309  return result;
310 }
311 
312 static __inline int32_t nlib_atomic_sub_fetch32(int32_t* ptr, int32_t val,
313  int memorder) {
314  int32_t result;
315  (void)memorder;
316  _ReadWriteBarrier();
317  result = _InterlockedExchangeAdd((volatile long*)ptr, -val) - val; // NOLINT
318  _ReadWriteBarrier();
319  return result;
320 }
321 
322 static __inline int32_t nlib_atomic_and_fetch32(int32_t* ptr, int32_t val,
323  int memorder) {
324  int32_t result;
325  (void)memorder;
326  _ReadWriteBarrier();
327  result = _InterlockedAnd((volatile long*)ptr, val) & val; // NOLINT
328  _ReadWriteBarrier();
329  return result;
330 }
331 
332 static __inline int32_t nlib_atomic_xor_fetch32(int32_t* ptr, int32_t val,
333  int memorder) {
334  int32_t result;
335  (void)memorder;
336  _ReadWriteBarrier();
337  result = _InterlockedXor((volatile long*)ptr, val) ^ val; // NOLINT
338  _ReadWriteBarrier();
339  return result;
340 }
341 
342 static __inline int32_t nlib_atomic_or_fetch32(int32_t* ptr, int32_t val,
343  int memorder) {
344  int32_t result;
345  (void)memorder;
346  _ReadWriteBarrier();
347  result = _InterlockedOr((volatile long*)ptr, val) | val; // NOLINT
348  _ReadWriteBarrier();
349  return result;
350 }
351 
352 static __inline int32_t nlib_atomic_fetch_add32(int32_t* ptr, int32_t val,
353  int memorder) {
354  int32_t result;
355  (void)memorder;
356  _ReadWriteBarrier();
357  result = _InterlockedExchangeAdd((volatile long*)ptr, val); // NOLINT
358  _ReadWriteBarrier();
359  return result;
360 }
361 
362 static __inline int32_t nlib_atomic_fetch_sub32(int32_t* ptr, int32_t val,
363  int memorder) {
364  int32_t result;
365  (void)memorder;
366  _ReadWriteBarrier();
367  result = _InterlockedExchangeAdd((volatile long*)ptr, -val); // NOLINT
368  _ReadWriteBarrier();
369  return result;
370 }
371 
372 static __inline int32_t nlib_atomic_fetch_and32(int32_t* ptr, int32_t val,
373  int memorder) {
374  int32_t result;
375  (void)memorder;
376  _ReadWriteBarrier();
377  result = _InterlockedAnd((volatile long*)ptr, val); // NOLINT
378  _ReadWriteBarrier();
379  return result;
380 }
381 
382 static __inline int32_t nlib_atomic_fetch_xor32(int32_t* ptr, int32_t val,
383  int memorder) {
384  int32_t result;
385  (void)memorder;
386  _ReadWriteBarrier();
387  result = _InterlockedXor((volatile long*)ptr, val); // NOLINT
388  _ReadWriteBarrier();
389  return result;
390 }
391 
392 static __inline int32_t nlib_atomic_fetch_or32(int32_t* ptr, int32_t val,
393  int memorder) {
394  int32_t result;
395  (void)memorder;
396  _ReadWriteBarrier();
397  result = _InterlockedOr((volatile long*)ptr, val); // NOLINT
398  _ReadWriteBarrier();
399  return result;
400 }
401 
402 static __inline int64_t nlib_atomic_load64(const int64_t* ptr, int memorder) {
403  int64_t result;
404  _ReadWriteBarrier();
405  result = *ptr;
406  _ReadWriteBarrier();
407  (void)memorder;
408  // if (memorder & NLIB_ATOMIC_ACQUIRE)
409  // NLIB_MEMORY_ORDER_ACQUIRE;
410  return result;
411 }
412 
413 static __inline void nlib_atomic_store64(int64_t* ptr, int64_t val, int memorder) {
414  _ReadWriteBarrier();
415  if (memorder != NLIB_ATOMIC_SEQ_CST) {
416  // if (memorder & NLIB_ATOMIC_RELEASE)
417  // NLIB_MEMORY_ORDER_RELEASE;
418  *ptr = val;
419  } else {
420 #ifndef NLIB_64BIT
421  InterlockedExchange64((volatile long long*)ptr, val); // NOLINT
422 #else
423  _InterlockedExchange64((volatile long long*)ptr, val); // NOLINT
424 #endif
425  }
426  _ReadWriteBarrier();
427 }
428 
429 static __inline int64_t nlib_atomic_exchange64(int64_t* ptr, int64_t val,
430  int memorder) {
431  int64_t result;
432  (void)memorder;
433  _ReadWriteBarrier();
434 #ifndef NLIB_64BIT
435  result = (int64_t)InterlockedExchange64((volatile long long*)ptr, val); // NOLINT
436 #else
437  result = (int64_t)_InterlockedExchange64((volatile long long*)ptr, val); // NOLINT
438 #endif
439  _ReadWriteBarrier();
440  return result;
441 }
442 
443 static __inline int nlib_atomic_compare_exchange64(int64_t* ptr, int64_t* expected,
444  int64_t desired, int weak,
445  int success_memorder, int failure_memorder) {
446  int64_t result;
447  _ReadWriteBarrier();
448 #ifndef NLIB_64BIT
449  result = InterlockedCompareExchange64((volatile long long*)ptr, desired, *expected); // NOLINT
450 #else
451  result = _InterlockedCompareExchange64((volatile long long*)ptr, desired, *expected); // NOLINT
452 #endif
453  _ReadWriteBarrier();
454  (void)weak;
455  (void)success_memorder;
456  (void)failure_memorder;
457  if (result == *expected) {
458  return 1;
459  } else {
460  *expected = result;
461  return 0;
462  }
463 }
464 
465 static __inline int64_t nlib_atomic_add_fetch64(int64_t* ptr, int64_t val,
466  int memorder) {
467  int64_t result;
468  (void)memorder;
469  _ReadWriteBarrier();
470 #ifndef NLIB_64BIT
471  result = InterlockedExchangeAdd64((volatile long long*)ptr, val) + val; // NOLINT
472 #else
473  result = _InterlockedExchangeAdd64((volatile long long*)ptr, val) + val; // NOLINT
474 #endif
475  _ReadWriteBarrier();
476  return result;
477 }
478 
479 static __inline int64_t nlib_atomic_sub_fetch64(int64_t* ptr, int64_t val,
480  int memorder) {
481  int64_t result;
482  (void)memorder;
483  _ReadWriteBarrier();
484 #ifndef NLIB_64BIT
485  result = InterlockedExchangeAdd64((volatile long long*)ptr, -val) - val; // NOLINT
486 #else
487  result = _InterlockedExchangeAdd64((volatile long long*)ptr, -val) - val; // NOLINT
488 #endif
489  _ReadWriteBarrier();
490  return result;
491 }
492 
493 static __inline int64_t nlib_atomic_and_fetch64(int64_t* ptr, int64_t val,
494  int memorder) {
495  int64_t result;
496  (void)memorder;
497  _ReadWriteBarrier();
498 #ifndef NLIB_64BIT
499  result = InterlockedAnd64((volatile long long*)ptr, val) & val; // NOLINT
500 #else
501  result = _InterlockedAnd64((volatile long long*)ptr, val) & val; // NOLINT
502 #endif
503  _ReadWriteBarrier();
504  return result;
505 }
506 
507 static __inline int64_t nlib_atomic_xor_fetch64(int64_t* ptr, int64_t val,
508  int memorder) {
509  int64_t result;
510  (void)memorder;
511  _ReadWriteBarrier();
512 #ifndef NLIB_64BIT
513  result = InterlockedXor64((volatile long long*)ptr, val) ^ val; // NOLINT
514 #else
515  result = _InterlockedXor64((volatile long long*)ptr, val) ^ val; // NOLINT
516 #endif
517  _ReadWriteBarrier();
518  return result;
519 }
520 
521 static __inline int64_t nlib_atomic_or_fetch64(int64_t* ptr, int64_t val,
522  int memorder) {
523  int64_t result;
524  (void)memorder;
525  _ReadWriteBarrier();
526 #ifndef NLIB_64BIT
527  result = InterlockedOr64((volatile long long*)ptr, val) | val; // NOLINT
528 #else
529  result = _InterlockedOr64((volatile long long*)ptr, val) | val; // NOLINT
530 #endif
531  _ReadWriteBarrier();
532  return result;
533 }
534 
535 static __inline int64_t nlib_atomic_fetch_add64(int64_t* ptr, int64_t val,
536  int memorder) {
537  int64_t result;
538  (void)memorder;
539  _ReadWriteBarrier();
540 #ifndef NLIB_64BIT
541  result = InterlockedExchangeAdd64((volatile long long*)ptr, val); // NOLINT
542 #else
543  result = _InterlockedExchangeAdd64((volatile long long*)ptr, val); // NOLINT
544 #endif
545  _ReadWriteBarrier();
546  return result;
547 }
548 
549 static __inline int64_t nlib_atomic_fetch_sub64(int64_t* ptr, int64_t val,
550  int memorder) {
551  int64_t result;
552  (void)memorder;
553  _ReadWriteBarrier();
554 #ifndef NLIB_64BIT
555  result = InterlockedExchangeAdd64((volatile long long*)ptr, -val); // NOLINT
556 #else
557  result = _InterlockedExchangeAdd64((volatile long long*)ptr, -val); // NOLINT
558 #endif
559  _ReadWriteBarrier();
560  return result;
561 }
562 
563 static __inline int64_t nlib_atomic_fetch_and64(int64_t* ptr, int64_t val,
564  int memorder) {
565  int64_t result;
566  (void)memorder;
567  _ReadWriteBarrier();
568 #ifndef NLIB_64BIT
569  result = InterlockedAnd64((volatile long long*)ptr, val); // NOLINT
570 #else
571  result = _InterlockedAnd64((volatile long long*)ptr, val); // NOLINT
572 #endif
573  _ReadWriteBarrier();
574  return result;
575 }
576 
577 static __inline int64_t nlib_atomic_fetch_xor64(int64_t* ptr, int64_t val,
578  int memorder) {
579  int64_t result;
580  (void)memorder;
581  _ReadWriteBarrier();
582 #ifndef NLIB_64BIT
583  result = InterlockedXor64((volatile long long*)ptr, val); // NOLINT
584 #else
585  result = _InterlockedXor64((volatile long long*)ptr, val); // NOLINT
586 #endif
587  _ReadWriteBarrier();
588  return result;
589 }
590 
591 static __inline int64_t nlib_atomic_fetch_or64(int64_t* ptr, int64_t val,
592  int memorder) {
593  int64_t result;
594  (void)memorder;
595  _ReadWriteBarrier();
596 #ifndef NLIB_64BIT
597  result = InterlockedOr64((volatile long long*)ptr, val); // NOLINT
598 #else
599  result = _InterlockedOr64((volatile long long*)ptr, val); // NOLINT
600 #endif
601  _ReadWriteBarrier();
602  return result;
603 }
604 
605 static __inline void* nlib_atomic_loadptr(void* const* ptr, int memorder) {
606  void* result;
607  _ReadWriteBarrier();
608  result = *ptr;
609  _ReadWriteBarrier();
610  (void)memorder;
611  // if (memorder & NLIB_ATOMIC_ACQUIRE)
612  // NLIB_MEMORY_ORDER_ACQUIRE;
613  return result;
614 }
615 
616 static __inline void nlib_atomic_storeptr(void** ptr, void* val, int memorder) {
617  _ReadWriteBarrier();
618  if (memorder != NLIB_ATOMIC_SEQ_CST) {
619  // if (memorder & NLIB_ATOMIC_RELEASE)
620  // NLIB_MEMORY_ORDER_RELEASE;
621  *ptr = val;
622  } else {
623 #if _MSC_VER < 1800 || (_MSC_VER == 1800 && !defined(NLIB_64BIT))
624  InterlockedExchangePointer((void* volatile*)ptr, val); // NOLINT
625 #else
626  _InterlockedExchangePointer((void* volatile*)ptr, val); // NOLINT
627 #endif
628  }
629  _ReadWriteBarrier();
630 }
631 
632 static __inline int nlib_atomic_compare_exchangeptr(void** ptr, void** expected,
633  void* desired, int weak,
634  int success_memorder, int failure_memorder) {
635  void* result;
636  _ReadWriteBarrier();
637 #if _MSC_VER < 1800
638  result = InterlockedCompareExchangePointer((void* volatile *)ptr, desired, *expected);
639 #else
640  result = _InterlockedCompareExchangePointer((void* volatile *)ptr, desired, *expected);
641 #endif
642  _ReadWriteBarrier();
643  (void)weak;
644  (void)success_memorder;
645  (void)failure_memorder;
646  if (result == *expected) {
647  return 1;
648  } else {
649  *expected = result;
650  return 0;
651  }
652 }
653 
654 static __inline void nlib_atomic_thread_fence(int memorder) {
655  switch (memorder) {
656  case NLIB_ATOMIC_RELAXED:
657  break;
658  case NLIB_ATOMIC_ACQUIRE:
660  break;
661  case NLIB_ATOMIC_RELEASE:
663  break;
664  default:
666  break;
667  }
668 }
669 #endif
670 
671 #ifdef __cplusplus
672 }
673 #endif
674 
675 #ifndef _WIN64
676 # pragma comment(linker, "/alternatename:_nlib_malloc=_malloc")
677 # pragma comment(linker, "/alternatename:_nlib_free=_free")
678 # pragma comment(linker, "/alternatename:_nlib_calloc=_calloc")
679 # pragma comment(linker, "/alternatename:_nlib_realloc=_realloc")
680 # pragma comment(linker, "/alternatename:_nlib_free_size=_nlib_free_size_")
681 #else
682 # pragma comment(linker, "/alternatename:nlib_malloc=malloc")
683 # pragma comment(linker, "/alternatename:nlib_free=free")
684 # pragma comment(linker, "/alternatename:nlib_calloc=calloc")
685 # pragma comment(linker, "/alternatename:nlib_realloc=realloc")
686 # pragma comment(linker, "/alternatename:nlib_free_size=nlib_free_size_")
687 #endif
688 
689 #if defined(NLIB_SIMD)
690 # ifndef _WIN64
691 # ifndef NLIB_LIBC_nlib_strlen
692 # pragma comment(linker, "/alternatename:_nlib_strlen=_nlib_strlen_simd")
693 # endif
694 # ifndef NLIB_LIBC_nlib_strlen
695 # pragma comment(linker, "/alternatename:_nlib_strnlen=_nlib_strnlen_simd")
696 # endif
697 # pragma comment(linker, "/alternatename:_nlib_utf16len_=_nlib_utf16len_simd")
698 # pragma comment(linker, "/alternatename:_nlib_utf16nlen_=_nlib_utf16nlen_simd")
699 # pragma comment(linker, "/alternatename:_nlib_utf32len_=_nlib_utf32len_generic")
700 # pragma comment(linker, "/alternatename:_nlib_utf32nlen_=_nlib_utf32nlen_generic")
701 # pragma comment(linker, "/alternatename:_nlib_utf16cplen_ex_=_nlib_utf16cplen_ex_simd")
702 # pragma comment(linker, "/alternatename:_nlib_strchr=_nlib_strchr_simd")
703 # pragma comment(linker, "/alternatename:_nlib_strrchr=_strrchr")
704 # pragma comment(linker, "/alternatename:_nlib_strchr_mb=_nlib_strchr_mb_simd")
705 # pragma comment(linker, "/alternatename:_nlib_memcmp=_nlib_memcmp_simd")
706 # pragma comment(linker, "/alternatename:_nlib_memchr=_nlib_memchr_simd")
707 # pragma comment(linker, "/alternatename:_nlib_memrchr=_nlib_memrchr_simd")
708 # pragma comment(linker, "/alternatename:_nlib_memchr_not=_nlib_memchr_not_simd")
709 # pragma comment(linker, "/alternatename:_nlib_memchr_range_not=_nlib_memchr_range_not_simd")
710 # pragma comment(linker, "/alternatename:_nlib_memchr_lt=_nlib_memchr_lt_simd")
711 # pragma comment(linker, "/alternatename:_nlib_memchr_gt=_nlib_memchr_gt_simd")
712 # pragma comment(linker, "/alternatename:_nlib_memchr_mb=_nlib_memchr_mb_simd")
713 # pragma comment(linker, "/alternatename:_nlib_skipws=_nlib_skipws_simd")
714 # pragma comment(linker, "/alternatename:_nlib_swapendian_16=_nlib_swapendian_16_simd")
715 # pragma comment(linker, "/alternatename:_nlib_swapendian_32=_nlib_swapendian_32_simd")
716 # pragma comment(linker, "/alternatename:_nlib_swapendian_64=_nlib_swapendian_64_simd")
717 # pragma comment(linker, "/alternatename:_nlib_strcplen_ex=_nlib_strcplen_ex")
718 # pragma comment(linker, "/alternatename:_nlib_popcnt=_nlib_popcnt_simd")
719 # pragma comment(linker, "/alternatename:_nlib_popcnt64=_nlib_popcnt64_simd")
720 # else
721 # ifndef NLIB_LIBC_nlib_strlen
722 # pragma comment(linker, "/alternatename:nlib_strlen=nlib_strlen_simd")
723 # endif
724 # ifndef NLIB_LIBC_nlib_strlen
725 # pragma comment(linker, "/alternatename:nlib_strnlen=nlib_strnlen_simd")
726 # endif
727 # pragma comment(linker, "/alternatename:nlib_utf16len_=nlib_utf16len_simd")
728 # pragma comment(linker, "/alternatename:nlib_utf16nlen_=nlib_utf16nlen_simd")
729 # pragma comment(linker, "/alternatename:nlib_utf32len_=nlib_utf32len_generic")
730 # pragma comment(linker, "/alternatename:nlib_utf32nlen_=nlib_utf32nlen_generic")
731 # pragma comment(linker, "/alternatename:nlib_utf16cplen_ex_=nlib_utf16cplen_ex_simd")
732 # pragma comment(linker, "/alternatename:nlib_strchr=nlib_strchr_simd")
733 # pragma comment(linker, "/alternatename:nlib_strrchr=strrchr")
734 # pragma comment(linker, "/alternatename:nlib_strchr_mb=nlib_strchr_mb_simd")
735 # pragma comment(linker, "/alternatename:nlib_memcmp=nlib_memcmp_simd")
736 # pragma comment(linker, "/alternatename:nlib_memchr=nlib_memchr_simd")
737 # pragma comment(linker, "/alternatename:nlib_memrchr=nlib_memrchr_simd")
738 # pragma comment(linker, "/alternatename:nlib_memchr_not=nlib_memchr_not_simd")
739 # pragma comment(linker, "/alternatename:nlib_memchr_range_not=nlib_memchr_range_not_simd")
740 # pragma comment(linker, "/alternatename:nlib_memchr_lt=nlib_memchr_lt_simd")
741 # pragma comment(linker, "/alternatename:nlib_memchr_gt=nlib_memchr_gt_simd")
742 # pragma comment(linker, "/alternatename:nlib_memchr_mb=nlib_memchr_mb_simd")
743 # pragma comment(linker, "/alternatename:nlib_skipws=nlib_skipws_simd")
744 # pragma comment(linker, "/alternatename:nlib_swapendian_16=nlib_swapendian_16_simd")
745 # pragma comment(linker, "/alternatename:nlib_swapendian_32=nlib_swapendian_32_simd")
746 # pragma comment(linker, "/alternatename:nlib_swapendian_64=nlib_swapendian_64_simd")
747 # pragma comment(linker, "/alternatename:nlib_strcplen_ex=nlib_strcplen_ex")
748 # pragma comment(linker, "/alternatename:nlib_popcnt=nlib_popcnt_simd")
749 # pragma comment(linker, "/alternatename:nlib_popcnt64=nlib_popcnt64_simd")
750 # endif
751 #else
752 # ifndef _WIN64
753 # ifndef NLIB_LIBC_nlib_strlen
754 # pragma comment(linker, "/alternatename:_nlib_strlen=_nlib_strlen_generic")
755 # endif
756 # ifndef NLIB_LIBC_nlib_strlen
757 # pragma comment(linker, "/alternatename:_nlib_strnlen=_nlib_strnlen_generic")
758 # endif
759 # pragma comment(linker, "/alternatename:_nlib_utf16len_=_nlib_utf16len_generic")
760 # pragma comment(linker, "/alternatename:_nlib_utf16nlen_=_nlib_utf16nlen_generic")
761 # pragma comment(linker, "/alternatename:_nlib_utf32len_=_nlib_utf32len_generic")
762 # pragma comment(linker, "/alternatename:_nlib_utf32nlen_=_nlib_utf32nlen_generic")
763 # pragma comment(linker, "/alternatename:_nlib_utf16cplen_ex_=_nlib_utf16cplen_ex_generic")
764 # pragma comment(linker, "/alternatename:_nlib_strchr=_nlib_strchr_generic")
765 # pragma comment(linker, "/alternatename:_nlib_strrchr=_nlib_strrchr_generic")
766 # pragma comment(linker, "/alternatename:_nlib_strchr_mb=_nlib_strchr_mb_generic")
767 # pragma comment(linker, "/alternatename:_nlib_memcmp=_nlib_memcmp_generic")
768 # pragma comment(linker, "/alternatename:_nlib_memchr=_nlib_memchr_generic")
769 # pragma comment(linker, "/alternatename:_nlib_memrchr=_nlib_memrchr_generic")
770 # pragma comment(linker, "/alternatename:_nlib_memchr_not=_nlib_memchr_not_generic")
771 # pragma comment(linker, "/alternatename:_nlib_memchr_range_not=_nlib_memchr_range_not_generic")
772 # pragma comment(linker, "/alternatename:_nlib_memchr_lt=_nlib_memchr_lt_generic")
773 # pragma comment(linker, "/alternatename:_nlib_memchr_gt=_nlib_memchr_gt_generic")
774 # pragma comment(linker, "/alternatename:_nlib_memchr_mb=_nlib_memchr_mb_generic")
775 # pragma comment(linker, "/alternatename:_nlib_skipws=_nlib_skipws_generic")
776 # pragma comment(linker, "/alternatename:_nlib_swapendian_16=_nlib_swapendian_16_generic")
777 # pragma comment(linker, "/alternatename:_nlib_swapendian_32=_nlib_swapendian_32_generic")
778 # pragma comment(linker, "/alternatename:_nlib_swapendian_64=_nlib_swapendian_64_generic")
779 # pragma comment(linker, "/alternatename:_nlib_strcplen_ex=_nlib_strcplen_ex")
780 # pragma comment(linker, "/alternatename:_nlib_popcnt=_nlib_popcnt_generic")
781 # pragma comment(linker, "/alternatename:_nlib_popcnt64=_nlib_popcnt64_generic")
782 # else
783 # ifndef NLIB_LIBC_nlib_strlen
784 # pragma comment(linker, "/alternatename:nlib_strlen=nlib_strlen_generic")
785 # endif
786 # ifndef NLIB_LIBC_nlib_strlen
787 # pragma comment(linker, "/alternatename:nlib_strnlen=nlib_strnlen_generic")
788 # endif
789 # pragma comment(linker, "/alternatename:nlib_utf16len_=nlib_utf16len_generic")
790 # pragma comment(linker, "/alternatename:nlib_utf16nlen_=nlib_utf16nlen_generic")
791 # pragma comment(linker, "/alternatename:nlib_utf32len_=nlib_utf32len_generic")
792 # pragma comment(linker, "/alternatename:nlib_utf32nlen_=nlib_utf32nlen_generic")
793 # pragma comment(linker, "/alternatename:nlib_utf16cplen_ex_=nlib_utf16cplen_ex_generic")
794 # pragma comment(linker, "/alternatename:nlib_strchr=nlib_strchr_generic")
795 # pragma comment(linker, "/alternatename:nlib_strrchr=nlib_strrchr_generic")
796 # pragma comment(linker, "/alternatename:nlib_strchr_mb=nlib_strchr_mb_generic")
797 # pragma comment(linker, "/alternatename:nlib_memcmp=nlib_memcmp_generic")
798 # pragma comment(linker, "/alternatename:nlib_memchr=nlib_memchr_generic")
799 # pragma comment(linker, "/alternatename:nlib_memrchr=nlib_memrchr_generic")
800 # pragma comment(linker, "/alternatename:nlib_memchr_not=nlib_memchr_not_generic")
801 # pragma comment(linker, "/alternatename:nlib_memchr_range_not=nlib_memchr_range_not_generic")
802 # pragma comment(linker, "/alternatename:nlib_memchr_lt=nlib_memchr_lt_generic")
803 # pragma comment(linker, "/alternatename:nlib_memchr_gt=nlib_memchr_gt_generic")
804 # pragma comment(linker, "/alternatename:nlib_memchr_mb=nlib_memchr_mb_generic")
805 # pragma comment(linker, "/alternatename:nlib_skipws=nlib_skipws_generic")
806 # pragma comment(linker, "/alternatename:nlib_swapendian_16=nlib_swapendian_16_generic")
807 # pragma comment(linker, "/alternatename:nlib_swapendian_32=nlib_swapendian_32_generic")
808 # pragma comment(linker, "/alternatename:nlib_swapendian_64=nlib_swapendian_64_generic")
809 # pragma comment(linker, "/alternatename:nlib_strcplen_ex=nlib_strcplen_ex")
810 # pragma comment(linker, "/alternatename:nlib_popcnt=nlib_popcnt_generic")
811 # pragma comment(linker, "/alternatename:nlib_popcnt64=nlib_popcnt64_generic")
812 # endif
813 #endif
814 
815 #endif
816 #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()に準じます。 ...
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()に準じます。
int64_t nlib_atomic_fetch_add64(int64_t *ptr, int64_t val, int memorder)
アトミックな値の加算を行います。動作はgccの__atomic_fetch_add()に準じます。
struct nlib_rwlock_ nlib_rwlock
リードライトロックオブジェクトの型です。
Definition: Platform.h:1113
sem_t nlib_semaphore
セマフォオブジェクトの型です。
#define NLIB_MEMORY_ORDER_ACQUIRE
メモリフェンスです。C++11ではatomic_thread_fence(memory_order_acquire)に一致します。 ...
#define NLIB_ATOMIC_RELEASE
gccの__ATOMIC_RELEASEやC++11のstd::memory_order_releaseに準じます。
int32_t nlib_atomic_or_fetch32(int32_t *ptr, int32_t val, int memorder)
アトミックな値の論理和の計算を行います。動作はgccの__atomic_or_fetch()に準じます。 ...
int64_t nlib_atomic_fetch_sub64(int64_t *ptr, int64_t val, int memorder)
アトミックな値の減算を行います。動作はgccの__atomic_fetch_sub()に準じます。
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:61
int64_t nlib_atomic_fetch_or64(int64_t *ptr, int64_t val, int memorder)
アトミックな値の論理和の計算を行います。動作はgccの__atomic_fetch_or()に準じます。 ...
#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)に一致します。 ...
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
条件変数オブジェクトの型です。
#define NLIB_ATOMIC_RELAXED
gccの__ATOMIC_RELAXEDやC++11のstd::memory_order_relaxedに準じます。
pthread_mutex_t nlib_mutex
ミューテックス変数の型です。
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()に準じます。
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()に準じます。
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()に準じます。 ...
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()に準じます。