From dc146f7c09d1369f5621e4aac23d410d40d3a6f0 Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Tue, 12 Jan 2010 21:40:25 +0000 Subject: Implement core awareness. * bcache.c (compare_ints): Remove (print_percentage): Use compare_positive_ints. * defs.h (compare_positive_ints): Declare. * linux-nat.h (struct lin_lwp): New field core. (linux_nat_core_of_thread_1): Declare. * linux-nat.c (add_lwp): Init the 'core' field. (linux_nat_wait_1): Record the core. (linux_nat_core_of_thread_1, linux_nat_core_of_thread): New. (linux_nat_add_target): Register the above. * linux-thread-db.c (update_thread_core): New. (thread_db_find_new_threads): Update core information for every thread. * remote.c (struct private_thread_info): New. (free_private_thread_info, demand_private_info): New. (PACKET_qXfer_threads, use_osdata_threads): New. (struct thread_item, threads_parsing_context (start_thread, end_thread, thread_attributes) (thread_children, threads_children, threads_elements): New. (remote_threads_info): Try qXfer:threads before anything else. (remote_protocol_packets): Register qXfer:threads. (remote_open_1): Init use_osdata_threads. (struct stop_reply): New field 'core'. (remote_parse_stop_reply): Parse core number. (process_stop_reply): Record core number. (remote_xfer_partial): Handle qXfer:threads. (remote_core_of_thread): New. (init_remote_ops): Register remote_core_of_thread. (_initialize_remote): Register qXfer:read. * target.c (target_core_of_thread): New * target.h (enum target_object): New value TARGET_OBJECT_THREADS. (struct target_ops): New field to_core_of_threads. (target_core_of_thread): Declare. * gdbthread.h (struct thread_info): New field private_dtor. * thread.c (print_thread_info): Report the core. * ui-out.c (MAX_UI_OUT_LEVELS): Increase. * utils.c (compare_positive_ints): New. * features/threads.dtd: New. * mi/mi-interp.c (mi_on_normal_stop): Report the core. * mi/mi-main.c (struct collect_cores_data, collect_cores) (do_nothing, free_vector_of_osdata_items) (splay_tree_int_comparator, free_splay_tree): New. (print_one_inferior_data): Implemented printing of selected inferiors. Collect and print cores. (output_cores): New. (mi_cmd_list_thread_groups): Support --recurse. Permit specifying thread groups together with --available. --- gdb/linux-nat.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) (limited to 'gdb/linux-nat.c') diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index 48ea1bc..bf0a5f1 100644 --- a/gdb/linux-nat.c +++ b/gdb/linux-nat.c @@ -1184,6 +1184,7 @@ add_lwp (ptid_t ptid) lp->waitstatus.kind = TARGET_WAITKIND_IGNORE; lp->ptid = ptid; + lp->core = -1; lp->next = lwp_list; lwp_list = lp; @@ -3642,6 +3643,7 @@ retry: fprintf_unfiltered (gdb_stdlog, "LLW: exit\n"); restore_child_signals_mask (&prev_mask); + lp->core = linux_nat_core_of_thread_1 (lp->ptid); return lp->ptid; } @@ -5423,6 +5425,75 @@ linux_nat_thread_address_space (struct target_ops *t, ptid_t ptid) return inf->aspace; } +int +linux_nat_core_of_thread_1 (ptid_t ptid) +{ + struct cleanup *back_to; + char *filename; + FILE *f; + char *content = NULL; + char *p; + char *ts = 0; + int content_read = 0; + int i; + int core; + + filename = xstrprintf ("/proc/%d/task/%ld/stat", + GET_PID (ptid), GET_LWP (ptid)); + back_to = make_cleanup (xfree, filename); + + f = fopen (filename, "r"); + if (!f) + { + do_cleanups (back_to); + return -1; + } + + make_cleanup_fclose (f); + + for (;;) + { + int n; + content = xrealloc (content, content_read + 1024); + n = fread (content + content_read, 1, 1024, f); + content_read += n; + if (n < 1024) + { + content[content_read] = '\0'; + break; + } + } + + make_cleanup (xfree, content); + + p = strchr (content, '('); + p = strchr (p, ')') + 2; /* skip ")" and a whitespace. */ + + /* If the first field after program name has index 0, then core number is + the field with index 36. There's no constant for that anywhere. */ + p = strtok_r (p, " ", &ts); + for (i = 0; i != 36; ++i) + p = strtok_r (NULL, " ", &ts); + + if (sscanf (p, "%d", &core) == 0) + core = -1; + + do_cleanups (back_to); + + return core; +} + +/* Return the cached value of the processor core for thread PTID. */ + +int +linux_nat_core_of_thread (struct target_ops *ops, ptid_t ptid) +{ + struct lwp_info *info = find_lwp_pid (ptid); + if (info) + return info->core; + return -1; +} + void linux_nat_add_target (struct target_ops *t) { @@ -5463,6 +5534,8 @@ linux_nat_add_target (struct target_ops *t) t->to_supports_multi_process = linux_nat_supports_multi_process; + t->to_core_of_thread = linux_nat_core_of_thread; + /* We don't change the stratum; this target will sit at process_stratum and thread_db will set at thread_stratum. This is a little strange, since this is a multi-threaded-capable -- cgit v1.1