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