more debug output
[linux-2.4.git] / include / asm-cris / locks.h
1 /*
2  *      SMP locks primitives for building ix86 locks
3  *      (not yet used).
4  *
5  *              Alan Cox, alan@cymru.net, 1995
6  */
7  
8 /*
9  *      This would be much easier but far less clear and easy
10  *      to borrow for other processors if it was just assembler.
11  */
12
13 extern __inline__ void prim_spin_lock(struct spinlock *sp)
14 {
15         int processor=smp_processor_id();
16         
17         /*
18          *      Grab the lock bit
19          */
20          
21         while(lock_set_bit(0,&sp->lock))
22         {
23                 /*
24                  *      Failed, but that's cos we own it!
25                  */
26                  
27                 if(sp->cpu==processor)
28                 {
29                         sp->users++;
30                         return 0;
31                 }
32                 /*
33                  *      Spin in the cache S state if possible
34                  */
35                 while(sp->lock)
36                 {
37                         /*
38                          *      Wait for any invalidates to go off
39                          */
40                          
41                         if(smp_invalidate_needed&(1<<processor))
42                                 while(lock_clear_bit(processor,&smp_invalidate_needed))
43                                         local_flush_tlb();
44                         sp->spins++;
45                 }
46                 /*
47                  *      Someone wrote the line, we go 'I' and get
48                  *      the cache entry. Now try to regrab
49                  */
50         }
51         sp->users++;sp->cpu=processor;
52         return 1;
53 }
54
55 /*
56  *      Release a spin lock
57  */
58  
59 extern __inline__ int prim_spin_unlock(struct spinlock *sp)
60 {
61         /* This is safe. The decrement is still guarded by the lock. A multilock would
62            not be safe this way */
63         if(!--sp->users)
64         {
65                 lock_clear_bit(0,&sp->lock);sp->cpu= NO_PROC_ID;
66                 return 1;
67         }
68         return 0;
69 }
70
71
72 /*
73  *      Non blocking lock grab
74  */
75  
76 extern __inline__ int prim_spin_lock_nb(struct spinlock *sp)
77 {
78         if(lock_set_bit(0,&sp->lock))
79                 return 0;               /* Locked already */
80         sp->users++;
81         return 1;                       /* We got the lock */
82 }
83
84
85 /*
86  *      These wrap the locking primitives up for usage
87  */
88  
89 extern __inline__ void spinlock(struct spinlock *sp)
90 {
91         if(sp->priority<current->lock_order)
92                 panic("lock order violation: %s (%d)\n", sp->name, current->lock_order);
93         if(prim_spin_lock(sp))
94         {
95                 /*
96                  *      We got a new lock. Update the priority chain
97                  */
98                 sp->oldpri=current->lock_order;
99                 current->lock_order=sp->priority;
100         }
101 }
102
103 extern __inline__ void spinunlock(struct spinlock *sp)
104 {
105         if(current->lock_order!=sp->priority)
106                 panic("lock release order violation %s (%d)\n", sp->name, current->lock_order);
107         if(prim_spin_unlock(sp))
108         {
109                 /*
110                  *      Update the debugging lock priority chain. We dumped
111                  *      our last right to the lock.
112                  */
113                 current->lock_order=sp->oldpri;
114         }       
115 }
116
117 extern __inline__ void spintestlock(struct spinlock *sp)
118 {
119         /*
120          *      We do no sanity checks, it's legal to optimistically
121          *      get a lower lock.
122          */
123         prim_spin_lock_nb(sp);
124 }
125
126 extern __inline__ void spintestunlock(struct spinlock *sp)
127 {
128         /*
129          *      A testlock doesn't update the lock chain so we
130          *      must not update it on free
131          */
132         prim_spin_unlock(sp);
133 }