Merge from vendor branch CVS:
[dragonfly.git] / test / stress / eattls.c
1 /*
2  * EATTLS.C
3  *
4  *      Rapidly switch between threads with different TLS pointers to
5  *      test that the operating system properly switches the TLS segment.
6  *
7  * $DragonFly: src/test/stress/eattls.c,v 1.1 2005/05/02 19:33:52 dillon Exp $
8  */
9
10 #include <sys/types.h>
11 #include <sys/tls.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <unistd.h>
15
16 #define BIGSIZE (16 * 1024 * 1024)
17
18 struct test {
19         int random1;
20         int random2;
21 };
22
23 static int getdata(int offset);
24
25 int
26 main(int ac, char **av)
27 {
28     struct tls_info info;
29     struct test *test;
30     char *buf;
31     int gs;
32     int random1;
33     int random2;
34
35     srandomdev();
36     random1 = random();
37     random2 = random();
38
39     buf = malloc(BIGSIZE);
40     buf += random() % (BIGSIZE - sizeof(struct test));
41     test = (void *)buf;
42     info.base = buf;
43     info.size = sizeof(struct test);
44     if ((gs = sys_set_tls_area(2, &info, sizeof(info))) < 0) {
45         perror("sys_set_tls_area");
46         exit(1);
47     }
48     test->random1 = random1;
49     test->random2 = random2;
50     printf("setting %%gs to 0x%02x segment at %p\n", gs, test);
51     __asm __volatile("movl %0,%%eax; movl %%eax,%%gs" : "=m" (gs) : : "ax");
52     for (;;) {
53         if (getdata(0) != random1 || getdata(4) != random2)
54             printf("data verification failed!\n");
55         if (random() % 1000 > 500)
56             usleep(random() % 1000);
57     }
58
59     return(0);
60 }
61
62 static int
63 getdata(int offset)
64 {
65     int rv;
66     __asm __volatile("movl %%gs:(%0),%%eax; movl %%eax,%1" : 
67                      "+r" (offset) : "m" (rv) : "ax");
68     return (rv);
69 }
70