merged tag ooo/DEV300_m102
[LibreOffice.git] / sal / osl / unx / interlck.c
blob0342cdd983b4af1305db5623f07d006f3a450f03
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
29 #include "system.h"
31 #include <osl/interlck.h>
32 #include <osl/diagnose.h>
34 #if ( defined ( SOLARIS ) || defined ( NETBSD ) ) && defined ( SPARC )
35 #error please use asm/interlck_sparc.s
36 #elif defined ( SOLARIS) && defined ( X86 )
37 #error please use asm/interlck_x86.s
38 #elif defined ( GCC ) && ( defined ( X86 ) || defined ( X86_64 ) )
39 /* That's possible on x86-64 too since oslInterlockedCount is a sal_Int32 */
41 extern int osl_isSingleCPU;
43 /*****************************************************************************/
44 /* osl_incrementInterlockedCount */
45 /*****************************************************************************/
46 oslInterlockedCount SAL_CALL osl_incrementInterlockedCount(oslInterlockedCount* pCount)
48 register oslInterlockedCount nCount asm("%eax");
50 nCount = 1;
52 if ( osl_isSingleCPU ) {
53 __asm__ __volatile__ (
54 "xaddl %0, %1\n\t"
55 : "+r" (nCount), "+m" (*pCount)
56 : /* nothing */
57 : "memory");
59 else {
60 __asm__ __volatile__ (
61 "lock\n\t"
62 "xaddl %0, %1\n\t"
63 : "+r" (nCount), "+m" (*pCount)
64 : /* nothing */
65 : "memory");
68 return ++nCount;
71 oslInterlockedCount SAL_CALL osl_decrementInterlockedCount(oslInterlockedCount* pCount)
73 register oslInterlockedCount nCount asm("%eax");
75 nCount = -1;
77 if ( osl_isSingleCPU ) {
78 __asm__ __volatile__ (
79 "xaddl %0, %1\n\t"
80 : "+r" (nCount), "+m" (*pCount)
81 : /* nothing */
82 : "memory");
84 else {
85 __asm__ __volatile__ (
86 "lock\n\t"
87 "xaddl %0, %1\n\t"
88 : "+r" (nCount), "+m" (*pCount)
89 : /* nothing */
90 : "memory");
93 return --nCount;
96 #elif defined ( GCC ) && defined ( POWERPC )
98 /*****************************************************************************/
99 /* osl_incrementInterlockedCount */
100 /*****************************************************************************/
101 oslInterlockedCount SAL_CALL osl_incrementInterlockedCount(oslInterlockedCount* pCount)
103 /* "addi" doesn't work with r0 as second parameter */
104 register oslInterlockedCount nCount __asm__ ("r4");
106 __asm__ __volatile__ (
107 "1: lwarx %0,0,%2\n\t"
108 " addi %0,%0,1\n\t"
109 " stwcx. %0,0,%2\n\t"
110 " bne- 1b\n\t"
111 " isync"
112 : "=&r" (nCount), "=m" (*pCount)
113 : "r" (pCount)
114 : "memory");
116 return nCount;
119 oslInterlockedCount SAL_CALL osl_decrementInterlockedCount(oslInterlockedCount* pCount)
121 /* "subi" doesn't work with r0 as second parameter */
122 register oslInterlockedCount nCount __asm__ ("r4");
124 __asm__ __volatile__ (
125 "1: lwarx %0,0,%2\n\t"
126 " subi %0,%0,1\n\t"
127 " stwcx. %0,0,%2\n\t"
128 " bne- 1b\n\t"
129 " isync"
130 : "=&r" (nCount), "=m" (*pCount)
131 : "r" (pCount)
132 : "memory");
134 return nCount;
137 #else
138 /* use only if nothing else works, expensive due to single mutex for all reference counts */
140 static pthread_mutex_t InterLock = PTHREAD_MUTEX_INITIALIZER;
142 /*****************************************************************************/
143 /* osl_incrementInterlockedCount */
144 /*****************************************************************************/
145 oslInterlockedCount SAL_CALL osl_incrementInterlockedCount(oslInterlockedCount* pCount)
147 oslInterlockedCount Count;
149 pthread_mutex_lock(&InterLock);
150 Count = ++(*pCount);
151 pthread_mutex_unlock(&InterLock);
153 return (Count);
156 /*****************************************************************************/
157 /* osl_decrementInterlockedCount */
158 /*****************************************************************************/
159 oslInterlockedCount SAL_CALL osl_decrementInterlockedCount(oslInterlockedCount* pCount)
161 oslInterlockedCount Count;
163 pthread_mutex_lock(&InterLock);
164 Count = --(*pCount);
165 pthread_mutex_unlock(&InterLock);
167 return (Count);
170 #endif /* default */