diff options
Diffstat (limited to 'tools/lib/traceevent/event-parse.c')
| -rw-r--r-- | tools/lib/traceevent/event-parse.c | 129 |
1 files changed, 82 insertions, 47 deletions
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index 69a96e39f0ab..abd4fa5d3088 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c | |||
| @@ -124,15 +124,15 @@ struct tep_print_arg *alloc_arg(void) | |||
| 124 | return calloc(1, sizeof(struct tep_print_arg)); | 124 | return calloc(1, sizeof(struct tep_print_arg)); |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | struct cmdline { | 127 | struct tep_cmdline { |
| 128 | char *comm; | 128 | char *comm; |
| 129 | int pid; | 129 | int pid; |
| 130 | }; | 130 | }; |
| 131 | 131 | ||
| 132 | static int cmdline_cmp(const void *a, const void *b) | 132 | static int cmdline_cmp(const void *a, const void *b) |
| 133 | { | 133 | { |
| 134 | const struct cmdline *ca = a; | 134 | const struct tep_cmdline *ca = a; |
| 135 | const struct cmdline *cb = b; | 135 | const struct tep_cmdline *cb = b; |
| 136 | 136 | ||
| 137 | if (ca->pid < cb->pid) | 137 | if (ca->pid < cb->pid) |
| 138 | return -1; | 138 | return -1; |
| @@ -152,7 +152,7 @@ static int cmdline_init(struct tep_handle *pevent) | |||
| 152 | { | 152 | { |
| 153 | struct cmdline_list *cmdlist = pevent->cmdlist; | 153 | struct cmdline_list *cmdlist = pevent->cmdlist; |
| 154 | struct cmdline_list *item; | 154 | struct cmdline_list *item; |
| 155 | struct cmdline *cmdlines; | 155 | struct tep_cmdline *cmdlines; |
| 156 | int i; | 156 | int i; |
| 157 | 157 | ||
| 158 | cmdlines = malloc(sizeof(*cmdlines) * pevent->cmdline_count); | 158 | cmdlines = malloc(sizeof(*cmdlines) * pevent->cmdline_count); |
| @@ -179,8 +179,8 @@ static int cmdline_init(struct tep_handle *pevent) | |||
| 179 | 179 | ||
| 180 | static const char *find_cmdline(struct tep_handle *pevent, int pid) | 180 | static const char *find_cmdline(struct tep_handle *pevent, int pid) |
| 181 | { | 181 | { |
| 182 | const struct cmdline *comm; | 182 | const struct tep_cmdline *comm; |
| 183 | struct cmdline key; | 183 | struct tep_cmdline key; |
| 184 | 184 | ||
| 185 | if (!pid) | 185 | if (!pid) |
| 186 | return "<idle>"; | 186 | return "<idle>"; |
| @@ -208,8 +208,8 @@ static const char *find_cmdline(struct tep_handle *pevent, int pid) | |||
| 208 | */ | 208 | */ |
| 209 | int tep_pid_is_registered(struct tep_handle *pevent, int pid) | 209 | int tep_pid_is_registered(struct tep_handle *pevent, int pid) |
| 210 | { | 210 | { |
| 211 | const struct cmdline *comm; | 211 | const struct tep_cmdline *comm; |
| 212 | struct cmdline key; | 212 | struct tep_cmdline key; |
| 213 | 213 | ||
| 214 | if (!pid) | 214 | if (!pid) |
| 215 | return 1; | 215 | return 1; |
| @@ -232,11 +232,13 @@ int tep_pid_is_registered(struct tep_handle *pevent, int pid) | |||
| 232 | * we must add this pid. This is much slower than when cmdlines | 232 | * we must add this pid. This is much slower than when cmdlines |
| 233 | * are added before the array is initialized. | 233 | * are added before the array is initialized. |
| 234 | */ | 234 | */ |
| 235 | static int add_new_comm(struct tep_handle *pevent, const char *comm, int pid) | 235 | static int add_new_comm(struct tep_handle *pevent, |
| 236 | const char *comm, int pid, bool override) | ||
| 236 | { | 237 | { |
| 237 | struct cmdline *cmdlines = pevent->cmdlines; | 238 | struct tep_cmdline *cmdlines = pevent->cmdlines; |
| 238 | const struct cmdline *cmdline; | 239 | struct tep_cmdline *cmdline; |
| 239 | struct cmdline key; | 240 | struct tep_cmdline key; |
| 241 | char *new_comm; | ||
| 240 | 242 | ||
| 241 | if (!pid) | 243 | if (!pid) |
| 242 | return 0; | 244 | return 0; |
| @@ -247,8 +249,19 @@ static int add_new_comm(struct tep_handle *pevent, const char *comm, int pid) | |||
| 247 | cmdline = bsearch(&key, pevent->cmdlines, pevent->cmdline_count, | 249 | cmdline = bsearch(&key, pevent->cmdlines, pevent->cmdline_count, |
| 248 | sizeof(*pevent->cmdlines), cmdline_cmp); | 250 | sizeof(*pevent->cmdlines), cmdline_cmp); |
| 249 | if (cmdline) { | 251 | if (cmdline) { |
| 250 | errno = EEXIST; | 252 | if (!override) { |
| 251 | return -1; | 253 | errno = EEXIST; |
| 254 | return -1; | ||
| 255 | } | ||
| 256 | new_comm = strdup(comm); | ||
| 257 | if (!new_comm) { | ||
| 258 | errno = ENOMEM; | ||
| 259 | return -1; | ||
| 260 | } | ||
| 261 | free(cmdline->comm); | ||
| 262 | cmdline->comm = new_comm; | ||
| 263 | |||
| 264 | return 0; | ||
| 252 | } | 265 | } |
| 253 | 266 | ||
| 254 | cmdlines = realloc(cmdlines, sizeof(*cmdlines) * (pevent->cmdline_count + 1)); | 267 | cmdlines = realloc(cmdlines, sizeof(*cmdlines) * (pevent->cmdline_count + 1)); |
| @@ -275,21 +288,13 @@ static int add_new_comm(struct tep_handle *pevent, const char *comm, int pid) | |||
| 275 | return 0; | 288 | return 0; |
| 276 | } | 289 | } |
| 277 | 290 | ||
| 278 | /** | 291 | static int _tep_register_comm(struct tep_handle *pevent, |
| 279 | * tep_register_comm - register a pid / comm mapping | 292 | const char *comm, int pid, bool override) |
| 280 | * @pevent: handle for the pevent | ||
| 281 | * @comm: the command line to register | ||
| 282 | * @pid: the pid to map the command line to | ||
| 283 | * | ||
| 284 | * This adds a mapping to search for command line names with | ||
| 285 | * a given pid. The comm is duplicated. | ||
| 286 | */ | ||
| 287 | int tep_register_comm(struct tep_handle *pevent, const char *comm, int pid) | ||
| 288 | { | 293 | { |
| 289 | struct cmdline_list *item; | 294 | struct cmdline_list *item; |
| 290 | 295 | ||
| 291 | if (pevent->cmdlines) | 296 | if (pevent->cmdlines) |
| 292 | return add_new_comm(pevent, comm, pid); | 297 | return add_new_comm(pevent, comm, pid, override); |
| 293 | 298 | ||
| 294 | item = malloc(sizeof(*item)); | 299 | item = malloc(sizeof(*item)); |
| 295 | if (!item) | 300 | if (!item) |
| @@ -312,6 +317,40 @@ int tep_register_comm(struct tep_handle *pevent, const char *comm, int pid) | |||
| 312 | return 0; | 317 | return 0; |
| 313 | } | 318 | } |
| 314 | 319 | ||
| 320 | /** | ||
| 321 | * tep_register_comm - register a pid / comm mapping | ||
| 322 | * @pevent: handle for the pevent | ||
| 323 | * @comm: the command line to register | ||
| 324 | * @pid: the pid to map the command line to | ||
| 325 | * | ||
| 326 | * This adds a mapping to search for command line names with | ||
| 327 | * a given pid. The comm is duplicated. If a command with the same pid | ||
| 328 | * already exist, -1 is returned and errno is set to EEXIST | ||
| 329 | */ | ||
| 330 | int tep_register_comm(struct tep_handle *pevent, const char *comm, int pid) | ||
| 331 | { | ||
| 332 | return _tep_register_comm(pevent, comm, pid, false); | ||
| 333 | } | ||
| 334 | |||
| 335 | /** | ||
| 336 | * tep_override_comm - register a pid / comm mapping | ||
| 337 | * @pevent: handle for the pevent | ||
| 338 | * @comm: the command line to register | ||
| 339 | * @pid: the pid to map the command line to | ||
| 340 | * | ||
| 341 | * This adds a mapping to search for command line names with | ||
| 342 | * a given pid. The comm is duplicated. If a command with the same pid | ||
| 343 | * already exist, the command string is udapted with the new one | ||
| 344 | */ | ||
| 345 | int tep_override_comm(struct tep_handle *pevent, const char *comm, int pid) | ||
| 346 | { | ||
| 347 | if (!pevent->cmdlines && cmdline_init(pevent)) { | ||
| 348 | errno = ENOMEM; | ||
| 349 | return -1; | ||
| 350 | } | ||
| 351 | return _tep_register_comm(pevent, comm, pid, true); | ||
| 352 | } | ||
| 353 | |||
| 315 | int tep_register_trace_clock(struct tep_handle *pevent, const char *trace_clock) | 354 | int tep_register_trace_clock(struct tep_handle *pevent, const char *trace_clock) |
| 316 | { | 355 | { |
| 317 | pevent->trace_clock = strdup(trace_clock); | 356 | pevent->trace_clock = strdup(trace_clock); |
| @@ -5227,18 +5266,6 @@ int tep_data_type(struct tep_handle *pevent, struct tep_record *rec) | |||
| 5227 | } | 5266 | } |
| 5228 | 5267 | ||
| 5229 | /** | 5268 | /** |
| 5230 | * tep_data_event_from_type - find the event by a given type | ||
| 5231 | * @pevent: a handle to the pevent | ||
| 5232 | * @type: the type of the event. | ||
| 5233 | * | ||
| 5234 | * This returns the event form a given @type; | ||
| 5235 | */ | ||
| 5236 | struct tep_event *tep_data_event_from_type(struct tep_handle *pevent, int type) | ||
| 5237 | { | ||
| 5238 | return tep_find_event(pevent, type); | ||
| 5239 | } | ||
| 5240 | |||
| 5241 | /** | ||
| 5242 | * tep_data_pid - parse the PID from record | 5269 | * tep_data_pid - parse the PID from record |
| 5243 | * @pevent: a handle to the pevent | 5270 | * @pevent: a handle to the pevent |
| 5244 | * @rec: the record to parse | 5271 | * @rec: the record to parse |
| @@ -5292,8 +5319,8 @@ const char *tep_data_comm_from_pid(struct tep_handle *pevent, int pid) | |||
| 5292 | return comm; | 5319 | return comm; |
| 5293 | } | 5320 | } |
| 5294 | 5321 | ||
| 5295 | static struct cmdline * | 5322 | static struct tep_cmdline * |
| 5296 | pid_from_cmdlist(struct tep_handle *pevent, const char *comm, struct cmdline *next) | 5323 | pid_from_cmdlist(struct tep_handle *pevent, const char *comm, struct tep_cmdline *next) |
| 5297 | { | 5324 | { |
| 5298 | struct cmdline_list *cmdlist = (struct cmdline_list *)next; | 5325 | struct cmdline_list *cmdlist = (struct cmdline_list *)next; |
| 5299 | 5326 | ||
| @@ -5305,7 +5332,7 @@ pid_from_cmdlist(struct tep_handle *pevent, const char *comm, struct cmdline *ne | |||
| 5305 | while (cmdlist && strcmp(cmdlist->comm, comm) != 0) | 5332 | while (cmdlist && strcmp(cmdlist->comm, comm) != 0) |
| 5306 | cmdlist = cmdlist->next; | 5333 | cmdlist = cmdlist->next; |
| 5307 | 5334 | ||
| 5308 | return (struct cmdline *)cmdlist; | 5335 | return (struct tep_cmdline *)cmdlist; |
| 5309 | } | 5336 | } |
| 5310 | 5337 | ||
| 5311 | /** | 5338 | /** |
| @@ -5321,10 +5348,10 @@ pid_from_cmdlist(struct tep_handle *pevent, const char *comm, struct cmdline *ne | |||
| 5321 | * next pid. | 5348 | * next pid. |
| 5322 | * Also, it does a linear search, so it may be slow. | 5349 | * Also, it does a linear search, so it may be slow. |
| 5323 | */ | 5350 | */ |
| 5324 | struct cmdline *tep_data_pid_from_comm(struct tep_handle *pevent, const char *comm, | 5351 | struct tep_cmdline *tep_data_pid_from_comm(struct tep_handle *pevent, const char *comm, |
| 5325 | struct cmdline *next) | 5352 | struct tep_cmdline *next) |
| 5326 | { | 5353 | { |
| 5327 | struct cmdline *cmdline; | 5354 | struct tep_cmdline *cmdline; |
| 5328 | 5355 | ||
| 5329 | /* | 5356 | /* |
| 5330 | * If the cmdlines have not been converted yet, then use | 5357 | * If the cmdlines have not been converted yet, then use |
| @@ -5363,7 +5390,7 @@ struct cmdline *tep_data_pid_from_comm(struct tep_handle *pevent, const char *co | |||
| 5363 | * Returns the pid for a give cmdline. If @cmdline is NULL, then | 5390 | * Returns the pid for a give cmdline. If @cmdline is NULL, then |
| 5364 | * -1 is returned. | 5391 | * -1 is returned. |
| 5365 | */ | 5392 | */ |
| 5366 | int tep_cmdline_pid(struct tep_handle *pevent, struct cmdline *cmdline) | 5393 | int tep_cmdline_pid(struct tep_handle *pevent, struct tep_cmdline *cmdline) |
| 5367 | { | 5394 | { |
| 5368 | struct cmdline_list *cmdlist = (struct cmdline_list *)cmdline; | 5395 | struct cmdline_list *cmdlist = (struct cmdline_list *)cmdline; |
| 5369 | 5396 | ||
| @@ -6593,6 +6620,12 @@ static struct tep_event *search_event(struct tep_handle *pevent, int id, | |||
| 6593 | * | 6620 | * |
| 6594 | * If @id is >= 0, then it is used to find the event. | 6621 | * If @id is >= 0, then it is used to find the event. |
| 6595 | * else @sys_name and @event_name are used. | 6622 | * else @sys_name and @event_name are used. |
| 6623 | * | ||
| 6624 | * Returns: | ||
| 6625 | * TEP_REGISTER_SUCCESS_OVERWRITE if an existing handler is overwritten | ||
| 6626 | * TEP_REGISTER_SUCCESS if a new handler is registered successfully | ||
| 6627 | * negative TEP_ERRNO_... in case of an error | ||
| 6628 | * | ||
| 6596 | */ | 6629 | */ |
| 6597 | int tep_register_event_handler(struct tep_handle *pevent, int id, | 6630 | int tep_register_event_handler(struct tep_handle *pevent, int id, |
| 6598 | const char *sys_name, const char *event_name, | 6631 | const char *sys_name, const char *event_name, |
| @@ -6610,7 +6643,7 @@ int tep_register_event_handler(struct tep_handle *pevent, int id, | |||
| 6610 | 6643 | ||
| 6611 | event->handler = func; | 6644 | event->handler = func; |
| 6612 | event->context = context; | 6645 | event->context = context; |
| 6613 | return 0; | 6646 | return TEP_REGISTER_SUCCESS_OVERWRITE; |
| 6614 | 6647 | ||
| 6615 | not_found: | 6648 | not_found: |
| 6616 | /* Save for later use. */ | 6649 | /* Save for later use. */ |
| @@ -6640,7 +6673,7 @@ int tep_register_event_handler(struct tep_handle *pevent, int id, | |||
| 6640 | pevent->handlers = handle; | 6673 | pevent->handlers = handle; |
| 6641 | handle->context = context; | 6674 | handle->context = context; |
| 6642 | 6675 | ||
| 6643 | return -1; | 6676 | return TEP_REGISTER_SUCCESS; |
| 6644 | } | 6677 | } |
| 6645 | 6678 | ||
| 6646 | static int handle_matches(struct event_handler *handler, int id, | 6679 | static int handle_matches(struct event_handler *handler, int id, |
| @@ -6723,8 +6756,10 @@ struct tep_handle *tep_alloc(void) | |||
| 6723 | { | 6756 | { |
| 6724 | struct tep_handle *pevent = calloc(1, sizeof(*pevent)); | 6757 | struct tep_handle *pevent = calloc(1, sizeof(*pevent)); |
| 6725 | 6758 | ||
| 6726 | if (pevent) | 6759 | if (pevent) { |
| 6727 | pevent->ref_count = 1; | 6760 | pevent->ref_count = 1; |
| 6761 | pevent->host_bigendian = tep_host_bigendian(); | ||
| 6762 | } | ||
| 6728 | 6763 | ||
| 6729 | return pevent; | 6764 | return pevent; |
| 6730 | } | 6765 | } |
