git subrepo pull --force deps/lightrec
[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
7void alarm_handler(int unused)
8{
9 _exit(1);
10}
11
12int
13main(int argc, char *argv[])
14{
15 jit_state_t *_jit;
16 void (*code)(void);
17 jit_node_t *jmpi_main, *label;
18 jit_node_t *func0, *func1, *func2, *func3;
19 jit_node_t *patch0, *patch1, *patch2, *patch3;
20 jit_word_t lock;
21 pthread_t tids[4];
22
23 /* If there is any bug, do not hang in "make check" */
24 signal(SIGALRM, alarm_handler);
25 alarm(5);
26
27 init_jit(argv[0]);
28 _jit = jit_new_state();
29
30 jmpi_main = jit_jmpi();
31
32#define defun(name, line) \
33 jit_name(#name); \
34 jit_note("catomic.c", line); \
35 name = jit_label(); \
36 jit_prolog(); \
37 jit_movi(JIT_V0, (jit_word_t)&lock); \
38 jit_movi(JIT_R1, 0); \
39 jit_movi(JIT_R2, line); \
40 /* spin until get the lock */ \
41 label = jit_label(); \
42 jit_casr(JIT_R0, JIT_V0, JIT_R1, JIT_R2); \
43 jit_patch_at(jit_beqi(JIT_R0, 0), label); \
44 /* lock acquired */ \
45 jit_prepare(); \
46 /* pretend to be doing something useful for 0.01 usec
47 * while holding the lock */ \
48 jit_pushargi(10000); \
49 jit_finishi(usleep); \
50 /* release lock */ \
51 jit_movi(JIT_R1, 0); \
52 jit_str(JIT_V0, JIT_R1); \
53 /* Now test casi */ \
54 jit_movi(JIT_R1, 0); \
55 jit_movi(JIT_R2, line); \
56 /* spin until get the lock */ \
57 label = jit_label(); \
58 jit_casi(JIT_R0, (jit_word_t)&lock, JIT_R1, JIT_R2); \
59 jit_patch_at(jit_beqi(JIT_R0, 0), label); \
60 /* lock acquired */ \
61 jit_prepare(); \
62 /* pretend to be doing something useful for 0.01 usec
63 * while holding the lock */ \
64 jit_pushargi(10000); \
65 jit_finishi(usleep); \
66 jit_prepare(); \
67 /* for make check, just print "ok" */ \
68 jit_pushargi((jit_word_t)"ok"); \
69 /*jit_pushargi((jit_word_t)#name);*/ \
70 jit_finishi(puts); \
71 /* release lock */ \
72 jit_movi(JIT_R1, 0); \
73 jit_str(JIT_V0, JIT_R1); \
74 jit_ret(); \
75 jit_epilog();
76 defun(func0, __LINE__);
77 defun(func1, __LINE__);
78 defun(func2, __LINE__);
79 defun(func3, __LINE__);
80
81 jit_patch(jmpi_main);
82 jit_name("main");
83 jit_note("catomic.c", __LINE__);
84 jit_prolog();
85
86#define start(tid) \
87 /* set JIT_R0 to thread function */ \
88 jit_patch_at(jit_movi(JIT_R0, 0), func##tid); \
89 jit_prepare(); \
90 /* pthread_t first argument */ \
91 jit_pushargi((jit_word_t)(tids + tid)); \
92 /* pthread_attr_t second argument */ \
93 jit_pushargi((jit_word_t)NULL); \
94 /* start routine third argument */ \
95 jit_pushargr(JIT_R0); \
96 /* argument to start routine fourth argument */ \
97 jit_pushargi((jit_word_t)NULL); \
98 /* start thread */ \
99 jit_finishi(pthread_create);
100 /* spawn four threads */
101 start(0);
102 start(1);
103 start(2);
104 start(3);
105
106#define join(tid) \
107 /* load pthread_t value in JIT_R0 */ \
108 jit_movi(JIT_R0, (jit_word_t)tids); \
109 jit_ldxi(JIT_R0, JIT_R0, tid * sizeof(pthread_t)); \
110 jit_prepare(); \
111 jit_pushargr(JIT_R0); \
112 jit_pushargi((jit_word_t)NULL); \
113 jit_finishi(pthread_join);
114 /* wait for threads to finish */
115 join(0);
116 join(1);
117 join(2);
118 join(3);
119
120 jit_prepare();
121 jit_pushargi((jit_word_t)"ok");
122 jit_finishi(puts);
123
124 jit_ret();
125 jit_epilog();
126
127 code = jit_emit();
128
129#if 1
130 jit_disassemble();
131#endif
132
133 jit_clear_state();
134
135 /* let first thread acquire the lock */
136 lock = 0;
137
138 (*code)();
139 jit_destroy_state();
140
141 finish_jit();
142
143 return (0);
144}