void mysql_poolinit(void) { pthread_t pthread[THREADS]; db_config dbc; int i; strlcpy(dbc.host, dbhost, strlen(dbhost) + 1); strlcpy(dbc.user, dbuser, strlen(dbuser) + 1); strlcpy(dbc.pass, dbpass, strlen(dbpass) + 1); strlcpy(dbc.name, dbname, strlen(dbname) + 1); dbc.port = 0; dbc.socket = NULL; if (!mysql_thread_safe()) { vbprintf("Using own threaded pool with %d mysql threads\n", THREADS); } else { vbprintf("Using threaded mysql connection pool of %d threads\n", THREADS); } vbprintf("DB Connections: %d, Threads: %d\n", CONPOOL, THREADS); //Pre - init for (i = 0; i < CONPOOL; i++) { dbm[i].db = mysql_conn(dbm[i].db, &dbc); pthread_mutex_init(&dbm[i].lock, NULL); } vbprintf("MySQL init done.\n"); }
/* * XXX: fix to propagate to all sets */ static void pfmon_ita_setup_rr(pfmon_event_set_t *set) { pfmlib_ita_input_param_t *param = set->mod_inp; pfmon_ita_args_t *ita_args; uintptr_t start, end; ita_args = set->mod_args; if (pfmon_ita_opt.chkp_func_arg) { if (set->priv_lvl_str) fatal_error("cannot use both a checkpoint function and per-event privilege level masks\n"); gen_code_range(pfmon_ita_opt.chkp_func_arg, &start, &end); /* just one bundle for this one */ end = start + 0x10; vbprintf("checkpoint function at %p\n", start); } else if (pfmon_ita_opt.irange_arg) { if (set->priv_lvl_str) fatal_error("cannot use both a code range function and per-event privilege level masks\n"); gen_code_range(pfmon_ita_opt.irange_arg, &start, &end); if ((unsigned long)start & 0xf) fatal_error("code range does not start on bundle boundary : %p\n", start); if ((unsigned long)end & 0xf) fatal_error("code range does not end on bundle boundary : %p\n", end); vbprintf("irange is [%p-%p)=%ld bytes\n", start, end, end-start); } /* * now finalize irange/chkp programming of the range */ if (pfmon_ita_opt.irange_arg || pfmon_ita_opt.chkp_func_arg) { param->pfp_ita_irange.rr_used = 1; param->pfp_ita_irange.rr_limits[0].rr_start = (unsigned long)start; param->pfp_ita_irange.rr_limits[0].rr_end = (unsigned long)end; param->pfp_ita_irange.rr_limits[0].rr_plm = set->inp.pfp_dfl_plm; /* use default */ } if (pfmon_ita_opt.drange_arg) { if (set->priv_lvl_str) fatal_error("cannot use both a data range and per-event privilege level masks\n"); gen_data_range(pfmon_ita_opt.drange_arg, &start, &end); vbprintf("drange is [%p-%p)=%lu bytes\n", start, end, end-start); param->pfp_ita_drange.rr_used = 1; param->pfp_ita_drange.rr_limits[0].rr_start = (unsigned long)start; param->pfp_ita_drange.rr_limits[0].rr_end = (unsigned long)end; param->pfp_ita_drange.rr_limits[0].rr_plm = set->inp.pfp_dfl_plm; /* use default */ } }
void sqlite_init(void) { char *dberr = NULL; int res; vbprintf("SQlite init: %s\n", dbdir); sqlite3_open(dbdir, &db); if (!db) { vbprintf("sqlite_init: unable to open db\n"); exit(1); } /* Check if database contains any data or structure */ res = sqlite3_exec(db, "select count(id) from status;", NULL, NULL, NULL); if (res != SQLITE_OK && res != SQLITE_BUSY) { res = sqlite3_exec(db, createdb, NULL, NULL, &dberr); if (res != SQLITE_OK && res != SQLITE_BUSY) { vbprintf("sqlite_init: PANIC: Couldn't create table: %s\n", dberr); free(dberr); exit(-1); } } /* Seems like all is okay */ vbprintf("sqlite_init: Database ready\n"); sqlite3_close(db); return; }
MYSQL_RES * mysql_my_query(MYSQL * mysql, pthread_mutex_t * lock, const char *query) { MYSQL_RES *res; long retc; pthread_mutex_lock(lock); retc = mysql_query(mysql, query); if (retc) { pthread_mutex_unlock(lock); vbprintf("mysql_query problem: %s", mysql_error(mysql)); return NULL; } res = mysql_store_result(mysql); pthread_mutex_unlock(lock); if (res) { return res; } else { if (mysql_field_count(mysql) == 0) { dbprintf("Query affected %d rows.\n", mysql_affected_rows(mysql)); } else { vbprintf("MySQL problem: %s\n", mysql_error(mysql)); } } return NULL; }
int sqlite_insert_stat(char *type, char *value, int status) { int res; char *dberr; char *query; time_t now; time(&now); if (asprintf(&query, "PRAGMA journal_mode=OFF; INSERT INTO status (status, value, alertstatus, lastalert) VALUES ('%s', '%s', '%d', '%lu');", type, value, status, (unsigned long int) now) < 0) { perror("sqlite_insert_stat: asprintf"); } sqlite3_open(dbdir, &db); res = sqlite3_exec(db, query, NULL, NULL, &dberr); if (res != SQLITE_OK) { vbprintf("sqlite_insert_stat: ERROR: %s\n", dberr); if (res != SQLITE_OK) { /* trying again */ while(res == SQLITE_BUSY) { res = sqlite3_exec(db, query, NULL, NULL, &dberr); } } sqlite3_close(db); return 0; } sqlite3_close(db); free(query); return 1; }
void blog_preload(void) { char *buf; vbprintf("Preloading data.\n"); webpage = suckfile_mmap(template);
int event_check(void) { /* * This function is used for checking events. Currently, only a load * average check is performed. But it can be extended to include a * whole range of checks. Returns the event or EV_AOK when everything * is between acceptable parameters. */ double load[3]; static int counter; int retval = EV_AOK; /* check load average */ if (maxload != -1) { if (getloadavg(load, 3) < 0) { warnx("getloadavg failed"); } if (maxload < load[0]) { if (counter == 0) vbprintf("Load too high. Setting event to EV_LOADTOOHIGH\n"); counter++; retval = EV_LOADTOOHIGH; } else { counter = 0; dbprintf("event_check: maxload: %.2f currload %.2f\n", maxload, load[0]); retval = EV_AOK; } } return retval; }
void extmacro_def(const char *name, const char *fmt, ...) { char buf[256]; struct extmacro *m; va_list ap; VTAILQ_FOREACH(m, &extmacro_list, list) if (!strcmp(name, m->name)) break; if (m == NULL && fmt != NULL) { m = calloc(sizeof *m, 1); AN(m); REPLACE(m->name, name); VTAILQ_INSERT_TAIL(&extmacro_list, m, list); } if (fmt != NULL) { AN(m); va_start(ap, fmt); free(m->val); vbprintf(buf, fmt, ap); va_end(ap); m->val = strdup(buf); AN(m->val); } else if (m != NULL) { VTAILQ_REMOVE(&extmacro_list, m, list); free(m->name); free(m->val); free(m); } }
// int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); void denySyscall(long pid) { struct user_regs_struct regs; EXITIF(ptrace(PTRACE_GETREGS, pid, NULL, ®s)<0); if (CDE_verbose_mode>=2) { vbprintf("[%ld-net] denySyscall %d\n", pid, SYSCALL_NUM(®s)); } SYSCALL_NUM(®s) = 0xbadca11; EXITIF(ptrace(PTRACE_SETREGS, pid, NULL, ®s)<0); }
/* * Print fmt and it's arguments (printf-style) to a newly allocated * buffer and return a pointer to that buffer if successful, NULL * if we ran out of memory. */ static char *bprintf (const char *fmt, ...) { char *buf; va_list ap; va_start (ap,fmt); buf = vbprintf (fmt,ap); va_end (ap); return (buf); }
int bprintf (buffer *b, char const *format, ...) { va_list args ; int r ; va_start(args, format) ; r = vbprintf(b, format, args) ; va_end(args) ; return r ; }
int vsprintf(char *string, const char *fmt, va_list ap) { struct buffer b; buffer_init(&b); vbprintf(&b, fmt, ap); memcpy(string, b.buffer, b.position); string[b.position]= '\0'; buffer_release(&b); return b.position; }
void check_mainloop(void) { time_t now = 0, then = 0; useconds_t sleeptime; int delta = 0; /* init */ status_alerted.alert_load = false; status_alerted.alert_disk = false; status_alerted.alert_cpu = false; sleeptime = 100000; numcpus = num_cpus(); http_fetch_url(hburl); vbprintf("Found %d cpus\n", numcpus); database_init(); /* * XXX: Right here we're just spinning in place. The reason for this * is to be able to have different intervals for the checking process * (disk/cpu/load), and also for the heartbeat-process, which might * check at different intervals. I might separate this out into * another file so we have a rudimentary timer-based scheduler that * can shoot off different functions at variable intervals. */ time(&then); while (1) { int sampletrig = 0, hbtrig = 0; time(&now); delta = (int) now - (int) then; sampletrig = delta % interval; hbtrig = delta % hbinterval; if (!sampletrig) { load_check(); disk_check(diskpaths); cpu_check(); check_alert(); sleep(1); /* make sure trig status is over */ } if (!hbtrig) { http_fetch_url(hburl); sleep(1); /* make sure trig status is over */ } usleep(sleeptime); } }
void prf(char *format, ...) { string b = allocate_string(prf_heap); va_list ap; string f = alloca_string(format); va_start(ap, format); vbprintf(b, f, ap); va_end(ap); write(1, bref(b, 0), buffer_length(b)); // deallocate_buffer(b); }
int vsnprintf(char *str,size_t n,const char *fmt,va_list ap) { int res; FILE sbuf; if(!binit(&sbuf,-1,O_WRONLY,str,0,n - 1,false)) return EOF; res = vbprintf(&sbuf,fmt,ap); /* null-termination */ str[sbuf.out.pos] = '\0'; return res; }
/* Like printf, but stores the output in debugger_output. */ void page_debug (char *format, ...) { va_list args; if (!debugger_output) debugger_output = bprintf_create_buffer (); va_start (args, format); vbprintf (debugger_output, format, args); if (debugger_output->buffer[debugger_output->bindex - 1] != '\n') bprintf (debugger_output, "\n"); }
/* Like printf, but stores the output in syserr_output. */ void page_syserr (char *format, ...) { va_list args; if (!syserr_output) syserr_output = bprintf_create_buffer (); va_start (args, format); vbprintf (syserr_output, format, args); if (syserr_output->buffer[syserr_output->bindex - 1] != '\n') bprintf (syserr_output, "\n"); }
void renice(pid_t pid, int value) { /* * Renices a process ID. Prints a warning when unsuccessful. */ if (setpriority(PRIO_PROCESS, pid, value) < 0) warnx("Setting prio of pid %d to %d failed!\n", pid, value); else vbprintf("Priority of pid %d is now %d\n", pid, value); return; }
node * sqlite_return_rows(sqlite3 * db, char *fmt,...) { va_list ap; char *query, *dberr; int ret; node *result = NULL; va_start(ap, fmt); ret = vasprintf(&query, fmt, ap); va_end(ap); lresult_start = lresult_last = NULL; /* these are global */ sqlite3_open(dbdir, &db); ret = sqlite3_exec(db, query, sqlite_generic_callback, result, &dberr); /* XXX Ugly, I know. So what. It doesn't really matter */ if (ret != SQLITE_OK && ret != SQLITE_BUSY) { /* Something else went wrong. Bail */ vbprintf("sqlite_return_rows: SQL error: %s\n", dberr); sqlite3_close(db); free(dbresult); free(dberr); return NULL; } /* XXX There is probably a cleaner way to do this */ if (ret == SQLITE_BUSY) { while (ret != SQLITE_OK) { /* try again! */ ret = sqlite3_exec(db, query, sqlite_generic_callback, result, &dberr); vbprintf("sqlite_return_rows: SQL error: %s\n", dberr); sleep(1); } } sqlite3_close(db); free(query); return lresult_start; }
static void line_error (char *format, ...) { BPRINTF_BUFFER *buffer = bprintf_create_buffer (); va_list args; va_start (args, format); bprintf (buffer, "%s: %d: ", current_filename ? current_filename : "BOGUS-FILE", current_line_number); vbprintf (buffer, format, args); fprintf (stderr, "%s", buffer->buffer); bprintf_free_buffer (buffer); }
static int delay_start(void) { unsigned int left_over; vbprintf("delaying start for %u seconds\n", options.trigger_delay); /* * if aborted by some signal (SIGINT or SIGCHILD), then left_over * is not 0 */ left_over = sleep(options.trigger_delay); DPRINT(("delay_start: left_over=%u\n", left_over)); return left_over ? -1 : 0; }
uint8_t uart_vprintf(uint8_t intfnum, const char *format, va_list * args){ uint8_t stat, lstat; stat = bytebuf_cPushReqBlindLock(uart_if[intfnum]->txbuf, BYTEBUF_TOKEN_PRINT); if (stat){ stat = vbprintf(uart_if[intfnum]->txbuf, format, *args); lstat = bytebuf_cPushRelinquishLock(uart_if[intfnum]->txbuf, BYTEBUF_TOKEN_PRINT); uart_send_trigger(intfnum); if (lstat){ return stat; } else{ return 0; } } else{ return 0; } }
void macro_def(struct vtclog *vl, const char *instance, const char *name, const char *fmt, ...) { char buf1[256]; char buf2[256]; struct macro *m; va_list ap; if (instance != NULL) { bprintf(buf1, "%s_%s", instance, name); name = buf1; } AZ(pthread_mutex_lock(¯o_mtx)); VTAILQ_FOREACH(m, ¯o_list, list) if (!strcmp(name, m->name)) break; if (m == NULL && fmt != NULL) { m = calloc(sizeof *m, 1); AN(m); REPLACE(m->name, name); VTAILQ_INSERT_TAIL(¯o_list, m, list); } if (fmt != NULL) { AN(m); va_start(ap, fmt); free(m->val); m->val = NULL; vbprintf(buf2, fmt, ap); va_end(ap); m->val = strdup(buf2); AN(m->val); vtc_log(vl, 4, "macro def %s=%s", name, m->val); } else if (m != NULL) { vtc_log(vl, 4, "macro undef %s", name); VTAILQ_REMOVE(¯o_list, m, list); free(m->name); free(m->val); free(m); } AZ(pthread_mutex_unlock(¯o_mtx)); }
MYSQL * mysql_conn(MYSQL * mysql, db_config * dbc) { // Set auto-reconnect my_bool reconnect=1; if (!(mysql = mysql_init(mysql))) mysql_die("mysql_init failed: %s", mysql_error(mysql)); else { mysql_options(mysql, MYSQL_OPT_RECONNECT, &reconnect); if (!mysql_real_connect(mysql, dbc->host, dbc->user, dbc->pass, dbc->name, dbc->port, dbc->socket, 0)) { vbprintf("host: %s user: %s pass: %s db: %s\n", dbc->host, dbc->user, dbc->pass, dbc->name); mysql_die("mysql_real_connect failed: %s", mysql_error(mysql)); } } dbprintf("DB connection active.\n"); return (mysql); }
int mgt_cli_askchild(unsigned *status, char **resp, const char *fmt, ...) { int i, j; va_list ap; unsigned u; char buf[params->cli_buffer], *p; if (resp != NULL) *resp = NULL; if (status != NULL) *status = 0; if (cli_i < 0|| cli_o < 0) { if (status != NULL) *status = CLIS_CANT; return (CLIS_CANT); } va_start(ap, fmt); vbprintf(buf, fmt, ap); va_end(ap); p = strchr(buf, '\0'); assert(p != NULL && p > buf && p[-1] == '\n'); i = p - buf; j = write(cli_o, buf, i); if (j != i) { if (status != NULL) *status = CLIS_COMMS; if (resp != NULL) *resp = strdup("CLI communication error"); MGT_Child_Cli_Fail(); return (CLIS_COMMS); } (void)VCLI_ReadResult(cli_i, &u, resp, params->cli_timeout); if (status != NULL) *status = u; if (u == CLIS_COMMS) MGT_Child_Cli_Fail(); return (u == CLIS_OK ? 0 : u); }
static int do_measure_one_cpu(void *data) { pfmon_thread_desc_t *arg = (pfmon_thread_desc_t *)data; pfmon_sdesc_t sdesc_var; /* local pfmon task descriptor */ pfmon_sdesc_t *sdesc = &sdesc_var; pfmon_ctxid_t ctxid = -1; pid_t mytid = gettid(); unsigned int mycpu; int aggr, needs_order; int r, error; /* * POSIX threads: * The signal state of the new thread is initialised as follows: * - the signal mask is inherited from the creating thread. * - the set of signals pending for the new thread is empty. * * we want to let the master handle the global signals, therefore * we mask them here. */ setup_worker_signals(); mycpu = arg->cpu; aggr = options.opt_aggr; /* * some NPTL sanity checks */ if (mytid == master_tid) { warning("pfmon is not compiled/linked with the correct pthread library," "the program is linked with NPTL when it should not." "Check Makefile." "[pid=%d:tid=%d]\n", getpid(), mytid); goto error; } /* * we initialize our "simplified" sdesc */ memset(sdesc, 0, sizeof(*sdesc)); /* * just to make sure we have these fields initialized */ sdesc->type = PFMON_SDESC_ATTACH; sdesc->tid = mytid; sdesc->pid = getpid(); sdesc->cpu = mycpu; sdesc->id = arg->id; /* logical id */ DPRINT(("CPU%u: pid=%d tid=%d\n", mycpu, sdesc->pid, sdesc->tid)); pthread_setspecific(param_key, arg); if (options.online_cpus > 1) { r = pfmon_pin_self(mycpu); if (r == -1) { warning("[%d] cannot set affinity to CPU%u: %s\n", mytid, mycpu, strerror(errno)); goto error; } } r = pfmon_sys_setup_context(sdesc, arg->cpu, arg->ctx); if (r) goto error; ctxid = sdesc->ctxid; needs_order = aggr || sdesc->out_fp == stdout; DPRINT(("sdesc->id=%u needs_order=%d\n", sdesc->id, needs_order)); /* * indicate we have reach the starting point */ arg->thread_state = THREAD_RUN; if (session_state == SESSION_ABORTED) goto error; /* * wait for the start signal */ pthread_barrier_wait(&barrier.barrier); DPRINT(("CPU%u after barrier state=%d\n", mycpu, session_state)); if (session_state == SESSION_ABORTED) goto error; if (options.opt_dont_start == 0) { if (pfmon_start(ctxid, &error) == -1) goto error; vbprintf("CPU%u started monitoring\n", mycpu); } else { vbprintf("CPU%u pfmon does not start session\n", mycpu); } /* * interval is not possible when sampling */ if (options.interval != PFMON_NO_TIMEOUT) { struct timespec tm; tm.tv_sec = options.interval / 1000; tm.tv_nsec = (options.interval % 1000) * 1000000; for(;session_state == SESSION_RUN; ) { nanosleep(&tm, NULL); /* * we only check on stop to avoid printing too many messages */ if (pfmon_stop(ctxid, &error) == -1) warning("CPU%u could not stop monitoring, CPU may be offline, check results\n", mycpu); read_incremental_results(sdesc); show_incr_results(sdesc, needs_order); pfmon_start(ctxid, &error); } pthread_testcancel(); } else { if (options.opt_use_smpl) { for(;session_state == SESSION_RUN;) { pfarg_msg_t msg; r = read(sdesc->ctxid, &msg, sizeof(msg)); if (r ==-1) { /* * we have been interrupted by signal (likely), * go check session_state */ continue; } ovfl_cnts[mycpu]++; pthread_testcancel(); if (aggr) pthread_mutex_lock(&pfmon_sys_aggr_lock); r = pfmon_process_smpl_buf(sdesc, 0); if (r) vbprintf("CPU%-4u error processing buffer\n", mycpu); if (aggr) pthread_mutex_unlock(&pfmon_sys_aggr_lock); pthread_testcancel(); } } else { sigset_t myset; int sig; sigemptyset(&myset); sigaddset(&myset, SIGUSR1); for(;session_state == SESSION_RUN;) { sigwait(&myset, &sig); } } } if (pfmon_stop(ctxid, &error) == -1) warning("CPU%u could not stop monitoring, CPU may be offline, check results\n", mycpu); vbprintf("CPU%-4u stopped monitoring\n", mycpu); /* * read the final counts */ if (options.opt_use_smpl == 0 || options.opt_smpl_print_counts) { if (read_results(sdesc) == -1) { warning("CPU%u read_results error\n", mycpu); goto error; } } DPRINT(("CPU%u has read PMDS\n", mycpu)); /* * dump results */ if (options.opt_aggr) { pthread_mutex_lock(&pfmon_sys_aggr_lock); syswide_aggregate_results(sdesc); if (options.opt_use_smpl) pfmon_process_smpl_buf(sdesc, 1); pthread_mutex_unlock(&pfmon_sys_aggr_lock); } else { if (options.opt_use_smpl) pfmon_process_smpl_buf(sdesc, 1); /* * no final totals in interval printing mode */ if (options.interval == PFMON_NO_TIMEOUT) show_results(sdesc, needs_order); close_results(sdesc); } if (options.opt_use_smpl) { if (options.opt_aggr == 0) pfmon_close_sampling_output(sdesc, -1, mycpu); munmap(sdesc->csmpl.smpl_hdr, sdesc->csmpl.map_size); } close(sdesc->ctxid); arg->thread_state = THREAD_DONE; DPRINT(("CPU%u is done\n", mycpu)); pthread_exit((void *)(0)); /* NO RETURN */ error: if (sdesc->ctxid > -1) close(sdesc->ctxid); arg->thread_state = THREAD_ERROR; vbprintf("CPU%-4u session aborted\n", mycpu); if (options.opt_use_smpl) { if (options.opt_aggr == 0) pfmon_close_sampling_output(sdesc, -1, mycpu); munmap(sdesc->csmpl.smpl_hdr, sdesc->csmpl.map_size); } pthread_exit((void *)(~0UL)); /* NO RETURN */ }
static int delimit_session(char **argv) { struct timeval time_start, time_end; time_t the_time; struct rusage ru; unsigned left_over; pid_t pid; int status; int ret = 0; /* * take care of the easy case first: no command to start */ if (argv == NULL || *argv == NULL) { if (options.trigger_delay && delay_start() == -1) return -1; /* * this will start the session in each "worker" thread */ pthread_barrier_wait(&barrier.barrier); time(&the_time); vbprintf("measurements started on %s\n", asctime(localtime(&the_time))); the_time = 0; if (options.session_timeout != PFMON_NO_TIMEOUT) { printf("<session to end in %u seconds>\n", options.session_timeout); left_over = sleep(options.session_timeout); if (left_over) pfmon_print_quit_reason(quit_reason); else time(&the_time); } else { printf("<press ENTER to stop session>\n"); ret = getchar(); if (ret == EOF) pfmon_print_quit_reason(quit_reason); else time(&the_time); } if (the_time) vbprintf("measurements completed at %s\n", asctime(localtime(&the_time))); return 0; } gettimeofday(&time_start, NULL); /* * we fork+exec the command to run during our system wide monitoring * session. When the command ends, we stop the session and print * the results. */ if ((pid=fork()) == -1) { warning("Cannot fork new process\n"); return -1; } if (pid == 0) { pid = getpid(); if (options.opt_verbose) { char **p = argv; vbprintf("starting process [%d]: ", pid); while (*p) vbprintf("%s ", *p++); vbprintf("\n"); } if (options.opt_pin_cmd) { vbprintf("applied cpu-list for %s\n", *argv); if (pfmon_set_affinity(pid, options.virt_cpu_mask)) { warning("could not pin %s to cpu-list\n"); } } /* * The use of ptrace() allows us to actually start monitoring after the exec() * is done, i.e., when the new program is ready to go back to user mode for the * "first time". With this technique, we can actually activate the workers * only when the process is ready to execute. Hence, we can capture even * the short lived workloads without measuring the overhead caused by fork/exec. * We will capture the overhead of the PTRACE_DETACH, though. */ if (options.trigger_delay == 0) { if (ptrace(PTRACE_TRACEME, 0, NULL, NULL) == -1) { warning("cannot ptrace me: %s\n", strerror(errno)); exit(1); } } if (options.opt_cmd_no_verbose) { dup2 (open("/dev/null", O_WRONLY), 1); dup2 (open("/dev/null", O_WRONLY), 2); } execvp(argv[0], argv); warning("child: cannot exec %s: %s\n", argv[0], strerror(errno)); exit(-1); } if (options.trigger_delay) { if (delay_start() == -1) { warning("process %d terminated before session was activated, nothing measured\n", pid); return -1; } } else { vbprintf("waiting for [%d] to exec\n", pid); /* * wait for the child to exec */ waitpid(pid, &status, WUNTRACED); } /* * this will start the session in each "worker" thread * */ pthread_barrier_wait(&barrier.barrier); /* * let the task run free now */ if (options.trigger_delay == 0) ptrace(PTRACE_DETACH, pid, NULL, NULL); ret = wait4(pid, &status, 0, &ru); gettimeofday(&time_end, NULL); if (ret == -1) { if (errno == EINTR) { pfmon_print_quit_reason(quit_reason); ret = 0; /* will cause the session to print results so far */ } else { vbprintf("unexpected wait() error for [%d]: %s\n", pid, strerror(errno)); } } else { if (WEXITSTATUS(status) != 0) { warning("process %d exited with non zero value (%d): results may be incorrect\n", pid, WEXITSTATUS(status)); } if (options.opt_show_rusage) show_task_rusage(&time_start, &time_end, &ru); } return ret; }
int measure_system_wide(pfmon_ctx_t *ctx, char **argv) { void *retval; unsigned long i, j, num_cpus; int ret; master_tid = gettid(); master_thread_id = pthread_self(); printf("sizeof=%zu %zu\n", sizeof(syswide_barrier_t), sizeof(barrier.pad)); setup_global_signals(); if (options.opt_aggr) { /* * used by syswide_aggregate_results() */ pfmon_clone_sets(options.sets, &sdesc_sys_aggr); if (pfmon_setup_aggr_sampling_output(&sdesc_sys_aggr) == -1) return -1; } session_state = SESSION_INIT; num_cpus = options.selected_cpus; vbprintf("system wide session on %lu processor(s)\n", num_cpus); pthread_barrier_init(&barrier.barrier, NULL, num_cpus+1); pthread_key_create(¶m_key, NULL); register_exit_function(exit_system_wide); for(i=0, j=0; num_cpus; i++) { if (pfmon_bitmask_isset(options.virt_cpu_mask, i) == 0) continue; thread_desc[j].id = j; thread_desc[j].cpu = i; thread_desc[j].thread_state = THREAD_STARTED; thread_desc[j].ctx = ctx; ret = pthread_create(&thread_desc[j].thread_id, NULL, (void *(*)(void *))do_measure_one_cpu, thread_desc+j); if (ret != 0) goto abort; DPRINT(("created thread[%u], %d\n", j, thread_desc[j].thread_id)); num_cpus--; j++; } /* reload number of cpus */ num_cpus = options.selected_cpus; for (j=0; j < num_cpus;) { DPRINT(("nthread_ok=%d ncpus=%d\n", j, num_cpus)); /* * poll thread state for errors */ for(i=0, j=0; i < num_cpus; i++) { if (thread_desc[i].thread_state == THREAD_ERROR) goto abort; if (thread_desc[i].thread_state == THREAD_RUN) j++; } } session_state = SESSION_RUN; if (delimit_session(argv) == -1) goto abort; /* * set end of session and unblock all threads */ session_state = SESSION_STOP; /* * get worker thread out of their mainloop */ for (i=0; i < num_cpus; i++) { if (thread_desc[i].thread_state != THREAD_ERROR) pthread_kill(thread_desc[i].thread_id, SIGUSR1); } DPRINT(("main thread after session stop\n")); for(i=0; i< num_cpus; i++) { ret = pthread_join(thread_desc[i].thread_id, &retval); if (ret !=0) warning("cannot join thread %u\n", i); DPRINT(("CPU%-4u session exited with value %ld\n", thread_desc[i].cpu, (unsigned long)retval)); } if (options.opt_aggr) { print_results(&sdesc_sys_aggr); /* mask taken from options.virt_cpu_mask */ if (options.opt_use_smpl) pfmon_close_aggr_sampling_output(&sdesc_sys_aggr); } pthread_key_delete(param_key); register_exit_function(NULL); if (options.opt_verbose && options.opt_use_smpl) { num_cpus = options.selected_cpus; for(i=0; num_cpus; i++) { if (pfmon_bitmask_isset(options.virt_cpu_mask, i)) { vbprintf("CPU%-4u %"PRIu64" sampling buffer overflows\n", i, ovfl_cnts[i]); num_cpus--; } } } return 0; abort: session_state = SESSION_ABORTED; if (session_state == SESSION_RUN) for (i=0; i < num_cpus; i++) if (thread_desc[i].thread_id) { DPRINT(("killing thread %d\n", i)); pthread_kill(thread_desc[i].thread_id, SIGUSR1); } num_cpus = options.selected_cpus; vbprintf("aborting %lu sessions\n", num_cpus); for(i=0; i < num_cpus; i++) { DPRINT(("cancelling on CPU%lu\n", i)); pthread_cancel(thread_desc[i].thread_id); } for(i=0; i < num_cpus; i++) { ret = pthread_join(thread_desc[i].thread_id, &retval); if (ret != 0) warning("cannot join thread %i\n", i); DPRINT(("CPU%-3d thread exited with value %ld\n", thread_desc[i].cpu, (unsigned long)retval)); } pthread_key_delete(param_key); register_exit_function(NULL); return -1; }
static void pfmon_ita_setup_btb(pfmon_event_set_t *set) { pfmlib_ita_input_param_t *param = set->mod_inp; pfmon_ita_args_t *ita_args; unsigned int i; ita_args = set->mod_args; /* * For pfmon, we do not activate the BTB registers unless a BRANCH_EVENT * is specified in the event list. The libpfm library does not have this restriction. * * XXX: must make sure BRANCH_EVENT shows up only once */ for (i=0; i < set->event_count; i++) { if (pfm_ita_is_btb(set->inp.pfp_events[i].event)) { goto found; } } /* * if the user specified a BTB option (but not the event) * then we program the BTB as a free running config. * * XXX: cannot record ALL branches */ if ( !ita_args->opt_btb_notar && !ita_args->opt_btb_notac && !ita_args->opt_btb_nobac && !ita_args->opt_btb_tm && !ita_args->opt_btb_ptm && !ita_args->opt_btb_ppm) return; found: /* * set the use bit, such that the library will program PMC12 */ param->pfp_ita_btb.btb_used = 1; /* by default, the registers are setup to * record every possible branch. * The record nothing is not available because it simply means * don't use a BTB event. * So the only thing the user can do is narrow down the type of * branches to record. This simplifies the number of cases quite * substantially. */ param->pfp_ita_btb.btb_tar = 1; param->pfp_ita_btb.btb_tac = 1; param->pfp_ita_btb.btb_bac = 1; param->pfp_ita_btb.btb_tm = 0x3; param->pfp_ita_btb.btb_ptm = 0x3; param->pfp_ita_btb.btb_ppm = 0x3; param->pfp_ita_btb.btb_plm = set->inp.pfp_events[i].plm; /* use the plm from the BTB event */ if (ita_args->opt_btb_notar) param->pfp_ita_btb.btb_tar = 0; if (ita_args->opt_btb_notac) param->pfp_ita_btb.btb_tac = 0; if (ita_args->opt_btb_nobac) param->pfp_ita_btb.btb_bac = 0; if (ita_args->opt_btb_tm) param->pfp_ita_btb.btb_tm = (unsigned char)ita_args->opt_btb_tm & 0x3; if (ita_args->opt_btb_ptm) param->pfp_ita_btb.btb_ptm = (unsigned char)ita_args->opt_btb_ptm & 0x3; if (ita_args->opt_btb_ppm) param->pfp_ita_btb.btb_ppm = (unsigned char)ita_args->opt_btb_ppm & 0x3; vbprintf("btb options:\n\tplm=%d tar=%c tac=%c bac=%c tm=%d ptm=%d ppm=%d\n", param->pfp_ita_btb.btb_plm, param->pfp_ita_btb.btb_tar ? 'Y' : 'N', param->pfp_ita_btb.btb_tac ? 'Y' : 'N', param->pfp_ita_btb.btb_bac ? 'Y' : 'N', param->pfp_ita_btb.btb_tm, param->pfp_ita_btb.btb_ptm, param->pfp_ita_btb.btb_ppm); }
static int inst_hist_process_samples(pfmon_sdesc_t *sdesc) { pfm_default_smpl_hdr_t *hdr; pfm_default_smpl_entry_t *ent; pfmon_smpl_desc_t *csmpl; uint64_t entry, count, skip; void *hash_desc, *data, *pos; hash_data_t *hash_entry; pfmon_hash_key_t key; int ret, pd_idx; size_t incr; uint16_t last_ovfl_pmd; uint32_t current_map_version; csmpl = &sdesc->csmpl; hdr = csmpl->smpl_hdr; if (hdr == NULL) return -1; hash_desc = csmpl->data; ent = (pfm_default_smpl_entry_t *)(hdr+1); pos = ent; entry = options.opt_aggr ? *csmpl->aggr_count : csmpl->entry_count; count = hdr->hdr_count; incr = 0; pd_idx = 0; last_ovfl_pmd = ~0; current_map_version = sdesc->current_map_version; DPRINT(("count=%"PRIu64" entry=%"PRIu64"\n", count, entry)); /* * check if we have new entries * if so skip the old entries and process only the new ones */ if((csmpl->last_ovfl == hdr->hdr_overflows && csmpl->last_count <= count) || ((csmpl->last_ovfl+1) == hdr->hdr_overflows && csmpl->last_count < count)) { skip = csmpl->last_count; vbprintf("[%d] skip %"PRIu64" samples out of %"PRIu64" (overflows: %"PRIu64")\n", sdesc->tid, skip, count, hdr->hdr_overflows); } else { skip = 0; } /* * only account for new entries, i.e., skip leftover entries */ if (options.opt_aggr) { *csmpl->aggr_count += count - skip; } else { csmpl->entry_count += count - skip; } csmpl->last_count = count; csmpl->last_ovfl = hdr->hdr_overflows; while(count--) { DPRINT(("entry %"PRIu64" PID:%d CPU:%d STAMP:0x%"PRIx64" OVF:%u IIP: %llx\n", entry, ent->pid, ent->cpu, ent->tstamp, ent->ovfl_pmd, (unsigned long long)ent->ip)); key.val = ent->ip; key.pid = ent->tgid; /* process id */ key.tid = ent->pid; key.version = current_map_version; if (ent->ovfl_pmd != last_ovfl_pmd) { pd_idx = sdesc->sets->rev_smpl_pmds[ent->ovfl_pmd].pd_idx; last_ovfl_pmd = ent->ovfl_pmd; incr =sdesc->sets->rev_smpl_pmds[ent->ovfl_pmd].num_smpl_pmds <<3; } /* * in aggregation mode sample processing is serialized, * therefore we are safe to use a single hash_table here */ // andrzejn: skip samples leftover from the previous call if(skip) { skip--; } else { ret = pfmon_hash_find(hash_desc, key, &data); hash_entry = data; if (ret == -1) { pfmon_hash_add(hash_desc, key, &data); hash_entry = data; hash_entry->count[pd_idx] = 0; hash_entry->key = key; } hash_entry->count[pd_idx]++; entry++; } /* skip over body */ pos += sizeof(*ent) + incr; ent = pos; } return 0; }