0023024: Update headers of OCCT files
[occt.git] / src / Standard / Standard_Atomic.hxx
CommitLineData
b311480e 1// Created on: 2007-09-04
2// Created by: Andrey BETENEV
3// Copyright (c) 2007-2012 OPEN CASCADE SAS
4//
5// The content of this file is subject to the Open CASCADE Technology Public
6// License Version 6.5 (the "License"). You may not use the content of this file
7// except in compliance with the License. Please obtain a copy of the License
8// at http://www.opencascade.org and read it completely before using this file.
9//
10// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12//
13// The Original Code and all software distributed under the License is
14// distributed on an "AS IS" basis, without warranty of any kind, and the
15// Initial Developer hereby disclaims all such warranties, including without
16// limitation, any warranties of merchantability, fitness for a particular
17// purpose or non-infringement. Please see the License for the specific terms
18// and conditions governing the rights and limitations under the License.
19
7fd59977 20
21//! @file
22//! Implementation of some atomic operations (elementary operations
23//! with data that cannot be interrupted by parallel threads in the
24//! multithread process) on various platforms
25//!
26//! By the moment, only operations necessary for reference counter
27//! in Standard_Transient objects are implemented.
28//!
e33e7e78
RK
29//! This is preffered to use fixed size types "int32_t" / "int64_t" for
30//! correct function declarations however we leave "int" assuming it is 32bits for now.
7fd59977 31
e33e7e78
RK
32#ifndef _Standard_Atomic_HeaderFile
33#define _Standard_Atomic_HeaderFile
7fd59977 34
e33e7e78 35#include <Standard_Macro.hxx>
7fd59977 36
e33e7e78 37#if (defined(_WIN32) || defined(__WIN32__))
7fd59977 38extern "C" {
e33e7e78
RK
39 long _InterlockedIncrement(long volatile* lpAddend);
40 long _InterlockedDecrement(long volatile* lpAddend);
7fd59977 41}
e33e7e78 42#endif
7fd59977 43
e33e7e78
RK
44#if defined(_MSC_VER)
45 // force intrinsic instead of WinAPI calls
46 #pragma intrinsic (_InterlockedIncrement)
47 #pragma intrinsic (_InterlockedDecrement)
48#endif
7fd59977 49
e33e7e78
RK
50//! Increments atomically integer variable pointed by theValue
51//! and returns resulting incremented value.
52static int Standard_Atomic_Increment (volatile int* theValue)
7fd59977 53{
e33e7e78
RK
54#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
55 // mordern g++ compiler (gcc4.4+)
56 // built-in functions available for appropriate CPUs (at least -march=i486 should be specified on x86 platform)
57 return __sync_add_and_fetch (theValue, 1);
58#elif (defined(_WIN32) || defined(__WIN32__))
59 // WinAPI function or MSVC intrinsic
60 return _InterlockedIncrement(reinterpret_cast<long volatile*>(theValue));
7fd59977 61#elif defined(LIN)
e33e7e78
RK
62 // use x86 / x86_64 inline assembly (compatibility with alien compilers / old GCC)
63 int anIncResult;
64 __asm__ __volatile__ (
65 #if defined(_OCC64)
66 "lock xaddl %%ebx, (%%rax) \n\t"
67 "incl %%ebx \n\t"
68 : "=b" (anIncResult)
69 : "a" (theValue), "b" (1)
70 : "cc", "memory");
71 #else
72 "lock xaddl %%eax, (%%ecx) \n\t"
73 "incl %%eax \n\t"
74 : "=a" (anIncResult)
75 : "c" (theValue), "a" (1)
76 : "memory");
77 #endif
78 return anIncResult;
7fd59977 79#else
e33e7e78
RK
80 //#error "Atomic operation doesn't implemented for current platform!"
81 return ++(*theValue);
82#endif
7fd59977 83}
84
e33e7e78
RK
85//! Decrements atomically integer variable pointed by theValue
86//! and returns resulting decremented value.
87static int Standard_Atomic_Decrement (volatile int* theValue)
7fd59977 88{
e33e7e78
RK
89#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
90 // mordern g++ compiler (gcc4.4+)
91 // built-in functions available for appropriate CPUs (at least -march=i486 should be specified on x86 platform)
92 return __sync_sub_and_fetch (theValue, 1);
93#elif (defined(_WIN32) || defined(__WIN32__))
94 // WinAPI function or MSVC intrinsic
95 return _InterlockedDecrement(reinterpret_cast<long volatile*>(theValue));
96#elif defined(LIN)
97 // use x86 / x86_64 inline assembly (compatibility with alien compilers / old GCC)
98 int aDecResult;
99 __asm__ __volatile__ (
100 #if defined(_OCC64)
101 "lock xaddl %%ebx, (%%rax) \n\t"
102 "decl %%ebx \n\t"
103 : "=b" (aDecResult)
104 : "a" (theValue), "b" (-1)
105 : "cc", "memory");
106 #else
107 "lock xaddl %%eax, (%%ecx) \n\t"
108 "decl %%eax \n\t"
109 : "=a" (aDecResult)
110 : "c" (theValue), "a" (-1)
111 : "memory");
112 #endif
113 return aDecResult;
114#else
115 //#error "Atomic operation doesn't implemented for current platform!"
116 return --(*theValue);
117#endif
7fd59977 118}
119
e33e7e78 120#endif //_Standard_Atomic_HeaderFile