OSDN Git Service

PR c++/29175
[pf3gnuchains/gcc-fork.git] / libjava / sysdep / sh / locks.h
1 // locks.h - Thread synchronization primitives. SuperH implementation.
2
3 /* Copyright (C) 2002  Free Software Foundation
4
5    This file is part of libgcj.
6
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
9 details.  */
10
11 #ifndef __SYSDEP_LOCKS_H__
12 #define __SYSDEP_LOCKS_H__
13
14 typedef size_t obj_addr_t;      /* Integer type big enough for object   */
15                                 /* address.                             */
16
17 static unsigned char __cas_lock = 0;
18
19 inline static void
20 __cas_start_atomic (void)
21 {
22   unsigned int val;
23
24   do
25     __asm__ __volatile__ ("tas.b @%1; movt %0"
26                           : "=r" (val)
27                           : "r" (&__cas_lock)
28                           : "memory");
29   while (val == 0);
30 }
31
32 inline static void
33 __cas_end_atomic (void)
34 {
35   __asm__ __volatile__ (" " : : : "memory");
36   __cas_lock = 0;
37 }
38
39 inline static bool
40 compare_and_swap (volatile obj_addr_t *addr, obj_addr_t old,
41                   obj_addr_t new_val)
42 {
43   bool ret;
44
45   __cas_start_atomic ();
46   if (*addr != old)
47     ret = false;
48   else
49     {
50       *addr = new_val;
51       ret = true;
52     }
53   __cas_end_atomic ();
54
55   return ret;
56 }
57
58 inline static void
59 release_set (volatile obj_addr_t *addr, obj_addr_t new_val)
60 {
61   __asm__ __volatile__ (" " : : : "memory");
62   *(addr) = new_val;
63 }
64
65 inline static bool
66 compare_and_swap_release (volatile obj_addr_t *addr, obj_addr_t old,
67                           obj_addr_t new_val)
68 {
69   return compare_and_swap (addr, old, new_val);
70 }
71
72 #endif /* ! __SYSDEP_LOCKS_H__ */