Changelog update
[public/netxms.git] / src / libnetxms / parisc_atomic.cpp
CommitLineData
6dde8627
VK
1/*
2** NetXMS - Network Management System
3** NetXMS Foundation Library
4** Copyright (C) 2003-2013 Victor Kirhenshtein
5**
6** This program is free software; you can redistribute it and/or modify
7** it under the terms of the GNU Lesser General Public License as published
8** by the Free Software Foundation; either version 3 of the License, or
9** (at your option) any later version.
10**
11** This program is distributed in the hope that it will be useful,
12** but WITHOUT ANY WARRANTY; without even the implied warranty of
13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14** GNU General Public License for more details.
15**
16** You should have received a copy of the GNU Lesser General Public License
17** along with this program; if not, write to the Free Software
18** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19**
20** File: parisc_atomic.cpp
21**
22**/
23
24#include "libnetxms.h"
25
26#if defined(__HP_aCC) && defined(__hppa) && !HAVE_ATOMIC_H
27
28extern "C" volatile int __ldcw(volatile int *);
29
30/**
31 * Global lock area
32 */
33static int lockArea[4] = { 1, 1, 1, 1 };
34
35/**
36 * Get 16-byte aligned address within lock area
37 */
38#ifdef __64BIT__
39#define aligned_addr(x) ((volatile int *)(((unsigned long)(x) + 15) & ~0x0F))
40#else
41#define aligned_addr(x) ((volatile int *)(((unsigned int)(x) + 15) & ~0x0F))
42#endif
43
44/**
45 * Lock spinlock
46 */
47inline void spinlock_lock(volatile int *lockArea)
48{
49 while(1)
50 {
51 if (*aligned_addr(lockArea) == 1)
52 if (__ldcw(lockArea) == 1)
53 return;
54 }
55}
56
57/**
58 * Unlock spinlock
59 */
60inline void spinlock_unlock(volatile int *lockArea)
61{
62 *aligned_addr(lockArea) = 1;
63}
64
65/**
66 * Atomic increment
67 */
68VolatileCounter parisc_atomic_inc(VolatileCounter *v)
69{
70 spinlock_lock(lockArea);
71 int nv = ++(*v);
72 spinlock_unlock(lockArea);
73 return nv;
74}
75
76/**
77 * Atomic decrement
78 */
79VolatileCounter parisc_atomic_dec(VolatileCounter *v)
80{
81 spinlock_lock(lockArea);
82 int nv = --(*v);
83 spinlock_unlock(lockArea);
84 return nv;
85}
86
87#endif