Skip to content

Commit

Permalink
Update.
Browse files Browse the repository at this point in the history
	* internals.h: Declare __pthread_last_event.
	* manager.c: Define __pthread_last_event.
	(pthread_handle_create): Set __pthread_last_event.
	(pthread_exited): Likewise.
	* join.c (pthread_exit): Likewise.
  • Loading branch information
Ulrich Drepper committed Nov 3, 1999
1 parent dbd3e86 commit ab86fbb
Show file tree
Hide file tree
Showing 16 changed files with 366 additions and 62 deletions.
6 changes: 6 additions & 0 deletions linuxthreads/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
1999-11-02 Ulrich Drepper <drepper@cygnus.com>

* internals.h: Declare __pthread_last_event.
* manager.c: Define __pthread_last_event.
(pthread_handle_create): Set __pthread_last_event.
(pthread_exited): Likewise.
* join.c (pthread_exit): Likewise.

* Makefile (libpthread-routines): Add events.
* events.c: New file.
* internals.h: Protect against multiple inclusion.
Expand Down
3 changes: 3 additions & 0 deletions linuxthreads/internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,9 @@ extern volatile int __pthread_threads_debug;
/* Globally enabled events. */
extern volatile td_thr_events_t __pthread_threads_events;

/* Pointer to descriptor of thread with last event. */
extern volatile pthread_descr __pthread_last_event;

/* Return the handle corresponding to a thread id */

static inline pthread_handle thread_handle(pthread_t id)
Expand Down
1 change: 1 addition & 0 deletions linuxthreads/join.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ void pthread_exit(void * retval)
/* Yep, we have to signal the death. */
THREAD_SETMEM(self, p_eventbuf.eventnum, TD_DEATH);
THREAD_SETMEM(self, p_eventbuf.eventdata, self);
__pthread_last_event = self;

/* Now call the function to signal the event. */
__linuxthreads_death_event();
Expand Down
5 changes: 5 additions & 0 deletions linuxthreads/manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ volatile int __pthread_threads_debug;
/* Globally enabled events. */
volatile td_thr_events_t __pthread_threads_events;

/* Pointer to thread descriptor with last event. */
volatile pthread_descr __pthread_last_event;

/* Mapping from stack segment to thread descriptor. */
/* Stack segment numbers are also indices into the __pthread_handles array. */
/* Stack segment number 0 is reserved for the initial thread. */
Expand Down Expand Up @@ -422,6 +425,7 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
already scheduled when we send the event. */
new_thread->p_eventbuf.eventdata = new_thread;
new_thread->p_eventbuf.eventnum = TD_CREATE;
__pthread_last_event = new_thread;

/* Now call the function which signals the event. */
__linuxthreads_create_event ();
Expand Down Expand Up @@ -523,6 +527,7 @@ static void pthread_exited(pid_t pid)
/* Yep, we have to signal the death. */
th->p_eventbuf.eventnum = TD_DEATH;
th->p_eventbuf.eventdata = th;
__pthread_last_event = th;

/* Now call the function to signal the event. */
__linuxthreads_reap_event();
Expand Down
21 changes: 21 additions & 0 deletions linuxthreads_db/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
1999-11-02 Ulrich Drepper <drepper@cygnus.com>

* td_ta_thr_iter.c (td_ta_thr_iter): Optimize a bit. Read all
handles at once.

* thread_dbP.h (struct th_thragent): Add pthread_handle_num.
* td_ta_new.c: Initialize pthread_handle_num.
* td_ta_event_getmsg.c: If last event was already reported search
for another unreported event.

* td_thr_get_info.c (td_thr_get_info): Initialize ti_events.

* Makefile (libthread_db-routines): Add td_ta_set_event,
td_ta_event_getmsg, and td_ta_clear_event.
* td_ta_clear_event.c: New file.
* td_ta_event_getmsg.c: New file.
* td_ta_new.c: Get address of __pthread_last_event in target.
* td_ta_set_event.c: Don't overwrite old mask, set additional bits.
* td_thr_set_event.c: Likewise.
* td_thr_clear_event.c: Implement.
* thread_db.h: Declare td_ta_clear_event and td_ta_event_getmsg.
* thread_dbP.h (struct td_thragent): Add pthread_last_event.

