Deleted Added
full compact
thr_info.c (144518) thr_info.c (154130)
1/*
2 * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 15 unchanged lines hidden (view full) ---

24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
1/*
2 * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 15 unchanged lines hidden (view full) ---

24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * $FreeBSD: head/lib/libthr/thread/thr_info.c 144518 2005-04-02 01:20:00Z davidxu $
32 * $FreeBSD: head/lib/libthr/thread/thr_info.c 154130 2006-01-09 08:07:22Z davidxu $
33 */
34
35#include <stdio.h>
36#include <stdlib.h>
33 */
34
35#include <stdio.h>
36#include <stdlib.h>
37#include <fcntl.h>
38#include <string.h>
37#include <string.h>
39#include <unistd.h>
40#include <pthread.h>
41#include <errno.h>
42
43#include "thr_private.h"
44
38
39#include "thr_private.h"
40
45#ifndef NELEMENTS
46#define NELEMENTS(arr) (sizeof(arr) / sizeof(arr[0]))
47#endif
48
49static void dump_thread(int fd, pthread_t pthread, int long_version);
50
51__weak_reference(_pthread_set_name_np, pthread_set_name_np);
52
53struct s_thread_info {
54 enum pthread_state state;
55 char *name;
56};
57
58/* Static variables: */
59static const struct s_thread_info thread_info[] = {
60 {PS_RUNNING , "Running"},
61 {PS_MUTEX_WAIT , "Waiting on a mutex"},
62 {PS_JOIN , "Waiting to join"},
63 {PS_SUSPENDED , "Suspended"},
64 {PS_DEAD , "Dead"},
65 {PS_DEADLOCK , "Deadlocked"},
66 {PS_STATE_MAX , "Not a real state!"}
67};
68
41/* Set the thread name for debug. */
69void
42void
70_thread_dump_info(void)
43_pthread_set_name_np(pthread_t thread, char *name)
71{
44{
72 char s[512], tmpfile[128];
73 pthread_t pthread;
74 int fd, i;
75
76 for (i = 0; i < 100000; i++) {
77 snprintf(tmpfile, sizeof(tmpfile), "/tmp/pthread.dump.%u.%i",
78 getpid(), i);
79 /* Open the dump file for append and create it if necessary: */
80 if ((fd = __sys_open(tmpfile, O_RDWR | O_CREAT | O_EXCL,
81 0666)) < 0) {
82 /* Can't open the dump file. */
83 if (errno == EEXIST)
84 continue;
85 /*
86 * We only need to continue in case of
87 * EEXIT error. Most other error
88 * codes means that we will fail all
89 * the times.
90 */
91 return;
92 } else {
93 break;
94 }
95 }
96 if (i==100000) {
97 /* all 100000 possibilities are in use :( */
98 return;
99 } else {
100 /* Dump the active threads. */
101 strcpy(s, "\n\n========\nACTIVE THREADS\n\n");
102 __sys_write(fd, s, strlen(s));
103
104 /* Enter a loop to report each thread in the global list: */
105 TAILQ_FOREACH(pthread, &_thread_list, tle) {
106 if (pthread->state != PS_DEAD)
107 dump_thread(fd, pthread, /*long_verson*/ 1);
108 }
109
110 /*
111 * Dump the ready threads.
112 * XXX - We can't easily do this because the run queues
113 * are per-KSEG.
114 */
115 strcpy(s, "\n\n========\nREADY THREADS - unimplemented\n\n");
116 __sys_write(fd, s, strlen(s));
117
118
119 /*
120 * Dump the waiting threads.
121 * XXX - We can't easily do this because the wait queues
122 * are per-KSEG.
123 */
124 strcpy(s, "\n\n========\nWAITING THREADS - unimplemented\n\n");
125 __sys_write(fd, s, strlen(s));
126
127 /* Close the dump file. */
128 __sys_close(fd);
129 }
130}
131
132static void
133dump_thread(int fd, pthread_t pthread, int long_version)
134{
45#if 0
135 struct pthread *curthread = _get_curthread();
46 struct pthread *curthread = _get_curthread();
136 char s[512];
137 int i;
138
47
139 /* Find the state: */
140 for (i = 0; i < NELEMENTS(thread_info) - 1; i++)
141 if (thread_info[i].state == pthread->state)
142 break;
143
144 /* Output a record for the thread: */
145 snprintf(s, sizeof(s),
146 "--------------------\n"
147 "Thread %p (%s), scope %s, prio %3d, state %s [%s:%d]\n",
148 pthread, (pthread->name == NULL) ? "" : pthread->name,
149 pthread->attr.flags & PTHREAD_SCOPE_SYSTEM ? "system" : "process",
150 pthread->active_priority,
151 thread_info[i].name, pthread->fname, pthread->lineno);
152 __sys_write(fd, s, strlen(s));
153
154 if (long_version != 0) {
155 /* Check if this is the running thread: */
156 if (pthread == curthread) {
157 /* Output a record for the running thread: */
158 strcpy(s, "This is the running thread\n");
159 __sys_write(fd, s, strlen(s));
160 }
161 /* Check if this is the initial thread: */
162 if (pthread == _thr_initial) {
163 /* Output a record for the initial thread: */
164 strcpy(s, "This is the initial thread\n");
165 __sys_write(fd, s, strlen(s));
166 }
167
168 /* Process according to thread state: */
169 switch (pthread->state) {
170 /*
171 * Trap other states that are not explicitly
172 * coded to dump information:
173 */
174 default:
175 snprintf(s, sizeof(s), "sigmask (hi) ");
176 __sys_write(fd, s, strlen(s));
177 for (i = _SIG_WORDS - 1; i >= 0; i--) {
178 snprintf(s, sizeof(s), "%08x ",
179 pthread->sigmask.__bits[i]);
180 __sys_write(fd, s, strlen(s));
181 }
182 snprintf(s, sizeof(s), "(lo)\n");
183 __sys_write(fd, s, strlen(s));
184 break;
185 }
186 }
187}
188
189/* Set the thread name for debug: */
190void
191_pthread_set_name_np(pthread_t thread, char *name)
192{
193 /* Check if the caller has specified a valid thread: */
194 if (thread != NULL && thread->magic == THR_MAGIC) {
48 if (thread != NULL && thread->magic == THR_MAGIC) {
49 THR_THREAD_LOCK(curthread, thread);
195 if (thread->name != NULL) {
50 if (thread->name != NULL) {
196 /* Free space for previous name. */
197 free(thread->name);
51 free(thread->name);
52 thread->name = NULL;
198 }
53 }
199 thread->name = strdup(name);
54 if (name != NULL)
55 thread->name = strdup(name);
56 THR_THREAD_UNLOCK(curthread, thread);
200 }
57 }
58#endif
201}
59}