]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4re-core/uclibc/lib/contrib/uclibc/libpthread/linuxthreads.old/sysdeps/microblaze/pt-machine.h
Update
[l4.git] / l4 / pkg / l4re-core / uclibc / lib / contrib / uclibc / libpthread / linuxthreads.old / sysdeps / microblaze / pt-machine.h
1 /*
2  * sysdeps/microblaze/pt-machine.h -- microblaze-specific pthread definitions
3  *
4  *  Copyright (C) 2003 John Williams <jwilliams@itee.uq.edu.au>
5  *  Copyright (C) 2002  NEC Electronics Corporation
6  *  Copyright (C) 2002  Miles Bader <miles@gnu.org>
7  *
8  * This file is subject to the terms and conditions of the GNU Lesser
9  * General Public License.  See the file COPYING.LIB in the main
10  * directory of this archive for more details.
11  *
12  * Written by Miles Bader <miles@gnu.org>
13  */
14
15 #ifndef _PT_MACHINE_H
16 #define _PT_MACHINE_H   1
17
18 #include <features.h>
19
20 #ifndef PT_EI
21 # define PT_EI extern inline
22 #endif
23
24 extern long int testandset (int *spinlock);
25 extern int __compare_and_swap (long *ptr, long old, long new);
26
27 /* Get some notion of the current stack.  Need not be exactly the top
28    of the stack, just something somewhere in the current frame.  */
29 #define CURRENT_STACK_FRAME  __stack_pointer
30 register char *__stack_pointer __asm__ ("r1");
31
32 #define HAS_COMPARE_AND_SWAP
33 #define HAS_COMPARE_AND_SWAP_WITH_RELEASE_SEMANTICS
34 #define IMPLEMENT_TAS_WITH_CAS
35
36 /* Atomically:  If *PTR == OLD, set *PTR to NEW and return true,
37    otherwise do nothing and return false.  */
38 PT_EI int __compare_and_swap (long *ptr, long old, long new)
39 {
40   unsigned long psw;
41
42   /* disable interrupts  */
43   /* This is ugly ugly ugly! */
44   __asm__ __volatile__ ("mfs    %0, rmsr;"
45                         "andi   r3, %0, ~2;"
46                         "mts    rmsr, r3;"
47                         : "=&r" (psw)
48                         :
49                         : "r3");
50
51   if (likely (*ptr == old))
52     {
53       *ptr = new;
54       __asm__ __volatile__ ("mts rmsr, %0;" :: "r" (psw)); /* re-enable */
55       return 1;
56     }
57   else
58     {
59       __asm__ __volatile__ ("mts rmsr, %0;" :: "r" (psw)); /* re-enable */
60       return 0;
61     }
62 }
63
64 /* like above's __compare_and_swap() but it first syncs the memory
65    (This is also the difference between both functions in e.g.
66     ../powerpc/pt-machine.h)
67    Doing this additional sync fixes a hang of __pthread_alt_unlock()
68    (Falk Brettschneider <fbrettschneider@baumeroptronic.de>) */
69 PT_EI int
70 __compare_and_swap_with_release_semantics (long *p,
71                                            long oldval, long newval)
72 {
73   __asm__ __volatile__ ("" : : : "memory"); /*MEMORY_BARRIER ();*/
74   return __compare_and_swap (p, oldval, newval);
75 }
76
77
78 #ifndef IMPLEMENT_TAS_WITH_CAS
79 /* Spinlock implementation; required.  */
80 PT_EI long int testandset (int *spinlock)
81 {
82         unsigned psw;
83
84         /* disable interrupts */
85         __asm__ __volatile__ ("mfs      %0, rmsr;"
86                               "andi     r3, %0, ~2;"
87                                "mts     rmsr, r3;"
88                         : "=&r" (psw)
89                         :
90                         : "r3");
91
92         if (*spinlock)
93         {
94                 /* Enable ints */
95                 __asm__ __volatile__ ("mts      rmsr, %0;" :: "r" (psw));
96                 return 1;
97         } else {
98                 *spinlock=1;
99                 /* Enable ints */
100                 __asm__ __volatile__ ("mts      rmsr, %0;" :: "r" (psw));
101                 return 0;
102         }
103 }
104
105 #endif
106 #endif /* pt-machine.h */