File: sparc_locks.h

package info (click to toggle)
yap 5.1.1-3
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 16,124 kB
  • ctags: 14,650
  • sloc: ansic: 122,796; perl: 22,545; sh: 3,768; java: 1,277; makefile: 1,191; xml: 739; tcl: 624; lisp: 142; awk: 9
file content (108 lines) | stat: -rw-r--r-- 3,275 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/**********************************************************************
                                                               
                       The OPTYap Prolog system                
  OPTYap extends the Yap Prolog system to support or-parallel tabling
                                                               
  Copyright:   R. Rocha and NCC - University of Porto, Portugal
  File:        sparc_locks.h
  version:     $Id: sparc_locks.h,v 1.3 2005/05/31 08:24:24 ricroc Exp $   
                                                                     
**********************************************************************/

/* ------------------------------- **
**      Atomic lock for SPARC      **
** ------------------------------- */

#define swap_il(adr,reg)				     \
({ int _ret;						     \
   asm volatile ("swap %1,%0"				     \
	: "=r" (_ret), "=m" (*(adr))	/* Output %0,%1 */   \
	: "m"  (*(adr)), "0" (reg));	/* Input (%2),%0 */  \
   _ret;						     \
})

#define TRY_LOCK(LOCK_VAR)  (swap_il((LOCK_VAR),1)==0)

#define INIT_LOCK(LOCK_VAR)    ((LOCK_VAR) = 0)
#define LOCK(LOCK_VAR)         do {                                     \
                                 if (TRY_LOCK(&(LOCK_VAR))) break;      \
		                 while (IS_LOCKED(LOCK_VAR)) continue;  \
		               } while (1)
#define IS_LOCKED(LOCK_VAR)    ((LOCK_VAR) != 0)
#define IS_UNLOCKED(LOCK_VAR)  ((LOCK_VAR) == 0)
#define UNLOCK(LOCK_VAR)       ((LOCK_VAR) = 0)

/* Read-write spinlocks, allowing multiple readers
 * but only one writer.
 *
 */

typedef struct { volatile unsigned int lock; } rwlock_t;

/* Sort of like atomic_t's on Sparc, but even more clever.
 *
 *	------------------------------------
 *	| 24-bit counter           | wlock |  rwlock_t
 *	------------------------------------
 *	 31                       8 7     0
 *
 * wlock signifies the one writer is in or somebody is updating
 * counter. For a writer, if he successfully acquires the wlock,
 * but counter is non-zero, he has to release the lock and wait,
 * till both counter and wlock are zero.
 *
 * Unfortunately this scheme limits us to ~16,000,000 cpus.
 */

static __inline__ void _read_lock(rwlock_t *rw)
{
	register rwlock_t *lp asm("g1");
	lp = rw;
	asm __volatile__("mov	%%o7, %%g4\n\t" \
	"call	___rw_read_enter\n\t" \
	"ldstub	[%%g1 + 3], %%g2\n" \
	: /* no outputs */ \
	: "r" (lp) \
	: "g2", "g4", "g7", "memory", "cc");
}


#define READ_LOCK(lock) \
do {	_read_lock(&(lock)); \
} while(0)

static __inline__ void _read_unlock(rwlock_t *rw)
{
	register rwlock_t *lp asm("g1");
	lp = rw;
	asm __volatile__( \
	"mov	%%o7, %%g4\n\t" \
	"call	___rw_read_exit\n\t" \
        "ldstub	[%%g1 + 3], %%g2\n" \
	: /* no outputs */ \
	: "r" (lp) \
	: "g2", "g4", "g7", "memory", "cc");
}

#define READ_UNLOCK(lock) \
do {	_read_unlock(&lock); \
} while(0)

static __inline__ void write_lock(rwlock_t *rw)
{
	register rwlock_t *lp asm("g1");
	lp = rw;
	asm __volatile__( \
	"mov	%%o7, %%g4\n\t"\
	"call	___rw_write_enter\n\t" \
	"ldstub	[%%g1 + 3], %%g2\n\t" \
	: /* no outputs */ \
	: "r" (lp) \
	: "g2", "g4", "g7", "memory", "cc");
}

#define WRITE_LOCK(X)  write_lock(&(X))

#define WRITE_UNLOCK(rw)	do { (&(rw))->lock = 0; } while(0)

#define INIT_RWLOCK(RW)   (RW).lock = 0