Update.
[platform/upstream/glibc.git] / linuxthreads / sysdeps / ia64 / pspinlock.c
1 /* POSIX spinlock implementation.  ia64 version.
2    Copyright (C) 2000 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Jes Sorensen <jes@linuxcare.com>
5
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Library General Public License as
8    published by the Free Software Foundation; either version 2 of the
9    License, or (at your option) any later version.
10
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Library General Public License for more details.
15
16    You should have received a copy of the GNU Library General Public
17    License along with the GNU C Library; see the file COPYING.LIB.  If not,
18    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19    Boston, MA 02111-1307, USA.  */
20
21 #include <errno.h>
22 #include <pthread.h>
23
24
25 /* This implementation is inspired by the implementation used in the
26    Linux kernel. */
27
28 int
29 __pthread_spin_lock (pthread_spinlock_t *lock)
30 {
31   asm volatile
32     ("mov ar.ccv = r0\n\t"
33      "mov r3 = 1\n\t"
34      ";;\n"
35      "1:\n\t"
36      "ld4 r2 = %0\n\t"
37      ";;\n\t"
38      "cmp4.eq p0, p7 = r0, r2\n\t"
39      "(p7) br.cond.spnt.few 1b \n\t"
40      "cmpxchg4.acq r2 = %0, r3, ar.ccv\n\t"
41      ";;\n\t"
42      "cmp4.eq p0, p7 = r0, r2\n\t"
43      "(p7) br.cond.spnt.few 1b\n\t"
44      ";;\n"
45      :: "m" (lock) : "r2", "r3", "p7", "memory");
46   return 0;
47 }
48 weak_alias (__pthread_spin_lock, pthread_spin_lock)
49
50
51 int
52 __pthread_spin_trylock (pthread_spinlock_t *lock)
53 {
54   int oldval;
55
56   asm volatile
57     ("mov ar.ccv = r0\n\t"
58      "mov r2 = 1\n\t"
59      ";;\n\t"
60      "cmpxchg4.acq %0 = %1, r2, ar.ccv\n\t"
61      ";;\n"
62      : "=r" (oldval) : "m" (lock) : "r2", "memory");
63   return oldval > 0 ? 0 : EBUSY;
64 }
65 weak_alias (__pthread_spin_trylock, pthread_spin_trylock)
66
67
68 int
69 __pthread_spin_unlock (pthread_spinlock_t *lock)
70 {
71   return *lock = 0;
72 }
73 weak_alias (__pthread_spin_unlock, pthread_spin_unlock)
74
75
76 int
77 __pthread_spin_init (pthread_spinlock_t *lock, int pshared)
78 {
79   /* We can ignore the `pshared' parameter.  Since we are busy-waiting
80      all processes which can access the memory location `lock' points
81      to can use the spinlock.  */
82   return *lock = 0;
83 }
84 weak_alias (__pthread_spin_init, pthread_spin_init)
85
86
87 int
88 __pthread_spin_destroy (pthread_spinlock_t *lock)
89 {
90   /* Nothing to do.  */
91   return 0;
92 }
93 weak_alias (__pthread_spin_destroy, pthread_spin_destroy)