0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <stdio.h>
0014 #include <unistd.h>
0015 #include <sys/syscall.h>
0016 #include <sys/time.h>
0017 #include <sys/types.h>
0018 #include <sys/wait.h>
0019 #include <stdlib.h>
0020 #include <pthread.h>
0021
0022 #include "utils.h"
0023
0024
0025 #define PREEMPT_TIME 20
0026
0027
0028
0029
0030 #define THREAD_FACTOR 8
0031
0032
0033 __thread double darray[] = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0,
0034 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0,
0035 2.1};
0036
0037 int threads_starting;
0038 int running;
0039
0040 extern void preempt_fpu(double *darray, int *threads_starting, int *running);
0041
0042 void *preempt_fpu_c(void *p)
0043 {
0044 int i;
0045 srand(pthread_self());
0046 for (i = 0; i < 21; i++)
0047 darray[i] = rand();
0048
0049
0050 preempt_fpu(darray, &threads_starting, &running);
0051
0052 return p;
0053 }
0054
0055 int test_preempt_fpu(void)
0056 {
0057 int i, rc, threads;
0058 pthread_t *tids;
0059
0060 threads = sysconf(_SC_NPROCESSORS_ONLN) * THREAD_FACTOR;
0061 tids = malloc((threads) * sizeof(pthread_t));
0062 FAIL_IF(!tids);
0063
0064 running = true;
0065 threads_starting = threads;
0066 for (i = 0; i < threads; i++) {
0067 rc = pthread_create(&tids[i], NULL, preempt_fpu_c, NULL);
0068 FAIL_IF(rc);
0069 }
0070
0071 setbuf(stdout, NULL);
0072
0073 printf("\tWaiting for all workers to start...");
0074 while(threads_starting)
0075 asm volatile("": : :"memory");
0076 printf("done\n");
0077
0078 printf("\tWaiting for %d seconds to let some workers get preempted...", PREEMPT_TIME);
0079 sleep(PREEMPT_TIME);
0080 printf("done\n");
0081
0082 printf("\tStopping workers...");
0083
0084
0085
0086
0087 running = 0;
0088 for (i = 0; i < threads; i++) {
0089 void *rc_p;
0090 pthread_join(tids[i], &rc_p);
0091
0092
0093
0094
0095
0096 if ((long) rc_p)
0097 printf("oops\n");
0098 FAIL_IF((long) rc_p);
0099 }
0100 printf("done\n");
0101
0102 free(tids);
0103 return 0;
0104 }
0105
0106 int main(int argc, char *argv[])
0107 {
0108 return test_harness(test_preempt_fpu, "fpu_preempt");
0109 }