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