int key_bind(const char *context, const char *key, const char *cmd, int force) { const struct key *k; struct binding *b, *ptr, *prev; struct command *command; int c, size; c = find_context(context); if (c < 0) return -1; k = find_key(key); if (k == NULL) return -1; /* check if already bound */ b = find_binding(c, k); if (b) { if (!force) goto bound; key_unbind(context, key, 0); } if (*cmd == ':') cmd++; size = strlen(cmd) + 1; b = xmalloc(sizeof(struct binding) + size); b->key = k; b->ctx = c; memcpy(b->cmd, cmd, size); /* insert keeping sorted by key */ prev = NULL; ptr = key_bindings[c]; while (ptr) { if (strcmp(b->key->name, ptr->key->name) < 0) break; prev = ptr; ptr = ptr->next; } b->next = ptr; if (prev) { prev->next = b; } else { key_bindings[c] = b; } command = get_command(cmd); if (command && !command->bc++) help_remove_unbound(command); help_add_bound(b); return 0; bound: error_msg("key %s already bound in context %s", key, key_context_names[c]); return -1; }
msg(source, mc, data, vars) { string c; PT(("]] %O:msg(%O, %O, %O, %O)\n", ME, source, mc, data, vars)) if (mappingp(vars) && (c = vars["_context"]) && (c = find_context(c))) return c->castmsg(source, mc, data, vars); return 0; }
void fz_assert_lock_not_held(fz_context *ctx, int lock) { int idx = find_context(ctx); if (idx < 0) return; if (fz_locks_debug[idx][lock] != 0) fprintf(stderr, "Lock %d held when not expected\n", lock); }
/** * start_counting * * Arguments: <context_id> <event_set_id> * * Call the pfm_start system-call to start counting for a perfmon context * that was previously stopped. **/ static int start_counting(int argc, char **argv) { struct context *ctx; struct event_set *evt; cpu_set_t old_cpu_set; int ctx_id, event_set_id; int system_wide, rc; ctx_id = strtoul(argv[1], NULL, 0); event_set_id = strtoul(argv[2], NULL, 0); if (ctx_id <= 0 || event_set_id < 0) { LOG_ERROR("context ID and event-set ID must be " "positive integers."); return EINVAL; } ctx = find_context(ctx_id); if (!ctx) { LOG_ERROR("Can't find context with ID %d.", ctx_id); return EINVAL; } evt = find_event_set(ctx, event_set_id); if (!evt) { LOG_ERROR("Can't find event-set with ID %d in context %d.", event_set_id, ctx_id); return EINVAL; } system_wide = ctx->ctx_flags & PFM_FL_SYSTEM_WIDE; if (system_wide && ctx->cpu >= 0) { rc = set_affinity(ctx->cpu, &old_cpu_set); if (rc) { return rc; } } rc = pfm_set_state(ctx->fd, 0, PFM_ST_START); if (rc) { rc = errno; LOG_ERROR("pfm_set_state system call returned an error: %d.", rc); return rc; } if (system_wide && ctx->cpu >= 0) { revert_affinity(&old_cpu_set); } LOG_INFO("Started counting for context %d, event-set %d.", ctx_id, event_set_id); return 0; }
void fz_lock_debug_unlock(fz_context *ctx, int lock) { int idx = find_context(ctx); if (idx < 0) return; if (fz_locks_debug[idx][lock] == 0) { fprintf(stderr, "Attempt to release lock %d when not held!\n", lock); } fz_locks_debug[idx][lock] = 0; }
/* SIGSEGV/SIGBUS handler that catches segfaults; used unless configured with DEBUG */ void xsb_segfault_catcher(int err) { char *tmp_message = xsb_segfault_message; #ifdef MULTI_THREAD th_context *th = find_context(xsb_thread_self()); xsb_exit(th, tmp_message); #else xsb_segfault_message = xsb_default_segfault_msg; /* restore default */ printf("segfault!!\n"); xsb_basic_abort(tmp_message); #endif }
/** * unload_context * * Arguments: <context_id> * * Call the pfm_unload_context system-call to unload a perfmon context from * the system's performance monitoring unit. **/ static int unload_context(int argc, char **argv) { struct context *ctx; cpu_set_t old_cpu_set; int system_wide; int ctx_id; int rc; ctx_id = strtoul(argv[1], NULL, 0); if (ctx_id <= 0) { LOG_ERROR("context ID must be a positive integer."); return EINVAL; } ctx = find_context(ctx_id); if (!ctx) { LOG_ERROR("Can't find context with ID %d.", ctx_id); return EINVAL; } system_wide = ctx->ctx_flags & PFM_FL_SYSTEM_WIDE; if (system_wide) { if (ctx->cpu < 0) { /* This context isn't loaded on any CPU. */ LOG_ERROR("Trying to unload context %d that isn't " "loaded.\n", ctx_id); return EINVAL; } rc = set_affinity(ctx->cpu, &old_cpu_set); if (rc) { return rc; } } rc = pfm_attach(ctx->fd, 0, PFM_NO_TARGET); if (rc) { rc = errno; LOG_ERROR("pfm_attach(detach) system call returned " "an error: %d.", rc); return rc; } if (system_wide) { ctx->cpu = -1; revert_affinity(&old_cpu_set); } LOG_INFO("Unloaded context %d.", ctx_id); return 0; }
static void process_continue(int handle, void *cmd_body, uint16_t text_len, void *response_body, size_t *response_size) { struct test_context *context = find_context(handle); if (!context) { *((uint8_t *)response_body) = EXC_HASH_UNKNOWN_CONTEXT; *response_size = 1; return; } _cpri__UpdateHash(&context->hstate, text_len, cmd_body); }
void cancel_proc(int sig) { #ifdef MULTI_THREAD th_context *th = find_context(xsb_thread_self()); if (th->cond_var_ptr != NULL) pthread_cond_broadcast( th->cond_var_ptr ) ; #endif #ifndef LINUX init_interrupt(); /* reset interrupt, if using signal */ #endif // asynint_val |= THREADINT_MARK; asynint_code = 0; }
void fz_assert_lock_held(fz_context *ctx, int lock) { int idx; if (ctx->locks.lock != fz_lock_default) return; idx = find_context(ctx); if (idx < 0) return; if (fz_locks_debug[idx][lock] == 0) fprintf(stderr, "Lock %d not held when expected\n", lock); }
void gc_unmap(struct gcmap *gcmap) { struct gccontextmap *context; GCPRINT(GCDBGFILTER, GCZONE_MAPPING, "++" GC_MOD_PREFIX "\n", __func__, __LINE__); mutex_lock(&mtx); /* Locate the client entry. */ gcmap->gcerror = find_context(&context, true); if (gcmap->gcerror != GCERR_NONE) goto exit; context->context->mmu_dirty = true; GCPRINT(GCDBGFILTER, GCZONE_MAPPING, GC_MOD_PREFIX "unmap client buffer\n", __func__, __LINE__); GCPRINT(GCDBGFILTER, GCZONE_MAPPING, GC_MOD_PREFIX " size = %d\n", __func__, __LINE__, gcmap->size); GCPRINT(GCDBGFILTER, GCZONE_MAPPING, GC_MOD_PREFIX " handle = 0x%08X\n", __func__, __LINE__, gcmap->handle); /* Map the buffer. */ gcmap->gcerror = mmu2d_unmap(&context->context->mmu, (struct mmu2darena *) gcmap->handle); if (gcmap->gcerror != GCERR_NONE) goto exit; /* Invalidate the MMU. */ context->context->mmu_dirty = true; /* Invalidate the handle. */ gcmap->handle = ~0U; exit: mutex_unlock(&mtx); GCPRINT(GCDBGFILTER, GCZONE_MAPPING, "--" GC_MOD_PREFIX "gc%s = 0x%08X\n", __func__, __LINE__, (gcmap->gcerror == GCERR_NONE) ? "result" : "error", gcmap->gcerror); }
/* TLS: 2/02 removed "inline static" modifiers so that this function can be called from interprolog_callback.c */ void keyint_proc(int sig) { #ifdef MULTI_THREAD th_context *th = find_context(xsb_thread_self()); if (th->cond_var_ptr != NULL) pthread_cond_broadcast( th->cond_var_ptr ) ; #endif #ifndef LINUX init_interrupt(); /* reset interrupt, if using signal */ #endif if (asynint_val & KEYINT_MARK) { xsb_abort("unhandled keyboard interrupt"); } else { asynint_val |= KEYINT_MARK; asynint_code = 0; } }
int context_help(struct descriptor_data *d, char *arg) { int context; /* skip if context help isn't wanted */ if (strcmp(arg, CONTEXT_HELP_STRING)) return 0; context = find_context(d); if (context != NOTHING && context < NUM_CONTEXTS && *context_help_list[context]) { write_to_output(d, "\r\n%s\r\n", context_help_list[context]); } else { write_to_output(d, "\r\n%s\r\n", NO_HELP); } write_to_output(d, "> "); /* a sort-of prompt*/ return 1; }
/** * restart_counting * * Arguments: <context_id> * * Call the pfm_restart system-call to clear the data counters and start * counting from zero for a perfmon context that was previously loaded. **/ static int restart_counting(int argc, char **argv) { struct context *ctx; cpu_set_t old_cpu_set; int system_wide; int ctx_id; int rc; ctx_id = strtoul(argv[1], NULL, 0); if (ctx_id <= 0) { LOG_ERROR("context ID must be a positive integer."); return EINVAL; } ctx = find_context(ctx_id); if (!ctx) { LOG_ERROR("Can't find context with ID %d.", ctx_id); return EINVAL; } system_wide = ctx->ctx_flags & PFM_FL_SYSTEM_WIDE; if (system_wide && ctx->cpu >= 0) { rc = set_affinity(ctx->cpu, &old_cpu_set); if (rc) { return rc; } } rc = pfm_set_state(ctx->fd, 0, PFM_ST_RESTART); if (rc) { rc = errno; LOG_ERROR("pfm_set_state(restart) system call returned an error: %d.", rc); return rc; } if (system_wide && ctx->cpu >= 0) { revert_affinity(&old_cpu_set); } LOG_INFO("Restarted counting for context %d.", ctx_id); return 0; }
void fz_lock_debug_unlock(fz_context *ctx, int lock) { int idx; if (ctx->locks.lock != fz_lock_default) return; idx = find_context(ctx); if (idx < 0) return; if (fz_locks_debug[idx][lock] == 0) { fprintf(stderr, "Attempt to release lock %d when not held!\n", lock); } fz_locks_debug[idx][lock] = 0; #ifdef FITZ_DEBUG_LOCKING_TIMES fz_lock_time[idx][lock] += ms_clock() - fz_lock_taken[idx][lock]; #endif }
void fz_lock_debug_lock(fz_context *ctx, int lock) { int i; int idx = find_context(ctx); if (idx < 0) return; if (fz_locks_debug[idx][lock] != 0) { fprintf(stderr, "Attempt to take lock %d when held already!\n", lock); } for (i = lock-1; i >= 0; i--) { if (fz_locks_debug[idx][i] != 0) { fprintf(stderr, "Lock ordering violation: Attempt to take lock %d when %d held already!\n", lock, i); } } fz_locks_debug[idx][lock] = 1; }
void setProfileBit(void *place_holder) { #ifdef MULTI_THREAD th_context *th = find_context(xsb_thread_self()); #endif while (TRUE) { if (if_profiling) { if (garbage_collecting) { prof_gc_count++; } else { prof_int_count++; asynint_val |= PROFINT_MARK; } } #ifdef WIN_NT Sleep(10); #else usleep(10000); #endif } }
void show_binding(const char *context, const char *key) { const struct key *k; const struct binding *b; int c; c = find_context(context); if (c < 0) return; k = find_key(key); if (k == NULL) return; b = find_binding(c, k); if (b == NULL) { info_msg("No such binding"); } else { info_msg("bind %s %s %s", context, key, b->cmd); } }
void capiconn_inject(unsigned applid, unsigned char *msg) { capiconn_context *ctx = find_context(applid); if (!ctx) return; capi_message2cmsg(&s_cmsg, msg); if (s_cmsg.Command == CAPI_DATA_B3 && s_cmsg.Subcommand == CAPI_IND) { handle_data(ctx, &s_cmsg); ctx->nrecvdatapkt++; return; } if ((s_cmsg.adr.adrController & 0xffffff00) == 0) handle_controller(ctx, &s_cmsg); else if ((s_cmsg.adr.adrPLCI & 0xffff0000) == 0) handle_plci(ctx, &s_cmsg); else handle_ncci(ctx, &s_cmsg); ctx->nrecvctlpkt++; }
int key_unbind(const char *context, const char *key, int force) { int c; const struct key *k; struct binding *b, *prev; struct command *command; c = find_context(context); if (c < 0) return -1; k = find_key(key); if (k == NULL) return -1; prev = NULL; b = key_bindings[c]; while (b) { if (b->key == k) { if (prev) { prev->next = b->next; } else { key_bindings[c] = b->next; } command = get_command(b->cmd); if (command && !--command->bc) help_add_unbound(command); help_remove_bound(b); free(b); return 0; } prev = b; b = b->next; } if (!force) { error_msg("key %s not bound in context %s", key, context); return -1; } return 0; }
void reset_other_threads( th_context *th, th_context *ctxt, VariantSF sgf ) { th_context *tmp ; VariantSF resetsgf ; tmp = ctxt; while( tmp != th ) { tmp->tmp_next = find_context(tmp->waiting_for_tid) ; tmp->waiting_for_tid = -1 ; tmp = tmp->tmp_next ; } pthread_mutex_unlock( &completing_mut ); tmp = ctxt; while( tmp != th ) { reset_thread( th, tmp, sgf, &resetsgf ); sgf = tmp->waiting_for_subgoal; tmp->waiting_for_subgoal = resetsgf ; tmp->waiting_for_tid = xsb_thread_id ; tmp = tmp->tmp_next; } }
/* Converts the input string into a mask with bits for the modifiers */ Bool ParseModifiers(char *in_modifiers, int *out_modifier_mask) { return find_context(in_modifiers, out_modifier_mask, key_modifiers); }
/* Converts the input string into a mask with bits for the contexts */ Bool ParseContext(char *in_context, int *out_context_mask) { return find_context(in_context, out_context_mask, win_contexts); }
void gc_map(struct gcmap *gcmap) { struct mmu2dphysmem mem; struct mmu2darena *mapped = NULL; struct gccontextmap *context; GCPRINT(GCDBGFILTER, GCZONE_MAPPING, "++" GC_MOD_PREFIX "\n", __func__, __LINE__); mutex_lock(&mtx); /* Locate the client entry. */ gcmap->gcerror = find_context(&context, true); if (gcmap->gcerror != GCERR_NONE) goto exit; context->context->mmu_dirty = true; GCPRINT(GCDBGFILTER, GCZONE_MAPPING, GC_MOD_PREFIX "map client buffer\n", __func__, __LINE__); /* Initialize the mapping parameters. */ if (gcmap->pagearray == NULL) { mem.base = ((u32) gcmap->buf.logical) & ~(PAGE_SIZE - 1); mem.offset = ((u32) gcmap->buf.logical) & (PAGE_SIZE - 1); mem.pages = NULL; GCPRINT(GCDBGFILTER, GCZONE_MAPPING, GC_MOD_PREFIX " logical = 0x%08X\n", __func__, __LINE__, (unsigned int) gcmap->buf.logical); } else { mem.base = 0; mem.offset = gcmap->buf.offset; mem.pages = gcmap->pagearray; GCPRINT(GCDBGFILTER, GCZONE_MAPPING, GC_MOD_PREFIX " pagearray = 0x%08X\n", __func__, __LINE__, (unsigned int) gcmap->pagearray); } GCPRINT(GCDBGFILTER, GCZONE_MAPPING, GC_MOD_PREFIX " size = %d\n", __func__, __LINE__, gcmap->size); mem.count = DIV_ROUND_UP(gcmap->size + mem.offset, PAGE_SIZE); mem.pagesize = gcmap->pagesize ? gcmap->pagesize : PAGE_SIZE; /* Map the buffer. */ gcmap->gcerror = mmu2d_map(&context->context->mmu, &mem, &mapped); if (gcmap->gcerror != GCERR_NONE) goto exit; /* Invalidate the MMU. */ context->context->mmu_dirty = true; gcmap->handle = (unsigned int) mapped; GCPRINT(GCDBGFILTER, GCZONE_MAPPING, GC_MOD_PREFIX " mapped address = 0x%08X\n", __func__, __LINE__, mapped->address); GCPRINT(GCDBGFILTER, GCZONE_MAPPING, GC_MOD_PREFIX " handle = 0x%08X\n", __func__, __LINE__, (unsigned int) mapped); exit: mutex_unlock(&mtx); GCPRINT(GCDBGFILTER, GCZONE_MAPPING, "--" GC_MOD_PREFIX "gc%s = 0x%08X\n", __func__, __LINE__, (gcmap->gcerror == GCERR_NONE) ? "result" : "error", gcmap->gcerror); }
/**************************************************************************** * * Parses a mouse or key binding * ****************************************************************************/ void ParseBindEntry(XEvent *eventp,Window w,FvwmWindow *tmp_win, unsigned long junk, char *tline,int* Module, Bool fKey) { char *action,context[20],modifiers[20],key[20],*ptr, *token; Binding *temp; int button,i,min,max; int n1=0,n2=0,n3=0; KeySym keysym; KeySym tkeysym; int contexts; int mods; int maxmods; int m; /* tline points after the key word "Mouse" or "Key" */ ptr = GetNextToken(tline, &token); if(token != NULL) { if (fKey) n1 = sscanf(token,"%19s",key); else n1 = sscanf(token,"%d",&button); free(token); } ptr = GetNextToken(ptr,&token); if(token != NULL) { n2 = sscanf(token,"%19s",context); free(token); } action = GetNextToken(ptr,&token); if(token != NULL) { n3 = sscanf(token,"%19s",modifiers); free(token); } if((n1 != 1)||(n2 != 1)||(n3 != 1)) { fvwm_msg(ERR,"ParseBindEntry","Syntax error in line %s",tline); return; } find_context(context,&contexts,win_contexts,tline); find_context(modifiers,&mods,key_modifiers,tline); if (fKey) { /* * Don't let a 0 keycode go through, since that means AnyKey to the * XGrabKey call in GrabKeys(). */ if ((keysym = XStringToKeysym(key)) == NoSymbol || (XKeysymToKeycode(dpy, keysym)) == 0) return; } /* ** strip leading whitespace from action if necessary */ while (*action && (*action == ' ' || *action == '\t')) action++; /* ** is this an unbind request? */ if (!action || action[0] == '-') { if (fKey) remove_binding(contexts,mods,0,keysym,0); else remove_binding(contexts,mods,button,0,1); return; } if (!fKey) { int j; if((contexts != C_ALL) && (contexts & C_LALL)) { /* check for nr_left_buttons */ i=0; j=(contexts &C_LALL)/C_L1; while(j>0) { i++; j=j>>1; } if(Scr.nr_left_buttons <i) Scr.nr_left_buttons = i; }
/** * read_pmd * * Arguments: <context_id> <event_set_id> <pmd_id>+ * * FIXME: Add options for other fields in pfarg_pmd_t. **/ static int read_pmd(int argc, char **argv) { struct context *ctx; struct event_set *evt; pfarg_pmr_t *pmd_args = NULL; cpu_set_t old_cpu_set; int ctx_id, event_set_id; int pmd_id, num_pmds; int system_wide, i, rc; ctx_id = strtoul(argv[1], NULL, 0); event_set_id = strtoul(argv[2], NULL, 0); if (ctx_id <= 0 || event_set_id < 0) { LOG_ERROR("context ID and event-set ID must be " "positive integers."); return EINVAL; } ctx = find_context(ctx_id); if (!ctx) { LOG_ERROR("Can't find context with ID %d.", ctx_id); return EINVAL; } evt = find_event_set(ctx, event_set_id); if (!evt) { LOG_ERROR("Can't find event-set with ID %d in context %d.", event_set_id, ctx_id); return EINVAL; } /* Allocate an array of PMD structures. */ num_pmds = argc - 3; pmd_args = calloc(num_pmds, sizeof(*pmd_args)); if (!pmd_args) { LOG_ERROR("Can't allocate PMD argument array."); return ENOMEM; } for (i = 0; i < num_pmds; i++) { pmd_id = strtoul(argv[3 + i], NULL, 0); if (pmd_id < 0) { LOG_ERROR("PMD ID must be a positive integer."); rc = EINVAL; goto out; } pmd_args[i].reg_num = pmd_id; pmd_args[i].reg_set = evt->id; } system_wide = ctx->ctx_flags & PFM_FL_SYSTEM_WIDE; if (system_wide && ctx->cpu >= 0) { rc = set_affinity(ctx->cpu, &old_cpu_set); if (rc) { goto out; } } rc = pfm_read(ctx->fd, 0, PFM_RW_PMD, pmd_args, num_pmds * sizeof(*pmd_args)); if (rc) { rc = errno; LOG_ERROR("pfm_read system call returned " "an error: %d.", rc); goto out; } if (system_wide && ctx->cpu >= 0) { revert_affinity(&old_cpu_set); } out: free(pmd_args); return rc; }
/** * load_context * * Arguments: <context_id> <event_set_id> <program_id|cpu_id> * * Call the pfm_load_context system-call to load a perfmon context into the * system's performance monitoring unit. **/ static int load_context(int argc, char **argv) { struct context *ctx; struct event_set *evt; struct program *prog; cpu_set_t old_cpu_set; int ctx_id, event_set_id, program_id; int system_wide, rc; int load_pid = 0; ctx_id = strtoul(argv[1], NULL, 0); event_set_id = strtoul(argv[2], NULL, 0); program_id = strtoul(argv[3], NULL, 0); if (ctx_id <= 0 || event_set_id < 0 || program_id < 0) { LOG_ERROR("context ID, event-set ID, and program/CPU ID must " "be positive integers."); return EINVAL; } /* Find the context, event_set, and program in the global lists. */ ctx = find_context(ctx_id); if (!ctx) { LOG_ERROR("Can't find context with ID %d.", ctx_id); return EINVAL; } evt = find_event_set(ctx, event_set_id); if (!evt) { LOG_ERROR("Can't find event-set with ID %d in context %d.", event_set_id, ctx_id); return EINVAL; } system_wide = ctx->ctx_flags & PFM_FL_SYSTEM_WIDE; if (system_wide) { if (ctx->cpu >= 0) { LOG_ERROR("Trying to load context %d which is already " "loaded on CPU %d.\n", ctx_id, ctx->cpu); return EBUSY; } rc = set_affinity(program_id, &old_cpu_set); if (rc) { return rc; } /* Specify the CPU as the PID. */ load_pid = program_id; } else { prog = find_program(program_id); if (!prog) { LOG_ERROR("Can't find program with ID %d.", program_id); return EINVAL; } load_pid = prog->pid; } rc = pfm_attach(ctx->fd, 0, load_pid); if (rc) { rc = errno; LOG_ERROR("pfm_attach system call returned " "an error: %d.", rc); return rc; } if (system_wide) { /* Keep track of which CPU this context is loaded on. */ ctx->cpu = program_id; revert_affinity(&old_cpu_set); } LOG_INFO("Loaded context %d, event-set %d onto %s %d.", ctx_id, event_set_id, system_wide ? "cpu" : "program", program_id); return 0; }
/** * create_context * * Arguments: [options] <context_id> * Options: --system * --no-overflow-msg * --block-on-notify * --sampler <sampler_name> * * Call the pfm_create_context system-call to create a new perfmon context. * Add a new entry to the global 'contexts' list. **/ static int create_context(int argc, char **argv) { pfm_dfl_smpl_arg_t smpl_arg; struct context *new_ctx = NULL; char *sampler_name = NULL; void *smpl_p; int no_overflow_msg = FALSE; int block_on_notify = FALSE; int system_wide = FALSE; int c, ctx_id = 0; int rc; uint32_t ctx_flags; size_t sz; struct option long_opts[] = { {"sampler", required_argument, NULL, 1}, {"system", no_argument, NULL, 2}, {"no-overflow-msg", no_argument, NULL, 3}, {"block-on-notify", no_argument, NULL, 4}, {NULL, 0, NULL, 0} }; ctx_flags = 0; opterr = 0; optind = 0; while ((c = getopt_long_only(argc, argv, "", long_opts, NULL)) != EOF) { switch (c) { case 1: sampler_name = optarg; break; case 2: system_wide = TRUE; break; case 3: no_overflow_msg = TRUE; break; case 4: block_on_notify = TRUE; break; default: LOG_ERROR("invalid option: %c", optopt); rc = EINVAL; goto error; } } if (argc < optind + 1) { USAGE("create_context [options] <context_id>"); rc = EINVAL; goto error; } ctx_id = strtoul(argv[optind], NULL, 0); if (ctx_id <= 0) { LOG_ERROR("Invalid context ID (%s). Must be a positive " "integer.", argv[optind]); rc = EINVAL; goto error; } /* Make sure we don't already have a context with this ID. */ new_ctx = find_context(ctx_id); if (new_ctx) { LOG_ERROR("Context with ID %d already exists.", ctx_id); rc = EINVAL; goto error; } if (sampler_name) { smpl_arg.buf_size = getpagesize(); smpl_p = &smpl_arg; sz = sizeof(smpl_arg); } else { smpl_p = NULL; sz = 0; } ctx_flags = (system_wide ? PFM_FL_SYSTEM_WIDE : 0) | (no_overflow_msg ? PFM_FL_OVFL_NO_MSG : 0) | (block_on_notify ? PFM_FL_NOTIFY_BLOCK : 0); if (sampler_name) ctx_flags |= PFM_FL_SMPL_FMT; rc = pfm_create(ctx_flags, NULL, sampler_name, smpl_p, sz); if (rc == -1) { rc = errno; LOG_ERROR("pfm_create_context system call returned " "an error: %d.", rc); goto error; } /* Allocate and initialize a new context structure and add it to the * global list. Every new context automatically gets one event_set * with an event ID of 0. */ new_ctx = calloc(1, sizeof(*new_ctx)); if (!new_ctx) { LOG_ERROR("Can't allocate structure for new context %d.", ctx_id); rc = ENOMEM; goto error; } new_ctx->event_sets = calloc(1, sizeof(*(new_ctx->event_sets))); if (!new_ctx->event_sets) { LOG_ERROR("Can't allocate event-set structure for new " "context %d.", ctx_id); rc = ENOMEM; goto error; } new_ctx->id = ctx_id; new_ctx->fd = rc; new_ctx->cpu = -1; new_ctx->ctx_flags = ctx_flags; new_ctx->smpl_arg = smpl_arg; insert_context(new_ctx); LOG_INFO("Created context %d with file-descriptor %d.", new_ctx->id, new_ctx->fd); return 0; error: if (new_ctx) { close(new_ctx->fd); free(new_ctx->event_sets); free(new_ctx); } return rc; }
/** * getinfo_eventset * * Arguments: <context_id> <event_set_id> **/ static int getinfo_eventset(int argc, char **argv) { pfarg_set_info_t set_arg; struct context *ctx; struct event_set *evt; cpu_set_t old_cpu_set; int ctx_id, event_set_id; int system_wide, rc; memset(&set_arg, 0, sizeof(set_arg)); ctx_id = strtoul(argv[1], NULL, 0); event_set_id = strtoul(argv[2], NULL, 0); if (ctx_id <= 0 || event_set_id < 0) { LOG_ERROR("context ID and event-set ID must be " "positive integers."); return EINVAL; } ctx = find_context(ctx_id); if (!ctx) { LOG_ERROR("Can't find context with ID %d.", ctx_id); return EINVAL; } evt = find_event_set(ctx, event_set_id); if (!evt) { LOG_ERROR("Can't find event-set with ID %d in context %d.", event_set_id, ctx_id); return EINVAL; } set_arg.set_id = evt->id; system_wide = ctx->ctx_flags & PFM_FL_SYSTEM_WIDE; if (system_wide && ctx->cpu >= 0) { rc = set_affinity(ctx->cpu, &old_cpu_set); if (rc) { return rc; } } rc = pfm_getinfo_sets(ctx->fd, 0, &set_arg, 1); if (rc) { rc = errno; LOG_ERROR("pfm_getinfo_evtsets system call returned " "an error: %d.", rc); return rc; } if (system_wide && ctx->cpu >= 0) { revert_affinity(&old_cpu_set); } LOG_INFO("Got info for event-set %d in context %d.", event_set_id, ctx_id); LOG_INFO(" Runs: %llu", (unsigned long long)set_arg.set_runs); LOG_INFO(" Timeout: %"PRIu64, set_arg.set_timeout); return 0; }
/** * create_eventset * * Arguments: [options] <context_id> <event_set_id> * Options: --timeout <nanoseconds> * --switch-on-overflow * --exclude-idle **/ static int create_eventset(int argc, char **argv) { pfarg_set_desc_t set_arg; struct context *ctx; struct event_set *evt; cpu_set_t old_cpu_set; int ctx_id, event_set_id; unsigned long timeout = 0; int switch_on_overflow = FALSE; int switch_on_timeout = FALSE; int exclude_idle = FALSE; int new_set = FALSE; int system_wide,c, rc; struct option long_opts[] = { {"next-set", required_argument, NULL, 1}, {"timeout", required_argument, NULL, 2}, {"switch-on-overflow", no_argument, NULL, 3}, {"exclude-idle", no_argument, NULL, 4}, {NULL, 0, NULL, 0} }; memset(&set_arg, 0, sizeof(set_arg)); opterr = 0; optind = 0; while ((c = getopt_long_only(argc, argv, "", long_opts, NULL)) != EOF) { switch (c) { case 1: timeout = strtoul(optarg, NULL, 0); if (!timeout) { LOG_ERROR("timeout must be a " "non-zero integer."); return EINVAL; } switch_on_timeout = TRUE; break; case 2: switch_on_overflow = TRUE; break; case 3: exclude_idle = TRUE; break; default: LOG_ERROR("invalid option: %c", optopt); return EINVAL; } } if (argc < optind + 2) { USAGE("create_eventset [options] <context_id> <event_set_id>"); return EINVAL; } ctx_id = strtoul(argv[optind], NULL, 0); event_set_id = strtoul(argv[optind+1], NULL, 0); if (ctx_id <= 0 || event_set_id < 0) { LOG_ERROR("context ID and event-set ID must be " "positive integers."); return EINVAL; } ctx = find_context(ctx_id); if (!ctx) { LOG_ERROR("Can't find context with ID %d.", ctx_id); return EINVAL; } if (switch_on_timeout && switch_on_overflow) { LOG_ERROR("Cannot switch set %d (context %d) on both " "timeout and overflow.", event_set_id, ctx_id); return EINVAL; } evt = find_event_set(ctx, event_set_id); if (!evt) { evt = calloc(1, sizeof(*evt)); if (!evt) { LOG_ERROR("Can't allocate structure for new event-set " "%d in context %d.", event_set_id, ctx_id); return ENOMEM; } evt->id = event_set_id; new_set = TRUE; } set_arg.set_id = event_set_id; set_arg.set_timeout = timeout; /* in nanseconds */ set_arg.set_flags = (switch_on_overflow ? PFM_SETFL_OVFL_SWITCH : 0) | (switch_on_timeout ? PFM_SETFL_TIME_SWITCH : 0); system_wide = ctx->ctx_flags & PFM_FL_SYSTEM_WIDE; if (system_wide && ctx->cpu >= 0) { rc = set_affinity(ctx->cpu, &old_cpu_set); if (rc) { free(evt); return rc; } } rc = pfm_create_sets(ctx->fd, 0, &set_arg, 1); if (rc) { rc = errno; LOG_ERROR("pfm_create_sets system call returned " "an error: %d.", rc); free(evt); return rc; } if (system_wide && ctx->cpu >= 0) { revert_affinity(&old_cpu_set); } if (new_set) { insert_event_set(ctx, evt); } LOG_INFO("%s event-set %d in context %d.", new_set ? "Created" : "Modified", event_set_id, ctx_id); if (switch_on_timeout) { LOG_INFO(" Actual timeout set to %llu ns.", (unsigned long long)set_arg.set_timeout); } return 0; }