blob: e8c03f9e531158f629cf4aa2bc068e9affb53a6f [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001/*
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
24extern long int testandset (int *spinlock);
25extern 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
30register 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. */
38PT_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>) */
69PT_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. */
80PT_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 */