* td_ta_new.c: Don't test for __pthread_threads_debug. Get address
of __pthread_threads_events and fail if this is not possible.
* td_ta_event_addr.c: Implement.
Expand Down
4 changes: 3 additions & 1 deletion linuxthreads_db/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ libthread_db-routines = td_init td_log td_ta_delete td_ta_get_nthreads \
td_ta_setconcurrency td_ta_enable_stats \
td_ta_reset_stats td_ta_get_stats td_ta_event_addr \
td_thr_event_enable td_thr_set_event \
td_thr_clear_event td_thr_event_getmsg
td_thr_clear_event td_thr_event_getmsg \
td_ta_set_event td_ta_event_getmsg \
td_ta_clear_event

libthread_db-inhibit-o = $(filter-out .os,$(object-suffixes))

Expand Down
49 changes: 49 additions & 0 deletions linuxthreads_db/td_ta_clear_event.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/* Globally disable events.
Copyright (C) 1999 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */

#include "thread_dbP.h"


td_err_e
td_ta_clear_event (ta, event)
const td_thragent_t *ta;
td_thr_events_t *event;
{
td_thr_events_t old_event;
int i;

LOG (__FUNCTION__);

/* Write the new value into the thread data structure. */
if (ps_pdread (ta->ph, ta->pthread_threads_eventsp,
&old_event, sizeof (td_thrhandle_t)) != PS_OK)
return TD_ERR; /* XXX Other error value? */

/* Remove the set bits in. */
for (i = 0; i < TD_EVENTSIZE; ++i)
old_event.event_bits[i] &= ~event->event_bits[i];

/* Write the new value into the thread data structure. */
if (ps_pdwrite (ta->ph, ta->pthread_threads_eventsp,
&old_event, sizeof (td_thrhandle_t)) != PS_OK)
return TD_ERR; /* XXX Other error value? */

return TD_OK;
}
124 changes: 124 additions & 0 deletions linuxthreads_db/td_ta_event_getmsg.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/* Retrieve event.
Copyright (C) 1999 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */

#include <stddef.h>
#include <string.h>

#include "thread_dbP.h"


