]> git.saurik.com Git - apple/xnu.git/blob - tools/tests/unit_tests/monitor_stress_12901965_src/monitor_stress/monitor_stress.m
267bb86c58fc1810bcb057658868993fe385783a
[apple/xnu.git] / tools / tests / unit_tests / monitor_stress_12901965_src / monitor_stress / monitor_stress.m
1 #define TARGET_OS_EMBEDDED 1
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <unistd.h>
5 #include <time.h>
6 #include <pthread.h>
7 #include <libgen.h>
8 #include <sys/types.h>
9 #include <sys/sysctl.h>
10
11 #import <Foundation/Foundation.h>
12
13 #include <mach/message.h>
14 #include <libproc_internal.h>
15
16 #define MAX_THREADS 100
17
18 char *pname;
19
20 int pid;
21
22 int exit_after = -1;
23
24 int percentage = 95, interval = 600;
25
26 int wakemon_rate = 150;
27
28 int limit = 0; // Worker thread should apply per-thread limit to self?
29 int limit_period = 5000;
30
31 void usage(void) {
32 printf("usage: monitor_stress [ -c nthreads ] [ -w nthreads ] \n");
33 printf("\t-c: number of CPU usage monitor stress threads to use (default: 2\n");
34 printf("\t-w: number of wakeups monitor stress threads to use (default: 0\n");
35 printf("\t-e: exit after this many seconds (default: run forever)\n");
36 printf("\t-p: act on this pid (default: self)\n");
37 }
38
39 void *perthr_limit_thread(void *arg)
40 {
41 int percent = 90, refill_period = 30; // time unit is milliseconds
42 int err;
43 int cpupercent;
44
45 top:
46 cpupercent = percent | (refill_period << 8);
47
48 if ((err = sysctlbyname("kern.setthread_cpupercent", 0, 0,
49 &cpupercent, sizeof (int))) != 0) {
50 printf("kern.setthread_cpupercent: error %d\n", err);
51 exit(1);
52 }
53 goto top;
54 }
55
56 void *cpumon_stress_thread(void *arg)
57 {
58 top:
59 if (proc_set_cpumon_params(pid, percentage, interval) != 0) {
60 perror("proc_set_cpumon_params");
61 exit(1);
62 }
63 if (proc_disable_cpumon(pid) != 0) {
64 perror("proc_disable_cpumon");
65 exit(1);
66 }
67 goto top;
68 }
69
70 void *wakemon_stress_thread(void *arg)
71 {
72 top:
73 if (proc_set_wakemon_params(pid, wakemon_rate, 0) != 0) {
74 perror("proc_set_wakemon_params");
75 exit(1);
76 }
77 if (proc_disable_wakemon(pid) != 0) {
78 perror("proc_disable_wakemon");
79 exit(1);
80 }
81 goto top;
82 }
83
84 void *exit_thread(void *arg)
85 {
86 sleep(exit_after);
87 printf("...exiting.\n");
88 exit(0);
89
90 return (NULL);
91 }
92
93 int main(int argc, char *argv[])
94 {
95 int ch;
96 int i = 0;
97 int cpumon_threads = 2;
98 int wakemon_threads = 0;
99
100 pthread_t thr_id;
101
102 pname = basename(argv[0]);
103 pid = getpid();
104
105 while ((ch = getopt(argc, argv, "c:w:e:p:h?")) != -1) {
106 switch (ch) {
107 case 'c':
108 cpumon_threads = atoi(optarg);
109 break;
110 case 'w':
111 wakemon_threads = atoi(optarg);
112 break;
113 case 'e':
114 exit_after = atoi(optarg);
115 break;
116 case 'p':
117 pid = atoi(optarg);
118 break;
119 case 'h':
120 default:
121 usage();
122 exit(1);
123
124 }
125 }
126 argc -= optind;
127 argv += optind;
128
129 if (argc != 0) {
130 usage();
131 exit(1);
132 }
133
134 if ((cpumon_threads <= 0) || (cpumon_threads > MAX_THREADS) ||
135 (wakemon_threads < 0) || (wakemon_threads > MAX_THREADS)) {
136 printf("%s: %d/%d threads too many (max is %d)\n", pname,
137 cpumon_threads, wakemon_threads, MAX_THREADS);
138 exit(1);
139 }
140
141 printf("%s: creating %d CPU usage monitor stress threads (1 will be main thread), ", pname, cpumon_threads);
142 if (wakemon_threads > 0) {
143 printf( "%d wakeups monitor stress threads, ", wakemon_threads);
144 }
145 printf("and 1 per-thread CPU limit stress thread.\n");
146
147 if (pthread_create(&thr_id, NULL, perthr_limit_thread, NULL) != 0) {
148 perror("pthread_create");
149 exit(1);
150 }
151
152 for (i = 0; i < wakemon_threads; i++) {
153 if (pthread_create(&thr_id, NULL, wakemon_stress_thread, NULL) != 0) {
154 perror("pthread_create");
155 exit(1);
156 }
157 }
158
159 // main thread will be used as stress thread too, so start count at 1
160 for (i = 1; i < cpumon_threads; i++) {
161 if (pthread_create(&thr_id, NULL, cpumon_stress_thread, NULL) != 0) {
162 perror("pthread_create");
163 exit(1);
164 }
165 }
166
167 if (exit_after >= 0) {
168 printf("%s: will exit after %d seconds\n", pname, exit_after);
169 if (pthread_create(&thr_id, NULL, exit_thread, NULL) != 0) {
170 perror("pthread_create");
171 exit(1);
172 }
173 }
174
175 cpumon_stress_thread(NULL);
176
177 return (0);
178 }