14 int debug_offset(void)
17 pthread_t self = pthread_self();
18 for (i = 0; i < 4; ++i)
26 printf(" spin %d : %ld\n", debug_offset(), lock);
31 printf(" lock %d : %ld\n", debug_offset(), lock);
34 void debug_unlock(void)
36 printf("unlock %d : %ld\n", debug_offset(), lock);
38 #define DEBUG_SPIN() jit_calli(debug_spin)
39 #define DEBUG_LOCK() jit_calli(debug_lock)
40 #define DEBUG_UNLOCK() jit_calli(debug_unlock)
42 #define DEBUG_SPIN() /**/
43 #define DEBUG_LOCK() /**/
44 #define DEBUG_UNLOCK() /**/
47 void alarm_handler(int unused)
53 main(int argc, char *argv[])
57 jit_node_t *jmpi_main, *label;
58 jit_node_t *func0, *func1, *func2, *func3;
59 jit_node_t *patch0, *patch1, *patch2, *patch3;
61 /* If there is any bug, do not hang in "make check" */
62 signal(SIGALRM, alarm_handler);
66 _jit = jit_new_state();
68 jmpi_main = jit_jmpi();
70 #define defun(name, line) \
72 jit_note("catomic.c", line); \
75 jit_movi(JIT_V0, (jit_word_t)&lock); \
76 jit_movi(JIT_V1, 0); \
77 jit_movi(JIT_V2, line); \
78 /* spin until get the lock */ \
80 label = jit_label(); \
81 jit_casr(JIT_R0, JIT_V0, JIT_V1, JIT_V2); \
82 jit_patch_at(jit_beqi(JIT_R0, 0), label); \
86 /* pretend to be doing something useful for 0.01 sec
87 * while holding the lock */ \
88 jit_pushargi(10000); \
89 jit_finishi(usleep); \
92 jit_movi(JIT_V1, 0); \
93 jit_str(JIT_V0, JIT_V1); \
95 jit_movi(JIT_V1, 0); \
96 jit_movi(JIT_V2, line); \
97 /* spin until get the lock */ \
99 label = jit_label(); \
100 jit_casi(JIT_R0, (jit_word_t)&lock, JIT_V1, JIT_V2); \
101 jit_patch_at(jit_beqi(JIT_R0, 0), label); \
102 /* lock acquired */ \
105 /* pretend to be doing something useful for 0.01 sec
106 * while holding the lock */ \
107 jit_pushargi(10000); \
108 jit_finishi(usleep); \
110 /* for make check, just print "ok" */ \
111 jit_pushargi((jit_word_t)"ok"); \
112 /*jit_pushargi((jit_word_t)#name);*/ \
116 jit_movi(JIT_V1, 0); \
117 jit_str(JIT_V0, JIT_V1); \
120 defun(func0, __LINE__);
121 defun(func1, __LINE__);
122 defun(func2, __LINE__);
123 defun(func3, __LINE__);
125 jit_patch(jmpi_main);
127 jit_note("catomic.c", __LINE__);
131 /* set JIT_R0 to thread function */ \
132 jit_patch_at(jit_movi(JIT_R0, 0), func##tid); \
134 /* pthread_t first argument */ \
135 jit_pushargi((jit_word_t)(tids + tid)); \
136 /* pthread_attr_t second argument */ \
137 jit_pushargi((jit_word_t)NULL); \
138 /* start routine third argument */ \
139 jit_pushargr(JIT_R0); \
140 /* argument to start routine fourth argument */ \
141 jit_pushargi((jit_word_t)NULL); \
143 jit_finishi(pthread_create);
144 /* spawn four threads */
151 /* load pthread_t value in JIT_R0 */ \
152 jit_movi(JIT_R0, (jit_word_t)tids); \
153 jit_ldxi(JIT_R0, JIT_R0, tid * sizeof(pthread_t)); \
155 jit_pushargr(JIT_R0); \
156 jit_pushargi((jit_word_t)NULL); \
157 jit_finishi(pthread_join);
158 /* wait for threads to finish */
165 jit_pushargi((jit_word_t)"ok");
179 /* let first thread acquire the lock */