td_err_e
td_ta_event_getmsg (const td_thragent_t *ta, td_event_msg_t *msg)
{
/* XXX I cannot think of another way but using a static variable. */
static td_thrhandle_t th;
td_eventbuf_t event;
psaddr_t addr;

LOG (__FUNCTION__);

/* Get the pointer to the thread descriptor with the last event. */
if (ps_pdread (ta->ph, ta->pthread_last_event,
&addr, sizeof (void *)) != PS_OK)
return TD_ERR; /* XXX Other error value? */

/* If the pointer is NULL no event occurred. */
if (addr == 0)
return TD_NOMSG;

/* Read the even structure from the target. */
if (ps_pdread (ta->ph,
((char *) addr
+ offsetof (struct _pthread_descr_struct, p_eventbuf)),
&event, sizeof (td_eventbuf_t)) != PS_OK)
return TD_ERR; /* XXX Other error value? */

/* Check whether an event occurred. */
if (event.eventnum == TD_EVENT_NONE)
{
/* Oh well, this means the last event was already read. So
we have to look for any other event. */
struct pthread_handle_struct handles[ta->pthread_threads_max];
int num;
int i;

/* Read the number of currently active threads. */
if (ps_pdread (ta->ph, ta->pthread_handles_num, &num, sizeof (int))
!= PS_OK)
return TD_ERR; /* XXX Other error value? */

/* Now read the handles. */
if (ps_pdread (ta->ph, ta->handles, handles,
ta->pthread_threads_max * sizeof (handles[0])) != PS_OK)
return TD_ERR; /* XXX Other error value? */

for (i = 0; i < ta->pthread_threads_max && num > 0; ++i)
{
if (handles[i].h_descr == NULL)
/* No entry here. */
continue;

/* First count this active thread. */
--num;

if (handles[i].h_descr == addr)
/* We already handled this. */
continue;

/* Read the event data for this thread. */
if (ps_pdread (ta->ph,
((char *) handles[i].h_descr
+ offsetof (struct _pthread_descr_struct,
p_eventbuf)),
&event, sizeof (td_eventbuf_t)) != PS_OK)
return TD_ERR;

if (event.eventnum != TD_EVENT_NONE)
{
/* We found a thread with an unreported event. */
addr = handles[i].h_descr;
break;
}
}

/* If we haven't found any other event signal this to the user. */
if (event.eventnum == TD_EVENT_NONE)
return TD_NOMSG;
}

/* Generate the thread descriptor. */
th.th_ta_p = (td_thragent_t *) ta;
th.th_unique = addr;

/* Fill the user's data structure. */
msg->event = event.eventnum;
msg->th_p = &th;
msg->msg.data = (uintptr_t) event.eventdata;

/* And clear the event message in the target. */
memset (&event, '\0', sizeof (td_eventbuf_t));
if (ps_pdwrite (ta->ph,
((char *) addr
+ offsetof (struct _pthread_descr_struct, p_eventbuf)),
&event, sizeof (td_eventbuf_t)) != PS_OK)
return TD_ERR; /* XXX Other error value? */

return TD_OK;
}
20 changes: 17 additions & 3 deletions linuxthreads_db/td_ta_new.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,29 @@ td_ta_new (struct ps_prochandle *ps, td_thragent_t **ta)
/* Remember the address. */
(*ta)->pthread_threads_eventsp = (td_thr_events_t *) addr;

/* See whether the library contains the necessary symbols. */
if (ps_pglobal_lookup (ps, LIBPTHREAD_SO, "__pthread_handles",
&addr) != PS_OK)
/* Get the pointer to the variable pointing to the thread descriptor
with the last event. */
if (ps_pglobal_lookup (ps, LIBPTHREAD_SO,
"__pthread_last_event",
&(*ta)->pthread_last_event) != PS_OK)
{
free_return:
free (*ta);
return TD_ERR;
}

/* Get the pointer to the variable containing the number of active
threads. */
if (ps_pglobal_lookup (ps, LIBPTHREAD_SO,
"__pthread_handles_num",
&(*ta)->pthread_handles_num) != PS_OK)
goto free_return;

/* See whether the library contains the necessary symbols. */
if (ps_pglobal_lookup (ps, LIBPTHREAD_SO, "__pthread_handles",
&addr) != PS_OK)
goto free_return;

(*ta)->handles = (struct pthread_handle_struct *) addr;


Expand Down
14 changes: 13 additions & 1 deletion linuxthreads_db/td_ta_set_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,23 @@ td_ta_set_event (ta, event)
const td_thragent_t *ta;
td_thr_events_t *event;
{
td_thr_events_t old_event;
int i;

LOG (__FUNCTION__);

/* Write the new value into the thread data structure. */
if (ps_pdread (ta->ph, ta->pthread_threads_eventsp,
&old_event, sizeof (td_thrhandle_t)) != PS_OK)
return TD_ERR; /* XXX Other error value? */

/* Or the new bits in. */
for (i = 0; i < TD_EVENTSIZE; ++i)
old_event.event_bits[i] |= event->event_bits[i];

/* Write the new value into the thread data structure. */
if (ps_pdwrite (ta->ph, ta->pthread_threads_eventsp,
event, sizeof (td_thrhandle_t)) != PS_OK)
&old_event, sizeof (td_thrhandle_t)) != PS_OK)
return TD_ERR; /* XXX Other error value? */

return TD_OK;
Expand Down
Loading

0 comments on commit ab86fbb

Please sign in to comment.