18 void item_calculate(struct item *item) {
19 item->seed_sin = sin(item->seed | 1);
20 item->seed_times_sin = (double)(item->seed | 1) * item->seed_sin;
21 item->seed_xor_times = item->seed ^ item->seed_times_sin;
24 int item_verify(struct item *item) {
31 printf("seed %ld, sin: %lf, times: %ld, xor: %ld\n",
32 item->seed, item->seed_sin, item->seed_times_sin, item->seed_xor_times);
35 if (t.seed_sin != item->seed_sin ||
36 t.seed_times_sin != item->seed_times_sin ||
37 t.seed_xor_times != item->seed_xor_times) {
38 printf("seed %ld, sin: %lf, times: %ld, xor: %ld\n",
39 item->seed, item->seed_sin, item->seed_times_sin, item->seed_xor_times);
46 int basic_sanity_test(struct xq *q) {
49 //printf("append_tail 9183\n");
50 r = xq_append_tail(q, 9183);
55 //printf("pop_head 9183\n");
61 //printf("append_head 1834\n");
62 r = xq_append_head(q, 1834);
67 //printf("pop_tail 1834\n");
73 //printf("append_tail 3814\n");
74 xq_append_tail(q, 3814);
78 //printf("append_head 5294\n");
79 xq_append_head(q, 5294);
83 //printf("append_tail 1983\n");
84 r = xq_append_tail(q, 1983);
89 //printf("pop_tail 1983\n");
95 //printf("append_head 8134\n");
96 r = xq_append_head(q, 8134);
101 //printf("pop_head 8134\n");
107 //printf("pop_tail 3814\n");
113 //printf("pop_head 5294\n");
119 //printf("pop_tail None\n");
125 //printf("pop_head None\n");
131 xqindex qsize = q->size;
132 for (t = 0; t < qsize; t += 1) {
133 r = xq_append_tail(q, t);
134 //if (r == None) printf("None: %lu\n", (unsigned long)t);
141 for (t = qsize-1; t != None; t -= 1) {
144 //printf("%lu vs %lu\n", t, (unsigned long)xq_pop_tail(q));
154 struct random_data *rdata;
159 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
161 void *random_test_thread(void *arg) {
162 struct thread_data *th = arg;
163 long loops = th->loops;
164 struct xq *q = th->q;
165 struct item *items = th->items;
166 //struct random_data *rdata = th->rdata;
172 pthread_mutex_lock(&mutex);
177 pthread_mutex_unlock(&mutex);
180 for (i = 0; i < loops; i++) {
184 if ((i & (1024*1024 -1)) == 0) {
185 printf("%d %ld\n", id, i);
188 //random_r(rdata, &rand);
193 xqi = xq_pop_tail(&q[0]);
194 if (xqi == None) goto unlock;
195 items[xqi].seed = rand;
196 item_calculate(&items[xqi]);
197 xq_append_head(&q[1], xqi);
200 xqi = xq_pop_head(&q[0]);
201 if (xqi == None) goto unlock;
202 items[xqi].seed = rand;
203 item_calculate(&items[xqi]);
204 xq_append_tail(&q[1], xqi);
207 xqi = xq_pop_tail(&q[1]);
208 if (xqi == None) goto unlock;
209 items[xqi].seed = rand;
210 item_calculate(&items[xqi]);
211 xq_append_head(&q[0], xqi);
214 xqi = xq_pop_head(&q[1]);
215 if (xqi == None) goto unlock;
216 items[xqi].seed = rand;
217 item_calculate(&items[xqi]);
218 xq_append_tail(&q[0], xqi);
228 int error(const char *msg) {
233 int random_test(long seed, long nr_threads, long loops, xqindex qsize, struct xq *q) {
236 struct thread_data *th = malloc(nr_threads * sizeof(struct thread_data));
237 if (!th) return error("malloc");
241 struct item *items = malloc(qsize * sizeof(struct item));
242 if (!items) return error("malloc");
244 for (t = 0; t < qsize; t += 1) item_calculate(&items[t]);
246 for (t = 0; t < qsize; t += 4) {
247 xq_append_tail(&q[0], t+0);
248 xq_append_head(&q[0], t+1);
249 xq_append_tail(&q[1], t+2);
250 xq_append_head(&q[1], t+3);
253 pthread_t *threads = malloc(nr_threads * sizeof(pthread_t));
254 if (!threads) return error("malloc");
256 //struct random_data *rdata = malloc(nr_threads * sizeof(struct random_data));
257 //if (!rdata) return error("malloc");
259 for (t = 0; t < nr_threads; t++) {
264 //th[t].rdata = &rdata[t];
266 //srandom_r(random(), th[t].rdata);
269 for (t = 0; t < nr_threads; t++) {
270 r = pthread_create(&threads[t], NULL, random_test_thread, &th[t]);
271 if (r) return error("pthread_create");
274 for (t = 0; t < nr_threads; t++) {
275 pthread_join(threads[t], NULL);
279 for (t = 0; t < qsize; t++) {
280 if (!item_verify(&items[t])) {
282 printf("error: item %ld\n", t);
291 int main(int argc, char **argv) {
295 printf("Usage: struct xqest <seed> <nr_threads> <nr_loops> <qsize>\n");
299 long seed = atol(argv[1]);
300 int nr_threads = atoi(argv[2]);
301 long loops = atol(argv[3]);
302 long qsize = atol(argv[4]);
304 if (nr_threads < 0) nr_threads = 2;
305 if (loops < 0) loops = 1000;
306 if (qsize < 0) qsize = 1000;
308 xq_alloc_empty(&q[0], qsize);
309 xq_alloc_empty(&q[1], qsize);
311 assert(q[1].size == qsize);
313 r = basic_sanity_test(&q[0]);
315 printf("basic sanity test complete.\n");
317 struct timeval tv0, tv1;
318 gettimeofday(&tv0, NULL);
319 r = random_test(seed, nr_threads, loops, qsize, q);
320 gettimeofday(&tv1, NULL);
321 double seconds = tv1.tv_sec + tv1.tv_usec/1000000.0 - tv0.tv_sec - tv0.tv_usec / 1000000.0;
322 printf("random multi-thread test complete with %d errors in %lf seconds\n", r, seconds);