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 18char *pname; 19 20int pid; 21 22int exit_after = -1; 23 24int percentage = 95, interval = 600; 25 26int wakemon_rate = 150; 27 28int limit = 0; // Worker thread should apply per-thread limit to self? 29int limit_period = 5000; 30 31void 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 39void *perthr_limit_thread(void *arg) 40{ 41 int percent = 90, refill_period = 30; // time unit is milliseconds 42 int err; 43 int cpupercent; 44 45top: 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 56void *cpumon_stress_thread(void *arg) 57{ 58top: 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 70void *wakemon_stress_thread(void *arg) 71{ 72top: 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 84void *exit_thread(void *arg) 85{ 86 sleep(exit_after); 87 printf("...exiting.\n"); 88 exit(0); 89 90 return (NULL); 91} 92 93int 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} 179