1 /*
2 * include/asm-s390/spinlock.h
3 *
4 * S390 version
5 * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
6 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
7 *
8 * Derived from "include/asm-i386/spinlock.h"
9 */
10
11 #ifndef __ASM_SPINLOCK_H
12 #define __ASM_SPINLOCK_H
13
14 /*
15 * Simple spin lock operations. There are two variants, one clears IRQ's
16 * on the local processor, one does not.
17 *
18 * We make no fairness assumptions. They have a cost.
19 */
20
21 typedef struct {
22 volatile unsigned long lock;
23 } spinlock_t;
24
25 #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
26 #define spin_lock_init(lp) do { (lp)->lock = 0; } while(0)
27 #define spin_unlock_wait(lp) do { barrier(); } while((volatile spinlock_t *)(lp)->lock)
28 #define spin_is_locked(x) ((x)->lock != 0)
29
30 extern inline void spin_lock(spinlock_t *lp)
31 {
32 __asm__ __volatile(" lhi 1,-1\n"
33 "0: slr 0,0\n"
34 " cs 0,1,%1\n"
35 " jl 0b"
36 : "=m" (lp->lock)
37 : "" (lp->lock) : "", "1");
38 }
39
40 extern inline int spin_trylock(spinlock_t *lp)
41 {
42 unsigned long result;
43 __asm__ __volatile(" slr %1,%1\n"
44 " lhi 0,-1\n"
45 "0: cs %1,0,%0"
46 : "=m" (lp->lock), "=&d" (result)
47 : "" (lp->lock) : "");
48 return !result;
49 }
50
51
52
53 extern inline void spin_unlock(spinlock_t *lp)
54 {
55 __asm__ __volatile(" xc 0(4,%0),0(%0)\n"
56 " bcr 15,0"
57 : /* no output */ : "a" (lp) );
58 }
59
60 /*
61 * Read-write spinlocks, allowing multiple readers
62 * but only one writer.
63 *
64 * NOTE! it is quite common to have readers in interrupts
65 * but no interrupt writers. For those circumstances we
66 * can "mix" irq-safe locks - any writer needs to get a
67 * irq-safe write-lock, but readers can get non-irqsafe
68 * read-locks.
69 */
70 typedef struct {
71 volatile unsigned long lock;
72 volatile unsigned long owner_pc;
73 } rwlock_t;
74
75 #define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 }
76
77 #define read_lock(rw) \
78 asm volatile(" l 2,%0\n" \
79 "0: sll 2,1\n" \
80 " srl 2,1\n" /* clear high (=write) bit */ \
81 " lr 3,2\n" \
82 " ahi 3,1\n" /* one more reader */ \
83 " cs 2,3,%0\n" /* try to write new value */ \
84 " jl 0b" \
85 : "+m" ((rw)->lock) : : "2", "3" );
86
87 #define read_unlock(rw) \
88 asm volatile(" l 2,%0\n" \
89 "0: lr 3,2\n" \
90 " ahi 3,-1\n" /* one less reader */ \
91 " cs 2,3,%0\n" \
92 " jl 0b" \
93 : "+m" ((rw)->lock) : : "2", "3" );
94
95 #define write_lock(rw) \
96 asm volatile(" lhi 3,1\n" \
97 " sll 3,31\n" /* new lock value = 0x80000000 */ \
98 "0: slr 2,2\n" /* old lock value must be 0 */ \
99 " cs 2,3,%0\n" \
100 " jl 0b" \
101 : "+m" ((rw)->lock) : : "2", "3" );
102
103 #define write_unlock(rw) \
104 asm volatile(" slr 3,3\n" /* new lock value = 0 */ \
105 "0: lhi 2,1\n" \
106 " sll 2,31\n" /* old lock value must be 0x80000000 */ \
107 " cs 2,3,%0\n" \
108 " jl 0b" \
109 : "+m" ((rw)->lock) : : "2", "3" );
110
111 #endif /* __ASM_SPINLOCK_H */
112
113
114
115
116
117
118
119
120
121
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.