/** Return true iff we have room to queue another onionskin of type * <b>type</b>. */ static int have_room_for_onionskin(uint16_t type) { const or_options_t *options = get_options(); int num_cpus; uint64_t tap_usec, ntor_usec; uint64_t ntor_during_tap_usec, tap_during_ntor_usec; /* If we've got fewer than 50 entries, we always have room for one more. */ if (ol_entries[type] < 50) return 1; num_cpus = get_num_cpus(options); /* Compute how many microseconds we'd expect to need to clear all * onionskins in various combinations of the queues. */ /* How long would it take to process all the TAP cells in the queue? */ tap_usec = estimated_usec_for_onionskins( ol_entries[ONION_HANDSHAKE_TYPE_TAP], ONION_HANDSHAKE_TYPE_TAP) / num_cpus; /* How long would it take to process all the NTor cells in the queue? */ ntor_usec = estimated_usec_for_onionskins( ol_entries[ONION_HANDSHAKE_TYPE_NTOR], ONION_HANDSHAKE_TYPE_NTOR) / num_cpus; /* How long would it take to process the tap cells that we expect to * process while draining the ntor queue? */ tap_during_ntor_usec = estimated_usec_for_onionskins( MIN(ol_entries[ONION_HANDSHAKE_TYPE_TAP], ol_entries[ONION_HANDSHAKE_TYPE_NTOR] / num_ntors_per_tap()), ONION_HANDSHAKE_TYPE_TAP) / num_cpus; /* How long would it take to process the ntor cells that we expect to * process while draining the tap queue? */ ntor_during_tap_usec = estimated_usec_for_onionskins( MIN(ol_entries[ONION_HANDSHAKE_TYPE_NTOR], ol_entries[ONION_HANDSHAKE_TYPE_TAP] * num_ntors_per_tap()), ONION_HANDSHAKE_TYPE_NTOR) / num_cpus; /* See whether that exceeds MaxOnionQueueDelay. If so, we can't queue * this. */ if (type == ONION_HANDSHAKE_TYPE_NTOR && (ntor_usec + tap_during_ntor_usec) / 1000 > (uint64_t)options->MaxOnionQueueDelay) return 0; if (type == ONION_HANDSHAKE_TYPE_TAP && (tap_usec + ntor_during_tap_usec) / 1000 > (uint64_t)options->MaxOnionQueueDelay) return 0; /* If we support the ntor handshake, then don't let TAP handshakes use * more than 2/3 of the space on the queue. */ if (type == ONION_HANDSHAKE_TYPE_TAP && tap_usec / 1000 > (uint64_t)options->MaxOnionQueueDelay * 2 / 3) return 0; return 1; }
void stop() { if (get_thread_num() != 0) { // workers don't come here until terminate() has been called int nv = Atomic::decrease_nv(&start_counter); // wait until all workers reached this step // all threads must agree that we are shutting // down before we can continue and invoke the // destructor startup_lock.lock(); startup_lock.unlock(); return; } start_executing(); // make sure threads have been started, or we will wait forever in barrier barrier_protocol.barrier(*threads[0]); startup_lock.lock(); for (int i = 1; i < get_num_cpus(); ++i) threads[i]->terminate(); // wait for all threads to join while (start_counter != 1) Atomic::rep_nop(); // signal that threads can destruct startup_lock.unlock(); for (int i = 1; i < get_num_cpus(); ++i) delete threads[i]; delete [] threads; delete [] task_queues; }
/** If we have too few or too many active cpuworkers, try to spawn new ones * or kill idle ones. */ static void spawn_enough_cpuworkers(void) { int num_cpuworkers_needed = get_num_cpus(get_options()); if (num_cpuworkers_needed < MIN_CPUWORKERS) num_cpuworkers_needed = MIN_CPUWORKERS; if (num_cpuworkers_needed > MAX_CPUWORKERS) num_cpuworkers_needed = MAX_CPUWORKERS; while (num_cpuworkers < num_cpuworkers_needed) { if (spawn_cpuworker() < 0) { log_warn(LD_GENERAL,"Cpuworker spawn failed. Will try again later."); return; } num_cpuworkers++; } }
int main(int argc, char **argv) { int num_cpus; int i ; num_cpus = get_num_cpus(); assert(num_cpus >= 1); num_devices = ps_list_devices(devices); if (num_devices == -1) { perror("ps_list_devices"); exit(1); } parse_opt(argc, argv); for (i = 0; i < num_cpus; i++) { int ret = fork(); assert(ret >= 0); my_cpu = i; if (ret == 0) { bind_cpu(i); signal(SIGINT, handle_signal); echo(); return 0; } } signal(SIGINT, SIG_IGN); while (1) { int ret = wait(NULL); if (ret == -1 && errno == ECHILD) break; } return 0; }
int bind_cpu(int cpu) { cpu_set_t *cmask; struct bitmask *bmask; size_t ncpu, setsize; int ret; ncpu = get_num_cpus(); if (cpu < 0 || cpu >= (int)ncpu) { errno = -EINVAL; return -1; } cmask = CPU_ALLOC(ncpu); if (cmask == NULL) return -1; setsize = CPU_ALLOC_SIZE(ncpu); CPU_ZERO_S(setsize, cmask); CPU_SET_S(cpu, setsize, cmask); ret = sched_setaffinity(0, ncpu, cmask); CPU_FREE(cmask); /* skip NUMA stuff for UMA systems */ if (numa_max_node() == 0) return ret; bmask = numa_bitmask_alloc(16); assert(bmask); numa_bitmask_setbit(bmask, cpu % 2); numa_set_membind(bmask); numa_bitmask_free(bmask); return ret; }
/** If we have too few or too many active cpuworkers, try to spawn new ones * or kill idle ones. */ static void spawn_enough_cpuworkers(void) { int num_cpuworkers_needed = get_num_cpus(get_options()); int reseed = 0; if (num_cpuworkers_needed < MIN_CPUWORKERS) num_cpuworkers_needed = MIN_CPUWORKERS; if (num_cpuworkers_needed > MAX_CPUWORKERS) num_cpuworkers_needed = MAX_CPUWORKERS; while (num_cpuworkers < num_cpuworkers_needed) { if (spawn_cpuworker() < 0) { log_warn(LD_GENERAL,"Cpuworker spawn failed. Will try again later."); return; } num_cpuworkers++; reseed++; } if (reseed) crypto_seed_weak_rng(&request_sample_rng); }
int main(int argc, char **argv) { num_devices = ps_list_devices(devices); if (num_devices == -1) { perror("ps_list_devices"); exit(1); } parse_opt(argc, argv); num_cpus = get_num_cpus(); assert(num_cpus >= 1); for (my_cpu = 0; my_cpu < num_cpus; my_cpu++) { int ret = fork(); assert(ret >= 0); if (ret == 0) { bind_cpu(my_cpu); signal(SIGINT, stat_signal); attach(); dump(); return 0; } } signal(SIGINT, SIG_IGN); while(1) { int ret = wait(NULL); if(-1 == ret && ECHILD == errno) break; } return 0; }
int main(int argc, char **argv) { int num_packets = 0; int chunk_size = 64; int packet_size = 60; int num_flows = 0; int i; ip_version = 4; struct timeval begin, end; num_cpus = get_num_cpus(); assert(num_cpus >= 1); num_devices = ps_list_devices(devices); assert(num_devices != -1); assert(num_devices > 0); for (i = 1; i < argc; i += 2) { if (i == argc - 1) print_usage(argv[0]); if (!strcmp(argv[i], "-n")) { num_packets = atoi(argv[i + 1]); assert(num_packets >= 0); } else if (!strcmp(argv[i], "-s")) { chunk_size = atoi(argv[i + 1]); assert(chunk_size >= 1 && chunk_size <= MAX_CHUNK_SIZE); } else if (!strcmp(argv[i], "-p")) { packet_size = atoi(argv[i + 1]); assert(packet_size >= 60 && packet_size <= 1514); } else if (!strcmp(argv[i], "-f")) { num_flows = atoi(argv[i + 1]); assert(num_flows >= 0 && num_flows <= MAX_FLOWS); } else if (!strcmp(argv[i], "-v")) { ip_version = atoi(argv[i + 1]); assert(ip_version == 4 || ip_version == 6); } else if (!strcmp(argv[i], "-i")) { int ifindex = -1; int j; if (!strcmp(argv[i + 1], "all")) { for (j = 0; j < num_devices; j++) devices_registered[j] = j; num_devices_registered = num_devices; continue; } for (j = 0; j < num_devices; j++) if (!strcmp(argv[i + 1], devices[j].name)) ifindex = j; if (ifindex == -1) { fprintf(stderr, "device %s does not exist!\n", argv[i + 1]); exit(1); } for (j = 0; j < num_devices_registered; j++) if (devices_registered[j] == ifindex) { fprintf(stderr, "device %s is registered more than once!\n", argv[i + 1]); exit(1); } devices_registered[num_devices_registered] = ifindex; num_devices_registered++; } else if (!strcmp(argv[i], "-t")) { time_limit = atoi(argv[i + 1]); assert(time_limit >= 0); } else print_usage(argv[0]); } if (num_devices_registered == 0) print_usage(argv[0]); printf("# of CPUs = %d\n", num_cpus); printf("# of packets to transmit = %d\n", num_packets); printf("chunk size = %d\n", chunk_size); printf("packet size = %d bytes\n", packet_size); printf("# of flows = %d\n", num_flows); printf("ip version = %d\n", ip_version); printf("time limit = %d seconds\n", time_limit); printf("interfaces: "); for (i = 0; i < num_devices_registered; i++) { if (i > 0) printf(", "); printf("%s", devices[devices_registered[i]].name); } printf("\n"); printf("----------\n"); if (num_flows > 0) srand(time(NULL)); assert(gettimeofday(&begin, NULL) == 0); for (my_cpu = 0; my_cpu < num_cpus; my_cpu++) { int ret = fork(); assert(ret >= 0); if (ret == 0) { bind_cpu(my_cpu); signal(SIGINT, handle_signal); send_packets(num_packets ? : LONG_MAX, chunk_size, packet_size, num_flows); return 0; } }
/* not using /proc/loadavg because it only works when our_timer_interval == theirs */ static int get_cpuload(double * load) { static long long o_user, o_nice, o_sys, o_idle, o_iow, o_irq, o_sirq, o_stl; long long n_user, n_nice, n_sys, n_idle, n_iow, n_irq, n_sirq, n_stl; static int first_time = 1; FILE * f = fopen("/proc/stat", "r"); double vload; int ncpu; static int errormsg = 0; if (! f) { /* Only write this error message five times. Otherwise you will annoy BSD-ish system administrators. */ if (errormsg < 5) { LM_ERR("could not open /proc/stat\n"); errormsg++; } return -1; } if (fscanf(f, "cpu %lld%lld%lld%lld%lld%lld%lld%lld", &n_user, &n_nice, &n_sys, &n_idle, &n_iow, &n_irq, &n_sirq, &n_stl) < 0) { LM_ERR("could not parse load information\n"); return -1; } fclose(f); if (first_time) { first_time = 0; *load = 0; } else { long long d_total = (n_user - o_user) + (n_nice - o_nice) + (n_sys - o_sys) + (n_idle - o_idle) + (n_iow - o_iow) + (n_irq - o_irq) + (n_sirq - o_sirq) + (n_stl - o_stl); long long d_idle = (n_idle - o_idle); vload = ((double)d_idle) / (double)d_total; /* divide by numbers of cpu */ ncpu = get_num_cpus(); vload = vload/ncpu; vload = 1.0 - vload; if(vload<0.0) vload = 0.0; else if (vload>1.0) vload = 1.0; *load = vload; } o_user = n_user; o_nice = n_nice; o_sys = n_sys; o_idle = n_idle; o_iow = n_iow; o_irq = n_irq; o_sirq = n_sirq; o_stl = n_stl; return 0; }
uintptr_t rust_get_num_cpus() { return get_num_cpus(); }
int http_server_start(unsigned short port, http_handler_t http_handlers[], int num_handlers, const char *static_root) { int rt; int num_cpus = get_num_cpus(); http_server_data_t server_data = {0}, *data_tmp = NULL; evutil_socket_t sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { perror("could not create socket"); return 1; } rt = evutil_make_listen_socket_reuseable(sock); if (rt < 0) { perror("cannot make socket reuseable"); return 1; } struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = htons(port); rt = bind(sock, (struct sockaddr*)&addr, sizeof(addr)); if (rt < 0) { perror("cannot bind socket"); return -1; } rt = listen(sock, 1024); if (rt < 0) { perror("cannot listen"); return -1; } rt = evutil_make_socket_nonblocking(sock); if (rt < 0) { perror("cannot make socket non blocking"); return -1; } server_data.handlers = http_handlers; server_data.num_handlers = num_handlers; server_data.sock = sock; server_data.static_root = static_root; int i; num_servers = num_cpus; server_base = apr_pcalloc(global_pool, (num_servers + 1) * sizeof(struct event_base *)); for(i= 0; i < num_servers; i++) { data_tmp = calloc(1, sizeof(http_server_data_t)); *data_tmp = server_data; data_tmp->server_index = i; apr_thread_pool_push(thread_pool, http_server, data_tmp, APR_THREAD_TASK_PRIORITY_HIGHEST, NULL); } return 0; }
/** * monitor_tbufs - monitor the contents of tbufs */ static int monitor_tbufs(void) { int i; struct t_struct *tbufs; /* Pointer to hypervisor maps */ struct t_buf **meta; /* pointers to the trace buffer metadata */ unsigned char **data; /* pointers to the trace buffer data areas * where they are mapped into user space. */ unsigned long tbufs_mfn; /* mfn of the tbufs */ unsigned int num; /* number of trace buffers / logical CPUS */ unsigned long tinfo_size; /* size of t_info metadata map */ unsigned long size; /* size of a single trace buffer */ unsigned long data_size, rec_size; /* get number of logical CPUs (and therefore number of trace buffers) */ num = get_num_cpus(); init_current(num); alloc_qos_data(num); printf("CPU Frequency = %7.2f\n", opts.cpu_freq); /* setup access to trace buffers */ get_tbufs(&tbufs_mfn, &tinfo_size); tbufs = map_tbufs(tbufs_mfn, num, tinfo_size); size = tbufs->t_info->tbuf_size * XC_PAGE_SIZE; data_size = size - sizeof(struct t_buf); meta = tbufs->meta; data = tbufs->data; if ( eventchn_init() < 0 ) fprintf(stderr, "Failed to initialize event channel; " "Using POLL method\r\n"); /* now, scan buffers for events */ while ( !interrupted ) { for ( i = 0; (i < num) && !interrupted; i++ ) { unsigned long start_offset, end_offset, cons, prod; cons = meta[i]->cons; prod = meta[i]->prod; xen_rmb(); /* read prod, then read item. */ if ( cons == prod ) continue; start_offset = cons % data_size; end_offset = prod % data_size; if ( start_offset >= end_offset ) { while ( start_offset != data_size ) { rec_size = process_record( i, (struct t_rec *)(data[i] + start_offset)); start_offset += rec_size; } start_offset = 0; } while ( start_offset != end_offset ) { rec_size = process_record( i, (struct t_rec *)(data[i] + start_offset)); start_offset += rec_size; } xen_mb(); /* read item, then update cons. */ meta[i]->cons = prod; } wait_for_event(); wakeups++; } /* cleanup */ free(meta); free(data); /* don't need to munmap - cleanup is automatic */ return 0; }
int OpenEXRforMatlab::getNumCPUs() { static int numCPUs = get_num_cpus(); return numCPUs; }
extern "C" CDECL uintptr_t rust_get_num_cpus() { return get_num_cpus(); }
int main (int argc, char **argv, char **envp) { global_prog_name = argv[0]; if (argc == 1) { usage(global_prog_name); exit(1); } // Determine which version of OS X we are running on. int major_version_num; int minor_version_num; int subminor_version_num; get_macosx_version(&major_version_num, &minor_version_num, &subminor_version_num); struct poll_state ps; ps.use_polling = 0; if (major_version_num >= 10) { // Mac OS X 10.5.* and earlier return a number that appears // correct from the ru_maxrss field of getrusage(), also // filled in by wait4(). // Mac OS X 10.6.* always returns 0 for ru_maxrss, so we must // use a different method to measure it. ps.use_polling = 1; } char **child_argv = (char **) malloc((unsigned) argc * sizeof(char *)); int i; for (i = 1; i < argc; i++) { child_argv[i-1] = argv[i]; } child_argv[argc-1] = NULL; // char **p; // for (p = child_argv; *p != NULL; p++) { // fprintf(stderr, " p[%d]='%s'", p-child_argv, *p); // } // fprintf(stderr, "\n"); struct timeval start_time; struct timeval end_time; unsigned int num_cpus = get_num_cpus(); cpu_usage *total_cpu_stats_start = malloc_cpu_stats(1); cpu_usage *per_cpu_stats_start = malloc_cpu_stats(num_cpus); cpu_usage *total_cpu_stats_end = malloc_cpu_stats(1); cpu_usage *per_cpu_stats_end = malloc_cpu_stats(num_cpus); get_cpu_usage(num_cpus, per_cpu_stats_start, total_cpu_stats_start); int ret = gettimeofday(&start_time, NULL); // tbd: check ret pid_t pid = fork(); if (pid == -1) { fprintf(stderr, "Error return status -1 while attempting" " to call fork(). errno=%d\n", errno); perror(global_prog_name); exit(3); } else if (pid == 0) { // We are the child process // Set the uid to the original uid of the process that invoked // the timemem-darwin process, so that the command being // measured is run with that user's priviliges, not with root // privileges. int original_uid = getuid(); int ret = setuid(original_uid); if (ret != 0) { fprintf(stderr, "Error return status %d while attempting" " to set uid to %d. errno=%d\n", ret, original_uid, errno); perror(global_prog_name); exit(4); } ret = execvp(child_argv[0], child_argv); // Normally the call above will not return. fprintf(stderr, "Error return status %d while attempting" " to call execvp(). errno=%d\n", ret, errno); perror(global_prog_name); exit(2); } // We are the parent process. // We want to wait until the child process finishes, but we also // want to periodically poll the child process's resident set size // (memory usage). On OS X 10.5.8 and earlier, simply using // wait4() for the child to finish would fill in the rusage struct // with the maximum resident set size, but this value is always // filled in with 0 in OS X 10.6, hence the use of polling. // We implement the polling by calling setitimer() so that we are // sent a SIGALRM signal every 100 msec. This should cause // wait4() to return early. We handle the signal, and then call // wait4() again. // Read the current maximum resident set size once before starting // the timer, because the most likely reason for it to fail is // that we are not running with root privileges. if (ps.use_polling) { if (init_polling_process_rss(pid, &ps) != 0) { run_as_superuser_msg(global_prog_name); exit(1); } poll_process_rss(&ps); // Set up the SIGALRM signal handler. global_sigalrm_handled = 0; enable_handling_sigalrm(); // Set timer to send us a SIGALRM signal every 100 msec. int timer_period_msec = 100; enable_timer(timer_period_msec); } //int wait_opts = WNOHANG; int wait_opts = 0; int wait_status; int wait4_ret; struct rusage r; while (1) { wait4_ret = wait4(pid, &wait_status, wait_opts, &r); if (wait4_ret != -1) { break; } if ((errno == EINTR) && ps.use_polling) { // Most likely the SIGALRM timer signal was handled. If // so, poll the child process's memory use once. The // timer should automatically signal again periodically // without having to reset it. if (global_sigalrm_handled) { poll_process_rss(&ps); global_sigalrm_handled = 0; if (ps.task_info_errored) { disable_timer(); ignore_sigalrm(); } } // Go around and call wait4() again. } else { fprintf(stderr, "wait4() returned %d. errno=%d\n", wait4_ret, errno); perror(global_prog_name); exit(5); } } // We may not use end_time if there are errors we haven't checked // for yet from wait4(), but it is more accurate to call this as // soon after wait4() returns as we can. It is out of the loop // above to avoid the overhead of calling it on every poll time. if (debug) { fprintf(stderr, "About to call gettimeofday()\n"); } ret = gettimeofday(&end_time, NULL); // tbd: check ret get_cpu_usage(num_cpus, per_cpu_stats_end, total_cpu_stats_end); if (wait4_ret != pid) { fprintf(stderr, "wait4() returned pid=%d. Expected pid" " %d of child process. Try again.\n", wait4_ret, pid); fprintf(stderr, "wait4 r.ru_maxrss=%ld\n", r.ru_maxrss); exit(7); } ps.wait4_returned_normally = 1; if (debug) { fprintf(stderr, "wait4() returned pid=%d of child process." " Done!\n", pid); } if (ps.use_polling) { // Disable the timer. Ignore SIGALRM, too, just in case one // more happens. if (debug) { fprintf(stderr, "About to disable the timer\n"); } disable_timer(); if (debug) { fprintf(stderr, "About to ignore SIGALRM\n"); } ignore_sigalrm(); } // Elapsed time int elapsed_msec = timeval_diff_msec(&start_time, &end_time); fprintf(stderr, "real %9d.%03d\n", (elapsed_msec / 1000), (elapsed_msec % 1000)); // User, sys times fprintf(stderr, "user %9ld.%03d\n", r.ru_utime.tv_sec, r.ru_utime.tv_usec / 1000); fprintf(stderr, "sys %9ld.%03d\n", r.ru_stime.tv_sec, r.ru_stime.tv_usec / 1000); // Maximum resident set size if (! ps.use_polling) { // At least on the Intel Core 2 Duo Mac OS X 10.5.8 machine on // which I first tested this code, it seemed to give a value // of up to 2^31-4096 bytes correctly, but if it went a little // bit over that, the fprintf statement showed it as 0, not // 2^31 bytes. For now, I'll do a special check for 0 and // print out what I believe to be the correct value. // One way to test this on that machine is as follows. The // first command below prints 2^31-4096 bytes as the maximum // resident set size. Without the "if" condition below, the // second command below prints 0 as the maximum resident set // size. // ./timemem-darwin ../../memuse/test-memuse 2096863 // ./timemem-darwin ../../memuse/test-memuse 2096864 // Reference: // http://lists.apple.com/archives/darwin-kernel/2009/Mar/msg00005.html if (r.ru_maxrss == 0L) { // Print 2^31 bytes exactly fprintf(stderr, "2147483648 maximum resident set size from getrusage\n"); } else { fprintf(stderr, "%10lu maximum resident set size from getrusage\n", (unsigned long) r.ru_maxrss); } } if (ps.use_polling) { long delta = (long) ps.max_rss_bytes - (long) r.ru_maxrss; fprintf(stderr, "%10lu maximum resident set size from polling (%.1f MB, delta %ld bytes = %.1f MB)\n", (unsigned long) ps.max_rss_bytes, (double) ps.max_rss_bytes / (1024.0 * 1024.0), delta, (double) delta / (1024.0 * 1024.0)); double elapsed_time_sec = (double) elapsed_msec / 1000.0; fprintf(stderr, "number of times rss polled=%ld, avg of %.1f times per second\n", ps.num_polls, (double) ps.num_polls / elapsed_time_sec); fprintf(stderr, "time between consecutive polls (msec): min=%.1f max=%.1f\n", (double) ps.consecutive_poll_separation_min_msec, (double) ps.consecutive_poll_separation_max_msec); int64 max_rss_first_seen_msec = timeval_diff_msec(&start_time, &(ps.poll_time_when_maxrss_first_seen)); fprintf(stderr, "Max RSS observed %.1f sec after start time\n", (double) max_rss_first_seen_msec / 1000.0); if (ps.task_info_errored) { int64 diff_msec = timeval_diff_msec(&end_time, &(ps.task_info_error_time)); if (diff_msec <= 0 && diff_msec >= -100) { // Then the error most likely occurred because the // child process had already exited. Ignore it. } else { fprintf(stderr, "A call to task_info() returned an error. error_time - end_time = %.3f sec. This may mean the maximum resident set size measurement above is too low.\n", (double) diff_msec / 1000.0); } } } // Show separate busy percentage for each CPU core fprintf(stderr, "Per core CPU utilization (%d cores):", num_cpus); for (i = 0; i < num_cpus; i++) { uint64 total = (per_cpu_stats_end[i].total - per_cpu_stats_start[i].total); int cpu_busy_percent = 0; if (total != 0) { uint64 idle = (per_cpu_stats_end[i].idle - per_cpu_stats_start[i].idle); cpu_busy_percent = (int) round(100.0 * (1.0 - ((float) idle)/total)); } fprintf(stderr, " %d%%", cpu_busy_percent); } fprintf(stderr, "\n"); if (WIFEXITED(wait_status)) { // Exit with the same status that the child process did. exit(WEXITSTATUS(wait_status)); } else if (WIFSIGNALED(wait_status)) { fprintf(stderr, "Command stopped due to signal %d without calling exit().\n", WTERMSIG(wait_status)); exit(1); } else { fprintf(stderr, "Command is stopped due to signal %d, and can be restarted.\n", WSTOPSIG(wait_status)); exit(2); } return 0; }
/** * monitor_tbufs - monitor the contents of tbufs */ int monitor_tbufs(void) { int i; extern int process_record(int, struct t_rec *); extern void alloc_qos_data(int ncpu); void *tbufs_mapped; /* pointer to where the tbufs are mapped */ struct t_buf **meta; /* pointers to the trace buffer metadata */ char **data; /* pointers to the trace buffer data areas * where they are mapped into user space. */ unsigned long tbufs_mfn; /* mfn of the tbufs */ unsigned int num; /* number of trace buffers / logical CPUS */ unsigned long size; /* size of a single trace buffer */ unsigned long data_size, rec_size; /* get number of logical CPUs (and therefore number of trace buffers) */ num = get_num_cpus(); init_current(num); alloc_qos_data(num); printf("CPU Frequency = %7.2f\n", opts.cpu_freq); /* setup access to trace buffers */ get_tbufs(&tbufs_mfn, &size); tbufs_mapped = map_tbufs(tbufs_mfn, num, size); data_size = size - sizeof(struct t_buf); /* build arrays of convenience ptrs */ meta = init_bufs_ptrs (tbufs_mapped, num, size); data = (char **)init_rec_ptrs(meta, num); if ( eventchn_init() < 0 ) fprintf(stderr, "Failed to initialize event channel; " "Using POLL method\r\n"); /* now, scan buffers for events */ while ( !interrupted ) { for ( i = 0; (i < num) && !interrupted; i++ ) { while ( meta[i]->cons != meta[i]->prod ) { rmb(); /* read prod, then read item. */ rec_size = process_record( i, (struct t_rec *)(data[i] + meta[i]->cons % data_size)); mb(); /* read item, then update cons. */ meta[i]->cons += rec_size; } } wait_for_event(); wakeups++; } /* cleanup */ free(meta); free(data); /* don't need to munmap - cleanup is automatic */ return 0; }
int main(int argc, char** argv) { int err = 0; long total; // Number of clock ticks per second long num_cpus; char cpu_field[MAX_CPU_FIELD_LEN + 1]; unsigned int _kern, _user, _nice, _idle; unsigned int kern, user, nice, idle; arguments config; buffer* stat = NULL; gmbar* bar = NULL; stat = buffer_new(); if (!stat) { return -1; } bar = gmbar_new_with_defaults(100, 10, "red", "none"); if (!bar) { buffer_free(stat); return -1; } err = gmbar_add_sections(bar, 4, "red", "orange", "yellow", "none"); if (err) { buffer_free(stat); gmbar_free(bar); return -1; } config.cpu_index = -1; config.common_config.bar = bar; config.common_config.interval = 15; config.common_config.prefix = NULL; config.common_config.suffix = NULL; err = argp_parse(&argp, argc, argv, 0, NULL, &config); if (err) { buffer_free(stat); gmbar_free(bar); return err; } /* Clock ticks per second (per CPU) */ total = sysconf(_SC_CLK_TCK); /* Number of CPUs */ num_cpus = get_num_cpus(); if (num_cpus < 0) { buffer_free(stat); gmbar_free(bar); return num_cpus; } if (config.cpu_index >= 0 && config.cpu_index <= CHAR_MAX && config.cpu_index < num_cpus) { snprintf(cpu_field, MAX_CPU_FIELD_LEN, "cpu%i ", config.cpu_index); } else { snprintf(cpu_field, MAX_CPU_FIELD_LEN, "cpu "); } /* Initialize history */ err = get_stat(stat, cpu_field, &_kern, &_user, &_nice, &_idle); if (err) { buffer_free(stat); gmbar_free(bar); return err; } while (config.common_config.interval) { sleep(config.common_config.interval); err = get_stat(stat, cpu_field, &kern, &user, &nice, &idle); if (err) { buffer_free(stat); gmbar_free(bar); return err; } /* total is not accurate */ total = (kern - _kern) + (user - _user) + (nice - _nice) + (idle - _idle); gmbar_set_section_width(bar->sections[0], total, kern - _kern); gmbar_set_section_width(bar->sections[1], total, user - _user); gmbar_set_section_width(bar->sections[2], total, nice - _nice); gmbar_set_section_width(bar->sections[3], total, idle - _idle); err = print_bar(&config.common_config); if (err) { buffer_free(stat); gmbar_free(bar); return err; } _kern = kern; _user = user; _nice = nice; _idle = idle; } return 0; }