1 /*
2  * Copyright (C) 2016-2017 Andes Technology, Inc.
3  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
4  */
5 
6 /* POSIX spinlock implementation.
7    Copyright (C) 2000 Free Software Foundation, Inc.
8 
9    The GNU C Library is free software; you can redistribute it and/or
10    modify it under the terms of the GNU Lesser General Public License as
11    published by the Free Software Foundation; either version 2.1 of the
12    License, or (at your option) any later version.
13 
14    The GNU C Library is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17    Lesser General Public License for more details.
18 
19    You should have received a copy of the GNU Lesser General Public
20    License along with the GNU C Library; see the file COPYING.LIB.  If not,
21    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22    Boston, MA 02111-1307, USA.  */
23 
24 #include <errno.h>
25 #include <pthread.h>
26 #include "internals.h"
27 
28 int
__pthread_spin_lock(pthread_spinlock_t * lock)29 __pthread_spin_lock (pthread_spinlock_t *lock)
30 {
31 	unsigned int		val ;
32 	unsigned int		temp ;
33 	unsigned int		offset = 0 ;
34 
35 	__asm__ __volatile__ (
36 		"1:\n\t"
37 		"llw	%0,	[%1 + %2 << 0]\n\t"
38 		"bnez	%0, 1b\n\t"
39 		"movi	%3, #0x1\n\t"
40 		"scw	%3,	[%1 + %2 << 0]\n\t"
41 		"beqz	%3, 1b\n\t"
42 		: "=&r" (val)
43 		: "r" (lock), "r" (offset), "r" (temp)
44 		: "memory" ) ;
45 
46 	return 0 ;
47 }
weak_alias(__pthread_spin_lock,pthread_spin_lock)48 weak_alias (__pthread_spin_lock, pthread_spin_lock)
49 
50 
51 int
52 __pthread_spin_trylock (pthread_spinlock_t *lock)
53 {
54 	unsigned int		val ;
55 	unsigned int		temp ;
56 	unsigned int		offset = 0 ;
57 
58 	__asm__ __volatile__ (
59 		"llw	%0,	[%1 + %2 << 0]\n\t"
60 		"bnez	%0, 1f\n\t"
61 		"movi	%3, #0x1\n\t"
62 		"scw	%3,	[%1 + %2 << 0]\n\t"
63 		"beqz	%3, 1f\n\t"
64 		"movi	%0, #0x0\n\t"
65 		"b	2f\n\t"
66 		"1:\n\t"
67 		"movi	%0, #16\n\t"
68 		"2:\n\t"
69 		: "=&r" (val)
70 		: "r" (lock), "r" (offset), "r" (temp)
71 		: "memory" ) ;
72 
73   return val;
74 }
weak_alias(__pthread_spin_trylock,pthread_spin_trylock)75 weak_alias (__pthread_spin_trylock, pthread_spin_trylock)
76 
77 int
78 __pthread_spin_unlock (pthread_spinlock_t *lock)
79 {
80   return *lock = 0;
81 }
weak_alias(__pthread_spin_unlock,pthread_spin_unlock)82 weak_alias (__pthread_spin_unlock, pthread_spin_unlock)
83 
84 
85 int
86 __pthread_spin_init (pthread_spinlock_t *lock, int pshared)
87 {
88   /* We can ignore the `pshared' parameter.  Since we are busy-waiting
89      all processes which can access the memory location `lock' points
90      to can use the spinlock.  */
91   return *lock = 0;
92 }
weak_alias(__pthread_spin_init,pthread_spin_init)93 weak_alias (__pthread_spin_init, pthread_spin_init)
94 
95 
96 int
97 __pthread_spin_destroy (pthread_spinlock_t *lock)
98 {
99   /* Nothing to do.  */
100   return 0;
101 }
102 weak_alias (__pthread_spin_destroy, pthread_spin_destroy)
103