blob: a4557891db9b480704d75beda3ed4959ce06f9f2 [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001/* Machine-dependent pthreads configuration and inline functions.
2 i386 version.
3 Copyright (C) 1996-2001, 2002, 2003 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
5 Contributed by Richard Henderson <rth@tamu.edu>.
6
7 The GNU C Library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public License as
9 published by the Free Software Foundation; either version 2.1 of the
10 License, or (at your option) any later version.
11
12 The GNU C Library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with the GNU C Library; see the file COPYING.LIB. If not,
19 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22#if defined __pentiumpro__ || defined __pentium4__ || defined __athlon__ || \
23 defined __k8__
24# include "i686/pt-machine.h"
25#else
26
27#ifndef _PT_MACHINE_H
28#define _PT_MACHINE_H 1
29
30#ifndef __ASSEMBLER__
31#ifndef PT_EI
32# define PT_EI __extern_always_inline
33#endif
34
35extern long int testandset (int *spinlock);
36extern int __compare_and_swap (long int *p, long int oldval, long int newval);
37
38/* Get some notion of the current stack. Need not be exactly the top
39 of the stack, just something somewhere in the current frame. */
40#define CURRENT_STACK_FRAME __builtin_frame_address (0)
41
42
43/* Spinlock implementation; required. */
44PT_EI long int
45testandset (int *spinlock)
46{
47 long int ret;
48
49 __asm__ __volatile__(
50 "xchgl %0, %1"
51 : "=r"(ret), "=m"(*spinlock)
52 : "0"(1), "m"(*spinlock)
53 : "memory");
54
55 return ret;
56}
57
58
59/* Compare-and-swap for semaphores.
60 Available on the 486 and above, but not on the 386.
61 We test dynamically whether it's available or not. */
62
63#define HAS_COMPARE_AND_SWAP
64#define TEST_FOR_COMPARE_AND_SWAP
65
66PT_EI int
67__compare_and_swap (long int *p, long int oldval, long int newval)
68{
69 char ret;
70 long int readval;
71
72 __asm__ __volatile__ ("lock; cmpxchgl %3, %1; sete %0"
73 : "=q" (ret), "=m" (*p), "=a" (readval)
74 : "r" (newval), "m" (*p), "a" (oldval)
75 : "memory");
76 return ret;
77}
78
79
80PT_EI int get_eflags (void);
81PT_EI int
82get_eflags (void)
83{
84 int res;
85 __asm__ __volatile__ ("pushfl; popl %0" : "=r" (res) : );
86 return res;
87}
88
89
90PT_EI void set_eflags (int newflags);
91PT_EI void
92set_eflags (int newflags)
93{
94 __asm__ __volatile__ ("pushl %0; popfl" : : "r" (newflags) : "cc");
95}
96
97
98PT_EI int compare_and_swap_is_available (void);
99PT_EI int
100compare_and_swap_is_available (void)
101{
102 int oldflags = get_eflags ();
103 int changed;
104 /* Flip AC bit in EFLAGS. */
105 set_eflags (oldflags ^ 0x40000);
106 /* See if bit changed. */
107 changed = (get_eflags () ^ oldflags) & 0x40000;
108 /* Restore EFLAGS. */
109 set_eflags (oldflags);
110 /* If the AC flag did not change, it's a 386 and it lacks cmpxchg.
111 Otherwise, it's a 486 or above and it has cmpxchg. */
112 return changed != 0;
113}
114#endif /* __ASSEMBLER__ */
115
116#endif /* pt-machine.h */
117
118#endif