xref: /AOO41X/main/sal/osl/w32/interlck.c (revision 647f063d49501903f1667b75f5634541fc603283)
1*647f063dSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*647f063dSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*647f063dSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*647f063dSAndrew Rist  * distributed with this work for additional information
6*647f063dSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*647f063dSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*647f063dSAndrew Rist  * "License"); you may not use this file except in compliance
9*647f063dSAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*647f063dSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*647f063dSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*647f063dSAndrew Rist  * software distributed under the License is distributed on an
15*647f063dSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*647f063dSAndrew Rist  * KIND, either express or implied.  See the License for the
17*647f063dSAndrew Rist  * specific language governing permissions and limitations
18*647f063dSAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*647f063dSAndrew Rist  *************************************************************/
21*647f063dSAndrew Rist 
22*647f063dSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #include "system.h"
25cdf0e10cSrcweir 
26cdf0e10cSrcweir #include <osl/interlck.h>
27cdf0e10cSrcweir #include <osl/diagnose.h>
28cdf0e10cSrcweir 
29cdf0e10cSrcweir extern int osl_isSingleCPU;
30cdf0e10cSrcweir 
31cdf0e10cSrcweir /* For all Intel x86 above x486 we use a spezial inline assembler implementation.
32cdf0e10cSrcweir    The main reason is that WIN9? does not return the result of the operation.
33cdf0e10cSrcweir    Instead there is only returned a value greater than zero is the increment
34cdf0e10cSrcweir    result is greater than zero, but not the the result of the addition.
35cdf0e10cSrcweir    For Windows NT the native function could be used, because the correct result
36cdf0e10cSrcweir    is returned. Beacuse of simpler code maintance and performace reasons we use
37cdf0e10cSrcweir    on every x86-Windows-Platform the inline assembler implementation.
38cdf0e10cSrcweir */
39cdf0e10cSrcweir 
40cdf0e10cSrcweir /*****************************************************************************/
41cdf0e10cSrcweir /* osl_incrementInterlockedCount */
42cdf0e10cSrcweir /*****************************************************************************/
osl_incrementInterlockedCount(oslInterlockedCount * pCount)43cdf0e10cSrcweir oslInterlockedCount SAL_CALL osl_incrementInterlockedCount(oslInterlockedCount* pCount)
44cdf0e10cSrcweir #ifdef _M_IX86
45cdf0e10cSrcweir #ifdef __MINGW32__
46cdf0e10cSrcweir {
47cdf0e10cSrcweir 	asm
48cdf0e10cSrcweir 	(
49cdf0e10cSrcweir 	 "	movl        %0, %%ecx\n"
50cdf0e10cSrcweir 	 "  	movl        $1, %%eax\n"
51cdf0e10cSrcweir 	 "	movl        %1, %%edx\n"
52cdf0e10cSrcweir 	 "	cmpl        $0, %%edx\n"
53cdf0e10cSrcweir 	 "	je          1f\n"
54cdf0e10cSrcweir 	 "  	xadd        %%eax, (%%ecx)\n"
55cdf0e10cSrcweir 	 "	jmp         2f\n"
56cdf0e10cSrcweir 	 "1:\n"
57cdf0e10cSrcweir 	 "  	lock xadd   %%eax, (%%ecx)\n"
58cdf0e10cSrcweir 	 "2:\n"
59cdf0e10cSrcweir 	 "  	incl        %%eax\n"
60cdf0e10cSrcweir 	 ::"m"(pCount),"m"(osl_isSingleCPU)
61cdf0e10cSrcweir 	);
62cdf0e10cSrcweir }
63cdf0e10cSrcweir #else
64cdf0e10cSrcweir #pragma warning(disable: 4035)
65cdf0e10cSrcweir {
66cdf0e10cSrcweir     __asm
67cdf0e10cSrcweir     {
68cdf0e10cSrcweir         mov         ecx, pCount
69cdf0e10cSrcweir         mov         eax, 1
70cdf0e10cSrcweir         mov         edx, osl_isSingleCPU
71cdf0e10cSrcweir         cmp         edx, 0
72cdf0e10cSrcweir         je          is_not_single
73cdf0e10cSrcweir         xadd        dword ptr [ecx],eax
74cdf0e10cSrcweir         jmp         cont
75cdf0e10cSrcweir     is_not_single:
76cdf0e10cSrcweir         lock xadd   dword ptr [ecx],eax
77cdf0e10cSrcweir     cont:
78cdf0e10cSrcweir         inc         eax
79cdf0e10cSrcweir     }
80cdf0e10cSrcweir }
81cdf0e10cSrcweir #pragma warning(default: 4035)
82cdf0e10cSrcweir #endif
83cdf0e10cSrcweir #else
84cdf0e10cSrcweir #pragma message("WARNING: Using system InterlockedIncrement")
85cdf0e10cSrcweir {
86cdf0e10cSrcweir     return (InterlockedIncrement(pCount));
87cdf0e10cSrcweir }
88cdf0e10cSrcweir #endif
89cdf0e10cSrcweir 
90cdf0e10cSrcweir /*****************************************************************************/
91cdf0e10cSrcweir /* osl_decrementInterlockedCount */
92cdf0e10cSrcweir /*****************************************************************************/
osl_decrementInterlockedCount(oslInterlockedCount * pCount)93cdf0e10cSrcweir oslInterlockedCount SAL_CALL osl_decrementInterlockedCount(oslInterlockedCount* pCount)
94cdf0e10cSrcweir #ifdef _M_IX86
95cdf0e10cSrcweir #ifdef __MINGW32__
96cdf0e10cSrcweir {
97cdf0e10cSrcweir 	asm
98cdf0e10cSrcweir 	(
99cdf0e10cSrcweir 	 "	movl        %0, %%ecx\n"
100cdf0e10cSrcweir 	 "  	orl         $-1, %%eax\n"
101cdf0e10cSrcweir 	 "	movl        %1, %%edx\n"
102cdf0e10cSrcweir 	 "	cmpl        $0, %%edx\n"
103cdf0e10cSrcweir 	 "	je          1f\n"
104cdf0e10cSrcweir 	 "  	xadd        %%eax, (%%ecx)\n"
105cdf0e10cSrcweir 	 "	jmp         2f\n"
106cdf0e10cSrcweir 	 "1:\n"
107cdf0e10cSrcweir 	 "  	lock xadd   %%eax, (%%ecx)\n"
108cdf0e10cSrcweir 	 "2:\n"
109cdf0e10cSrcweir 	 "  	decl        %%eax\n"
110cdf0e10cSrcweir 	 ::"m"(pCount),"m"(osl_isSingleCPU)
111cdf0e10cSrcweir 	);
112cdf0e10cSrcweir }
113cdf0e10cSrcweir #else
114cdf0e10cSrcweir #pragma warning(disable: 4035)
115cdf0e10cSrcweir {
116cdf0e10cSrcweir     __asm
117cdf0e10cSrcweir     {
118cdf0e10cSrcweir         mov         ecx, pCount
119cdf0e10cSrcweir         or          eax, -1
120cdf0e10cSrcweir         mov         edx, osl_isSingleCPU
121cdf0e10cSrcweir         cmp         edx, 0
122cdf0e10cSrcweir         je          is_not_single
123cdf0e10cSrcweir         xadd        dword ptr [ecx],eax
124cdf0e10cSrcweir         jmp         cont
125cdf0e10cSrcweir     is_not_single:
126cdf0e10cSrcweir         lock xadd   dword ptr [ecx],eax
127cdf0e10cSrcweir     cont:
128cdf0e10cSrcweir         dec         eax
129cdf0e10cSrcweir     }
130cdf0e10cSrcweir }
131cdf0e10cSrcweir #pragma warning(default: 4035)
132cdf0e10cSrcweir #endif
133cdf0e10cSrcweir #else
134cdf0e10cSrcweir #pragma message("WARNING: Using system InterlockedDecrement")
135cdf0e10cSrcweir {
136cdf0e10cSrcweir     return (InterlockedDecrement(pCount));
137cdf0e10cSrcweir }
138cdf0e10cSrcweir #endif
139