Commit | Line | Data |
---|---|---|
7fd59977 | 1 | // File: Standard_Atomic.hxx |
2 | // Created: Tue Sep 04 08:52:43 2007 | |
3 | // Author: Andrey BETENEV | |
4 | ||
5 | //! @file | |
6 | //! Implementation of some atomic operations (elementary operations | |
7 | //! with data that cannot be interrupted by parallel threads in the | |
8 | //! multithread process) on various platforms | |
9 | //! | |
10 | //! By the moment, only operations necessary for reference counter | |
11 | //! in Standard_Transient objects are implemented. | |
12 | //! | |
e33e7e78 RK |
13 | //! This is preffered to use fixed size types "int32_t" / "int64_t" for |
14 | //! correct function declarations however we leave "int" assuming it is 32bits for now. | |
7fd59977 | 15 | |
e33e7e78 RK |
16 | #ifndef _Standard_Atomic_HeaderFile |
17 | #define _Standard_Atomic_HeaderFile | |
7fd59977 | 18 | |
e33e7e78 | 19 | #include <Standard_Macro.hxx> |
7fd59977 | 20 | |
e33e7e78 | 21 | #if (defined(_WIN32) || defined(__WIN32__)) |
7fd59977 | 22 | extern "C" { |
e33e7e78 RK |
23 | long _InterlockedIncrement(long volatile* lpAddend); |
24 | long _InterlockedDecrement(long volatile* lpAddend); | |
7fd59977 | 25 | } |
e33e7e78 | 26 | #endif |
7fd59977 | 27 | |
e33e7e78 RK |
28 | #if defined(_MSC_VER) |
29 | // force intrinsic instead of WinAPI calls | |
30 | #pragma intrinsic (_InterlockedIncrement) | |
31 | #pragma intrinsic (_InterlockedDecrement) | |
32 | #endif | |
7fd59977 | 33 | |
e33e7e78 RK |
34 | //! Increments atomically integer variable pointed by theValue |
35 | //! and returns resulting incremented value. | |
36 | static int Standard_Atomic_Increment (volatile int* theValue) | |
7fd59977 | 37 | { |
e33e7e78 RK |
38 | #ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 |
39 | // mordern g++ compiler (gcc4.4+) | |
40 | // built-in functions available for appropriate CPUs (at least -march=i486 should be specified on x86 platform) | |
41 | return __sync_add_and_fetch (theValue, 1); | |
42 | #elif (defined(_WIN32) || defined(__WIN32__)) | |
43 | // WinAPI function or MSVC intrinsic | |
44 | return _InterlockedIncrement(reinterpret_cast<long volatile*>(theValue)); | |
7fd59977 | 45 | #elif defined(LIN) |
e33e7e78 RK |
46 | // use x86 / x86_64 inline assembly (compatibility with alien compilers / old GCC) |
47 | int anIncResult; | |
48 | __asm__ __volatile__ ( | |
49 | #if defined(_OCC64) | |
50 | "lock xaddl %%ebx, (%%rax) \n\t" | |
51 | "incl %%ebx \n\t" | |
52 | : "=b" (anIncResult) | |
53 | : "a" (theValue), "b" (1) | |
54 | : "cc", "memory"); | |
55 | #else | |
56 | "lock xaddl %%eax, (%%ecx) \n\t" | |
57 | "incl %%eax \n\t" | |
58 | : "=a" (anIncResult) | |
59 | : "c" (theValue), "a" (1) | |
60 | : "memory"); | |
61 | #endif | |
62 | return anIncResult; | |
7fd59977 | 63 | #else |
e33e7e78 RK |
64 | //#error "Atomic operation doesn't implemented for current platform!" |
65 | return ++(*theValue); | |
66 | #endif | |
7fd59977 | 67 | } |
68 | ||
e33e7e78 RK |
69 | //! Decrements atomically integer variable pointed by theValue |
70 | //! and returns resulting decremented value. | |
71 | static int Standard_Atomic_Decrement (volatile int* theValue) | |
7fd59977 | 72 | { |
e33e7e78 RK |
73 | #ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 |
74 | // mordern g++ compiler (gcc4.4+) | |
75 | // built-in functions available for appropriate CPUs (at least -march=i486 should be specified on x86 platform) | |
76 | return __sync_sub_and_fetch (theValue, 1); | |
77 | #elif (defined(_WIN32) || defined(__WIN32__)) | |
78 | // WinAPI function or MSVC intrinsic | |
79 | return _InterlockedDecrement(reinterpret_cast<long volatile*>(theValue)); | |
80 | #elif defined(LIN) | |
81 | // use x86 / x86_64 inline assembly (compatibility with alien compilers / old GCC) | |
82 | int aDecResult; | |
83 | __asm__ __volatile__ ( | |
84 | #if defined(_OCC64) | |
85 | "lock xaddl %%ebx, (%%rax) \n\t" | |
86 | "decl %%ebx \n\t" | |
87 | : "=b" (aDecResult) | |
88 | : "a" (theValue), "b" (-1) | |
89 | : "cc", "memory"); | |
90 | #else | |
91 | "lock xaddl %%eax, (%%ecx) \n\t" | |
92 | "decl %%eax \n\t" | |
93 | : "=a" (aDecResult) | |
94 | : "c" (theValue), "a" (-1) | |
95 | : "memory"); | |
96 | #endif | |
97 | return aDecResult; | |
98 | #else | |
99 | //#error "Atomic operation doesn't implemented for current platform!" | |
100 | return --(*theValue); | |
101 | #endif | |
7fd59977 | 102 | } |
103 | ||
e33e7e78 | 104 | #endif //_Standard_Atomic_HeaderFile |