1 /* Machine-dependent pthreads configuration and inline functions.
2 *
3 * Copyright (C) 2005-2007 Atmel Corporation
4 *
5 * This file is subject to the terms and conditions of the GNU Lesser General
6 * Public License. See the file "COPYING.LIB" in the main directory of this
7 * archive for more details.
8 */
9 #ifndef _PT_MACHINE_H
10 #define _PT_MACHINE_H 1
11
12 #include <features.h>
13
14 #ifndef PT_EI
15 # define PT_EI __extern_always_inline
16 #endif
17
18 static __inline__ int
_test_and_set(int * p,int v)19 _test_and_set (int *p, int v)
20 {
21 int result;
22
23 __asm__ __volatile__(
24 "/* Inline test and set */\n"
25 " xchg %[old], %[mem], %[new]"
26 : [old] "=&r"(result)
27 : [mem] "r"(p), [new] "r"(v)
28 : "memory");
29
30 return result;
31 }
32
33 extern long int testandset (int *spinlock);
34 extern int __compare_and_swap (long int *p, long int oldval, long int newval);
35
36 /* Spinlock implementation; required. */
37 PT_EI long int
testandset(int * spinlock)38 testandset (int *spinlock)
39 {
40 return _test_and_set(spinlock, 1);
41 }
42
43
44 /* Get some notion of the current stack. Need not be exactly the top
45 of the stack, just something somewhere in the current frame. */
46 #define CURRENT_STACK_FRAME stack_pointer
47 register char * stack_pointer __asm__ ("sp");
48
49 /* Compare-and-swap for semaphores. */
50
51 #define HAS_COMPARE_AND_SWAP
52 PT_EI int
__compare_and_swap(long int * p,long int oldval,long int newval)53 __compare_and_swap(long int *p, long int oldval, long int newval)
54 {
55 long int result;
56
57 __asm__ __volatile__(
58 "/* Inline compare and swap */\n"
59 "1: ssrf 5\n"
60 " ld.w %[result], %[mem]\n"
61 " eor %[result], %[old]\n"
62 " brne 2f\n"
63 " stcond %[mem], %[new]\n"
64 " brne 1b\n"
65 "2:"
66 : [result] "=&r"(result), [mem] "=m"(*p)
67 : "m"(*p), [new] "r"(newval), [old] "r"(oldval)
68 : "cc", "memory");
69
70 return result == 0;
71 }
72
73 #endif /* pt-machine.h */
74