Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "system.hxx"
21 :
22 : #include <osl/interlck.h>
23 : #include <osl/diagnose.h>
24 :
25 : #if ( defined ( SOLARIS ) || defined ( NETBSD ) ) && defined ( SPARC )
26 : #error please use asm/interlck_sparc.s
27 : #elif defined ( SOLARIS) && defined ( X86 )
28 : #error please use asm/interlck_x86.s
29 : #elif defined ( __GNUC__ ) && ( defined ( X86 ) || defined ( X86_64 ) )
30 : /* That's possible on x86-64 too since oslInterlockedCount is a sal_Int32 */
31 :
32 0 : oslInterlockedCount SAL_CALL osl_incrementInterlockedCount(oslInterlockedCount* pCount)
33 : {
34 : #if HAVE_GCC_BUILTIN_ATOMIC
35 0 : return __sync_add_and_fetch (pCount, 1);
36 : #else
37 : register oslInterlockedCount nCount asm("%eax");
38 : nCount = 1;
39 : __asm__ __volatile__ (
40 : "lock\n\t"
41 : "xaddl %0, %1\n\t"
42 : : "+r" (nCount), "+m" (*pCount)
43 : : /* nothing */
44 : : "memory");
45 : return ++nCount;
46 : #endif
47 : }
48 :
49 0 : oslInterlockedCount SAL_CALL osl_decrementInterlockedCount(oslInterlockedCount* pCount)
50 : {
51 : #if HAVE_GCC_BUILTIN_ATOMIC
52 0 : return __sync_sub_and_fetch (pCount, 1);
53 : #else
54 : register oslInterlockedCount nCount asm("%eax");
55 : nCount = -1;
56 : __asm__ __volatile__ (
57 : "lock\n\t"
58 : "xaddl %0, %1\n\t"
59 : : "+r" (nCount), "+m" (*pCount)
60 : : /* nothing */
61 : : "memory");
62 : return --nCount;
63 : #endif
64 : }
65 : #elif HAVE_GCC_BUILTIN_ATOMIC
66 : oslInterlockedCount SAL_CALL osl_incrementInterlockedCount(oslInterlockedCount* pCount)
67 : {
68 : return __sync_add_and_fetch(pCount, 1);
69 : }
70 : oslInterlockedCount SAL_CALL osl_decrementInterlockedCount(oslInterlockedCount* pCount)
71 : {
72 : return __sync_sub_and_fetch(pCount, 1);
73 : }
74 : #else
75 : /* use only if nothing else works, expensive due to single mutex for all reference counts */
76 :
77 : static pthread_mutex_t InterLock = PTHREAD_MUTEX_INITIALIZER;
78 :
79 : oslInterlockedCount SAL_CALL osl_incrementInterlockedCount(oslInterlockedCount* pCount)
80 : {
81 : oslInterlockedCount Count;
82 :
83 : pthread_mutex_lock(&InterLock);
84 : Count = ++(*pCount);
85 : pthread_mutex_unlock(&InterLock);
86 :
87 : return Count;
88 : }
89 :
90 : oslInterlockedCount SAL_CALL osl_decrementInterlockedCount(oslInterlockedCount* pCount)
91 : {
92 : oslInterlockedCount Count;
93 :
94 : pthread_mutex_lock(&InterLock);
95 : Count = --(*pCount);
96 : pthread_mutex_unlock(&InterLock);
97 :
98 : return Count;
99 : }
100 :
101 : #endif /* default */
102 :
103 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|