git subrepo pull (merge) --force deps/lightning
[pcsx_rearmed.git] / deps / lightning / check / catomic.c
CommitLineData
ba3814c1
PC
1#include <lightning.h>
2#include <pthread.h>
3#include <stdio.h>
4#include <unistd.h>
5#include <signal.h>
6
ba86ff93
PC
7/* FIXME Remove the "0 &&" below to make the test pass.
8 * This should not be a Lightning issue. It is crashing
9 * like this at exit:
10 * Thread 2 "catomic" received signal SIGSEGV, Segmentation fault.
11 * [Switching to Thread 0xf6acc480 (LWP 2561)]
12 * _IO_acquire_lock_fct (p=<synthetic pointer>) at libioP.h:797
13 * 797 libioP.h: No such file or directory.
14 * (gdb) bt
15 * #0 _IO_acquire_lock_fct (p=<synthetic pointer>) at libioP.h:797
16 * #1 _IO_puts (str=0x1 <error: Cannot access memory at address 0x1>)
17 * at ioputs.c:36
18 * #2 0xf8eca180 in ?? ()
19 * unless using these hacks, to not use stdio.
20 * Note that the problem will still happen on purpose, to not risk hiding
21 * a problem.
22 */
23#if 0 && defined(__hppa__)
24# if DEBUG
25# define DEBUG 0
26# define PRINT_OK() \
27 do { \
28 jit_prepare(); \
29 jit_pushargi(STDOUT_FILENO); \
30 jit_pushargi((jit_word_t)"ok\n"); \
31 jit_pushargri(3); \
32 jit_finishi(write); \
33 } while (0)
34# endif
35#else
36# define PRINT_OK() \
37 do { \
38 jit_prepare(); \
39 jit_pushargi((jit_word_t)"ok"); \
40 jit_finishi(puts); \
41 } while (0)
42#endif
43
c0c16242
PC
44#if DEBUG
45volatile
46#endif
47jit_word_t lock;
48pthread_t tids[4];
49
50#if DEBUG
51int debug_offset(void)
52{
53 int i;
54 pthread_t self = pthread_self();
55 for (i = 0; i < 4; ++i)
56 if (tids[i] == self)
57 return i;
58 return -1;
59}
60
61void debug_spin(void)
62{
63 printf(" spin %d : %ld\n", debug_offset(), lock);
64}
65
66void debug_lock(void)
67{
68 printf(" lock %d : %ld\n", debug_offset(), lock);
69}
70
71void debug_unlock(void)
72{
73 printf("unlock %d : %ld\n", debug_offset(), lock);
74}
75#define DEBUG_SPIN() jit_calli(debug_spin)
76#define DEBUG_LOCK() jit_calli(debug_lock)
77#define DEBUG_UNLOCK() jit_calli(debug_unlock)
78#else
79#define DEBUG_SPIN() /**/
80#define DEBUG_LOCK() /**/
81#define DEBUG_UNLOCK() /**/
82#endif
83
ba3814c1
PC
84void alarm_handler(int unused)
85{
86 _exit(1);
87}
88
89int
90main(int argc, char *argv[])
91{
92 jit_state_t *_jit;
93 void (*code)(void);
94 jit_node_t *jmpi_main, *label;
95 jit_node_t *func0, *func1, *func2, *func3;
96 jit_node_t *patch0, *patch1, *patch2, *patch3;
ba3814c1
PC
97
98 /* If there is any bug, do not hang in "make check" */
99 signal(SIGALRM, alarm_handler);
100 alarm(5);
101
102 init_jit(argv[0]);
103 _jit = jit_new_state();
104
105 jmpi_main = jit_jmpi();
106
107#define defun(name, line) \
108 jit_name(#name); \
109 jit_note("catomic.c", line); \
110 name = jit_label(); \
111 jit_prolog(); \
112 jit_movi(JIT_V0, (jit_word_t)&lock); \
c0c16242
PC
113 jit_movi(JIT_V1, 0); \
114 jit_movi(JIT_V2, line); \
ba3814c1 115 /* spin until get the lock */ \
c0c16242 116 DEBUG_SPIN(); \
ba3814c1 117 label = jit_label(); \
c0c16242 118 jit_casr(JIT_R0, JIT_V0, JIT_V1, JIT_V2); \
ba3814c1
PC
119 jit_patch_at(jit_beqi(JIT_R0, 0), label); \
120 /* lock acquired */ \
c0c16242 121 DEBUG_LOCK(); \
ba3814c1 122 jit_prepare(); \
c0c16242 123 /* pretend to be doing something useful for 0.01 sec
ba3814c1
PC
124 * while holding the lock */ \
125 jit_pushargi(10000); \
126 jit_finishi(usleep); \
127 /* release lock */ \
c0c16242
PC
128 DEBUG_UNLOCK(); \
129 jit_movi(JIT_V1, 0); \
130 jit_str(JIT_V0, JIT_V1); \
ba3814c1 131 /* Now test casi */ \
c0c16242
PC
132 jit_movi(JIT_V1, 0); \
133 jit_movi(JIT_V2, line); \
ba3814c1 134 /* spin until get the lock */ \
c0c16242 135 DEBUG_SPIN(); \
ba3814c1 136 label = jit_label(); \
c0c16242 137 jit_casi(JIT_R0, (jit_word_t)&lock, JIT_V1, JIT_V2); \
ba3814c1
PC
138 jit_patch_at(jit_beqi(JIT_R0, 0), label); \
139 /* lock acquired */ \
c0c16242 140 DEBUG_LOCK(); \
ba3814c1 141 jit_prepare(); \
c0c16242 142 /* pretend to be doing something useful for 0.01 sec
ba3814c1
PC
143 * while holding the lock */ \
144 jit_pushargi(10000); \
145 jit_finishi(usleep); \
ba86ff93 146 PRINT_OK(); \
ba3814c1 147 /* release lock */ \
c0c16242
PC
148 DEBUG_UNLOCK(); \
149 jit_movi(JIT_V1, 0); \
150 jit_str(JIT_V0, JIT_V1); \
ba3814c1
PC
151 jit_ret(); \
152 jit_epilog();
153 defun(func0, __LINE__);
154 defun(func1, __LINE__);
155 defun(func2, __LINE__);
156 defun(func3, __LINE__);
157
158 jit_patch(jmpi_main);
159 jit_name("main");
160 jit_note("catomic.c", __LINE__);
161 jit_prolog();
162
163#define start(tid) \
164 /* set JIT_R0 to thread function */ \
165 jit_patch_at(jit_movi(JIT_R0, 0), func##tid); \
166 jit_prepare(); \
167 /* pthread_t first argument */ \
168 jit_pushargi((jit_word_t)(tids + tid)); \
169 /* pthread_attr_t second argument */ \
170 jit_pushargi((jit_word_t)NULL); \
171 /* start routine third argument */ \
172 jit_pushargr(JIT_R0); \
173 /* argument to start routine fourth argument */ \
174 jit_pushargi((jit_word_t)NULL); \
175 /* start thread */ \
176 jit_finishi(pthread_create);
177 /* spawn four threads */
178 start(0);
179 start(1);
180 start(2);
181 start(3);
182
183#define join(tid) \
184 /* load pthread_t value in JIT_R0 */ \
185 jit_movi(JIT_R0, (jit_word_t)tids); \
79bfeef6
PC
186 if (__WORDSIZE == 64 && sizeof(pthread_t) == 4) \
187 jit_ldxi_i(JIT_R0, JIT_R0, tid * sizeof(pthread_t)); \
188 else \
189 jit_ldxi(JIT_R0, JIT_R0, tid * sizeof(pthread_t)); \
ba3814c1
PC
190 jit_prepare(); \
191 jit_pushargr(JIT_R0); \
192 jit_pushargi((jit_word_t)NULL); \
193 jit_finishi(pthread_join);
194 /* wait for threads to finish */
195 join(0);
196 join(1);
197 join(2);
198 join(3);
199
ba86ff93 200 PRINT_OK();
ba3814c1
PC
201
202 jit_ret();
203 jit_epilog();
204
205 code = jit_emit();
206
c0c16242 207#if DEBUG
ba3814c1
PC
208 jit_disassemble();
209#endif
210
211 jit_clear_state();
212
213 /* let first thread acquire the lock */
214 lock = 0;
215
216 (*code)();
217 jit_destroy_state();
218
219 finish_jit();
220
221 return (0);
222}