Update.
1999-11-03 Ulrich Drepper <drepper@cygnus.com> * Versions.def: Add version for libthread_db.
This commit is contained in:
parent
ab86fbb1d2
commit
9532eb67a4
|
@ -1,3 +1,7 @@
|
||||||
|
1999-11-03 Ulrich Drepper <drepper@cygnus.com>
|
||||||
|
|
||||||
|
* Versions.def: Add version for libthread_db.
|
||||||
|
|
||||||
1999-11-02 Andreas Jaeger <aj@suse.de>
|
1999-11-02 Andreas Jaeger <aj@suse.de>
|
||||||
|
|
||||||
* manual/header.texi (Library Summary): The command @indexfonts
|
* manual/header.texi (Library Summary): The command @indexfonts
|
||||||
|
|
|
@ -81,3 +81,6 @@ ld.so {
|
||||||
GLIBC_2.1 GLIBC_2.0
|
GLIBC_2.1 GLIBC_2.0
|
||||||
GLIBC_2.1.1 GLIBC_2.1
|
GLIBC_2.1.1 GLIBC_2.1
|
||||||
}
|
}
|
||||||
|
libthread_db {
|
||||||
|
GLIBC_2.1.3
|
||||||
|
}
|
||||||
|
|
|
@ -1,3 +1,28 @@
|
||||||
|
1999-11-03 Ulrich Drepper <drepper@cygnus.com>
|
||||||
|
|
||||||
|
* thread_dbP.h (ta_ok): New function.
|
||||||
|
* td_ta_new.c: Add new handle to list.
|
||||||
|
* td_ta_delete.c: Remove handle from list.
|
||||||
|
* td_ta_clear_event.c: Use ta_ok to check for correct ta parameter.
|
||||||
|
* td_ta_enable_stats.c: Likewise.
|
||||||
|
* td_ta_event_addr.c: Likewise.
|
||||||
|
* td_ta_event_getmsg.c: Likewise.
|
||||||
|
* td_ta_get_nthreads.c: Likewise.
|
||||||
|
* td_ta_get_ph.c: Likewise.
|
||||||
|
* td_ta_get_stats.c: Likewise.
|
||||||
|
* td_ta_map_id2thr.c: Likewise.
|
||||||
|
* td_ta_map_lwp2thr.c: Likewise.
|
||||||
|
* td_ta_reset_stats.c: Likewise.
|
||||||
|
* td_ta_set_event.c: Likewise.
|
||||||
|
* td_ta_setconcurrency.c: Likewise.
|
||||||
|
* td_ta_thr_iter.c: Likewise.
|
||||||
|
|
||||||
|
* td_ta_tsd_iter.c: Optimize memory retrieving.
|
||||||
|
|
||||||
|
* Versions: New file.
|
||||||
|
|
||||||
|
* td_thr_get_info.c (td_thr_get_info): Initialize ti_traceme.
|
||||||
|
|
||||||
1999-11-02 Ulrich Drepper <drepper@cygnus.com>
|
1999-11-02 Ulrich Drepper <drepper@cygnus.com>
|
||||||
|
|
||||||
* td_ta_thr_iter.c (td_ta_thr_iter): Optimize a bit. Read all
|
* td_ta_thr_iter.c (td_ta_thr_iter): Optimize a bit. Read all
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
libthread_db {
|
||||||
|
GLIBC_2.1.3 {
|
||||||
|
# t*
|
||||||
|
td_init; td_log; td_ta_clear_event; td_ta_delete; td_ta_enable_stats;
|
||||||
|
td_ta_event_addr; td_ta_event_getmsg; td_ta_get_nthreads; td_ta_get_ph;
|
||||||
|
td_ta_get_stats; td_ta_map_id2thr; td_ta_map_lwp2thr; td_ta_new;
|
||||||
|
td_ta_reset_stats; td_ta_set_event; td_ta_setconcurrency;
|
||||||
|
td_ta_thr_iter; td_ta_tsd_iter; td_thr_clear_event; td_thr_dbresume;
|
||||||
|
td_thr_dbsuspend; td_thr_event_enable; td_thr_event_getmsg;
|
||||||
|
td_thr_get_info; td_thr_getfpregs; td_thr_getgregs; td_thr_getxregs;
|
||||||
|
td_thr_getxregsize; td_thr_set_event; td_thr_setfpregs; td_thr_setgregs;
|
||||||
|
td_thr_setprio; td_thr_setsigpending; td_thr_setxregs; td_thr_sigsetmask;
|
||||||
|
td_thr_tsd; td_thr_validate;
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,6 +31,10 @@ td_ta_clear_event (ta, event)
|
||||||
|
|
||||||
LOG (__FUNCTION__);
|
LOG (__FUNCTION__);
|
||||||
|
|
||||||
|
/* Test whether the TA parameter is ok. */
|
||||||
|
if (! ta_ok (ta))
|
||||||
|
return TD_BADTA;
|
||||||
|
|
||||||
/* Write the new value into the thread data structure. */
|
/* Write the new value into the thread data structure. */
|
||||||
if (ps_pdread (ta->ph, ta->pthread_threads_eventsp,
|
if (ps_pdread (ta->ph, ta->pthread_threads_eventsp,
|
||||||
&old_event, sizeof (td_thrhandle_t)) != PS_OK)
|
&old_event, sizeof (td_thrhandle_t)) != PS_OK)
|
||||||
|
|
|
@ -28,6 +28,29 @@ td_ta_delete (td_thragent_t *ta)
|
||||||
{
|
{
|
||||||
LOG (__FUNCTION__);
|
LOG (__FUNCTION__);
|
||||||
|
|
||||||
|
/* Safety check. */
|
||||||
|
if (ta == NULL || __td_agent_list == NULL)
|
||||||
|
return TD_BADTA;
|
||||||
|
|
||||||
|
/* Remove the handle from the list. */
|
||||||
|
if (ta == __td_agent_list->ta)
|
||||||
|
/* It's the first element of the list. */
|
||||||
|
__td_agent_list = __td_agent_list->next;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* We have to search for it. */
|
||||||
|
struct agent_list *runp = __td_agent_list;
|
||||||
|
|
||||||
|
while (runp->next != NULL && runp->next->ta != ta)
|
||||||
|
runp = runp->next;
|
||||||
|
|
||||||
|
if (runp->next == NULL)
|
||||||
|
/* It's not a valid decriptor since it is not in the list. */
|
||||||
|
return TD_BADTA;
|
||||||
|
|
||||||
|
runp->next = runp->next->next;
|
||||||
|
}
|
||||||
|
|
||||||
/* The handle was allocated in `td_ta_new'. */
|
/* The handle was allocated in `td_ta_new'. */
|
||||||
free (ta);
|
free (ta);
|
||||||
|
|
||||||
|
|
|
@ -26,5 +26,10 @@ td_ta_enable_stats (const td_thragent_t *ta, int enable)
|
||||||
{
|
{
|
||||||
/* XXX We have to figure out what has to be done. */
|
/* XXX We have to figure out what has to be done. */
|
||||||
LOG (__FUNCTION__);
|
LOG (__FUNCTION__);
|
||||||
|
|
||||||
|
/* Test whether the TA parameter is ok. */
|
||||||
|
if (! ta_ok (ta))
|
||||||
|
return TD_BADTA;
|
||||||
|
|
||||||
return TD_OK;
|
return TD_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,10 @@ td_ta_event_addr (const td_thragent_t *ta, td_event_e event, td_notify_t *addr)
|
||||||
|
|
||||||
LOG (__FUNCTION__);
|
LOG (__FUNCTION__);
|
||||||
|
|
||||||
|
/* Test whether the TA parameter is ok. */
|
||||||
|
if (! ta_ok (ta))
|
||||||
|
return TD_BADTA;
|
||||||
|
|
||||||
switch (event)
|
switch (event)
|
||||||
{
|
{
|
||||||
case TD_CREATE:
|
case TD_CREATE:
|
||||||
|
|
|
@ -34,6 +34,10 @@ td_ta_event_getmsg (const td_thragent_t *ta, td_event_msg_t *msg)
|
||||||
|
|
||||||
LOG (__FUNCTION__);
|
LOG (__FUNCTION__);
|
||||||
|
|
||||||
|
/* Test whether the TA parameter is ok. */
|
||||||
|
if (! ta_ok (ta))
|
||||||
|
return TD_BADTA;
|
||||||
|
|
||||||
/* Get the pointer to the thread descriptor with the last event. */
|
/* Get the pointer to the thread descriptor with the last event. */
|
||||||
if (ps_pdread (ta->ph, ta->pthread_last_event,
|
if (ps_pdread (ta->ph, ta->pthread_last_event,
|
||||||
&addr, sizeof (void *)) != PS_OK)
|
&addr, sizeof (void *)) != PS_OK)
|
||||||
|
|
|
@ -28,6 +28,10 @@ td_ta_get_nthreads (const td_thragent_t *ta, int *np)
|
||||||
|
|
||||||
LOG (__FUNCTION__);
|
LOG (__FUNCTION__);
|
||||||
|
|
||||||
|
/* Test whether the TA parameter is ok. */
|
||||||
|
if (! ta_ok (ta))
|
||||||
|
return TD_BADTA;
|
||||||
|
|
||||||
/* Access the variable `__pthread_handles_num'. */
|
/* Access the variable `__pthread_handles_num'. */
|
||||||
if (ps_pglobal_lookup (ta->ph, LIBPTHREAD_SO, "__pthread_handles_num",
|
if (ps_pglobal_lookup (ta->ph, LIBPTHREAD_SO, "__pthread_handles_num",
|
||||||
&addr) != PS_OK)
|
&addr) != PS_OK)
|
||||||
|
|
|
@ -26,6 +26,10 @@ td_ta_get_ph (const td_thragent_t *ta, struct ps_prochandle **ph)
|
||||||
{
|
{
|
||||||
LOG (__FUNCTION__);
|
LOG (__FUNCTION__);
|
||||||
|
|
||||||
|
/* Test whether the TA parameter is ok. */
|
||||||
|
if (! ta_ok (ta))
|
||||||
|
return TD_BADTA;
|
||||||
|
|
||||||
*ph = ta->ph;
|
*ph = ta->ph;
|
||||||
|
|
||||||
return TD_OK;
|
return TD_OK;
|
||||||
|
|
|
@ -26,5 +26,10 @@ td_ta_get_stats (const td_thragent_t *ta, td_ta_stats_t *statsp)
|
||||||
{
|
{
|
||||||
/* XXX We have to figure out what has to be done. */
|
/* XXX We have to figure out what has to be done. */
|
||||||
LOG (__FUNCTION__);
|
LOG (__FUNCTION__);
|
||||||
|
|
||||||
|
/* Test whether the TA parameter is ok. */
|
||||||
|
if (! ta_ok (ta))
|
||||||
|
return TD_BADTA;
|
||||||
|
|
||||||
return TD_OK;
|
return TD_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,14 +24,21 @@
|
||||||
td_err_e
|
td_err_e
|
||||||
td_ta_map_id2thr (const td_thragent_t *ta, pthread_t pt, td_thrhandle_t *th)
|
td_ta_map_id2thr (const td_thragent_t *ta, pthread_t pt, td_thrhandle_t *th)
|
||||||
{
|
{
|
||||||
struct pthread_handle_struct *handles = ta->handles;
|
|
||||||
struct pthread_handle_struct phc;
|
struct pthread_handle_struct phc;
|
||||||
int pthread_threads_max = ta->pthread_threads_max;
|
struct _pthread_descr_struct pds;
|
||||||
|
int pthread_threads_max;
|
||||||
|
|
||||||
LOG (__FUNCTION__);
|
LOG (__FUNCTION__);
|
||||||
|
|
||||||
|
/* Test whether the TA parameter is ok. */
|
||||||
|
if (! ta_ok (ta))
|
||||||
|
return TD_BADTA;
|
||||||
|
|
||||||
|
/* Make the following expression a bit smaller. */
|
||||||
|
pthread_threads_max = ta->pthread_threads_max;
|
||||||
|
|
||||||
/* We can compute the entry in the handle array we want. */
|
/* We can compute the entry in the handle array we want. */
|
||||||
if (ps_pdread (ta->ph, handles + pt % pthread_threads_max, &phc,
|
if (ps_pdread (ta->ph, ta->handles + pt % pthread_threads_max, &phc,
|
||||||
sizeof (struct pthread_handle_struct)) != PS_OK)
|
sizeof (struct pthread_handle_struct)) != PS_OK)
|
||||||
return TD_ERR; /* XXX Other error value? */
|
return TD_ERR; /* XXX Other error value? */
|
||||||
|
|
||||||
|
@ -39,6 +46,15 @@ td_ta_map_id2thr (const td_thragent_t *ta, pthread_t pt, td_thrhandle_t *th)
|
||||||
if (phc.h_descr == NULL)
|
if (phc.h_descr == NULL)
|
||||||
return TD_BADTH;
|
return TD_BADTH;
|
||||||
|
|
||||||
|
/* Next test: get the descriptor to see whether this is not an old
|
||||||
|
thread handle. */
|
||||||
|
if (ps_pdread (ta->ph, phc.h_descr, &pds,
|
||||||
|
sizeof (struct _pthread_descr_struct)) != PS_OK)
|
||||||
|
return TD_ERR; /* XXX Other error value? */
|
||||||
|
|
||||||
|
if (pds.p_tid != pt)
|
||||||
|
return TD_BADTH;
|
||||||
|
|
||||||
/* Create the `td_thrhandle_t' object. */
|
/* Create the `td_thrhandle_t' object. */
|
||||||
th->th_ta_p = (td_thragent_t *) ta;
|
th->th_ta_p = (td_thragent_t *) ta;
|
||||||
th->th_unique = phc.h_descr;
|
th->th_unique = phc.h_descr;
|
||||||
|
|
|
@ -24,38 +24,57 @@
|
||||||
td_err_e
|
td_err_e
|
||||||
td_ta_map_lwp2thr (const td_thragent_t *ta, lwpid_t lwpid, td_thrhandle_t *th)
|
td_ta_map_lwp2thr (const td_thragent_t *ta, lwpid_t lwpid, td_thrhandle_t *th)
|
||||||
{
|
{
|
||||||
struct pthread_handle_struct *handles = ta->handles;
|
|
||||||
int pthread_threads_max = ta->pthread_threads_max;
|
int pthread_threads_max = ta->pthread_threads_max;
|
||||||
|
size_t sizeof_descr = ta->sizeof_descr;
|
||||||
|
struct pthread_handle_struct phc[pthread_threads_max];
|
||||||
size_t cnt;
|
size_t cnt;
|
||||||
|
#ifdef ALL_THREADS_STOPPED
|
||||||
|
int num;
|
||||||
|
#else
|
||||||
|
# define num 1
|
||||||
|
#endif
|
||||||
|
|
||||||
LOG (__FUNCTION__);
|
LOG (__FUNCTION__);
|
||||||
|
|
||||||
|
/* Test whether the TA parameter is ok. */
|
||||||
|
if (! ta_ok (ta))
|
||||||
|
return TD_BADTA;
|
||||||
|
|
||||||
|
/* Read all the descriptors. */
|
||||||
|
if (ps_pdread (ta->ph, ta->handles, phc,
|
||||||
|
sizeof (struct pthread_handle_struct) * pthread_threads_max)
|
||||||
|
!= PS_OK)
|
||||||
|
return TD_ERR; /* XXX Other error value? */
|
||||||
|
|
||||||
|
#ifdef ALL_THREADS_STOPPED
|
||||||
|
/* 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? */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Get the entries one after the other and find out whether the ID
|
/* Get the entries one after the other and find out whether the ID
|
||||||
matches. */
|
matches. */
|
||||||
for (cnt = 0; cnt < pthread_threads_max; ++cnt, ++handles)
|
for (cnt = 0; cnt < pthread_threads_max && num > 0; ++cnt)
|
||||||
{
|
if (phc[cnt].h_descr != NULL)
|
||||||
struct pthread_handle_struct phc;
|
{
|
||||||
struct _pthread_descr_struct pds;
|
struct _pthread_descr_struct pds;
|
||||||
|
|
||||||
if (ps_pdread (ta->ph, handles, &phc,
|
#ifdef ALL_THREADS_STOPPED
|
||||||
sizeof (struct pthread_handle_struct)) != PS_OK)
|
/* First count this active thread. */
|
||||||
return TD_ERR; /* XXX Other error value? */
|
--num;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (phc.h_descr != NULL)
|
if (ps_pdread (ta->ph, phc[cnt].h_descr, &pds, sizeof_descr) != PS_OK)
|
||||||
{
|
return TD_ERR; /* XXX Other error value? */
|
||||||
if (ps_pdread (ta->ph, phc.h_descr, &pds,
|
|
||||||
sizeof (struct _pthread_descr_struct)) != PS_OK)
|
|
||||||
return TD_ERR; /* XXX Other error value? */
|
|
||||||
|
|
||||||
if (pds.p_pid == lwpid)
|
if (pds.p_pid == lwpid)
|
||||||
{
|
{
|
||||||
/* Found it. Now fill in the `td_thrhandle_t' object. */
|
/* Found it. Now fill in the `td_thrhandle_t' object. */
|
||||||
th->th_ta_p = (td_thragent_t *) ta;
|
th->th_ta_p = (td_thragent_t *) ta;
|
||||||
th->th_unique = phc.h_descr;
|
th->th_unique = phc[cnt].h_descr;
|
||||||
|
|
||||||
return TD_OK;
|
return TD_OK;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TD_NOLWP;
|
return TD_NOLWP;
|
||||||
|
|
|
@ -25,10 +25,16 @@
|
||||||
#include "thread_dbP.h"
|
#include "thread_dbP.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Datatype for the list of known thread agents. Normally there will
|
||||||
|
be exactly one so we don't spend much though on making it fast. */
|
||||||
|
struct agent_list *__td_agent_list;
|
||||||
|
|
||||||
|
|
||||||
td_err_e
|
td_err_e
|
||||||
td_ta_new (struct ps_prochandle *ps, td_thragent_t **ta)
|
td_ta_new (struct ps_prochandle *ps, td_thragent_t **ta)
|
||||||
{
|
{
|
||||||
psaddr_t addr;
|
psaddr_t addr;
|
||||||
|
struct agent_list *elemp;
|
||||||
|
|
||||||
LOG (__FUNCTION__);
|
LOG (__FUNCTION__);
|
||||||
|
|
||||||
|
@ -130,5 +136,19 @@ td_ta_new (struct ps_prochandle *ps, td_thragent_t **ta)
|
||||||
goto free_return;
|
goto free_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Now add the new agent descriptor to the list. */
|
||||||
|
elemp = (struct agent_list *) malloc (sizeof (struct agent_list));
|
||||||
|
if (elemp == NULL)
|
||||||
|
{
|
||||||
|
/* Argh, now that everything else worked... */
|
||||||
|
free (*ta);
|
||||||
|
return TD_MALLOC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We don't care for thread-safety here. */
|
||||||
|
elemp->ta = *ta;
|
||||||
|
elemp->next = __td_agent_list;
|
||||||
|
__td_agent_list = elemp;
|
||||||
|
|
||||||
return TD_OK;
|
return TD_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,5 +26,10 @@ td_ta_reset_stats (const td_thragent_t *ta)
|
||||||
{
|
{
|
||||||
/* XXX We have to figure out what has to be done. */
|
/* XXX We have to figure out what has to be done. */
|
||||||
LOG (__FUNCTION__);
|
LOG (__FUNCTION__);
|
||||||
|
|
||||||
|
/* Test whether the TA parameter is ok. */
|
||||||
|
if (! ta_ok (ta))
|
||||||
|
return TD_BADTA;
|
||||||
|
|
||||||
return TD_OK;
|
return TD_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,10 @@ td_ta_set_event (ta, event)
|
||||||
|
|
||||||
LOG (__FUNCTION__);
|
LOG (__FUNCTION__);
|
||||||
|
|
||||||
|
/* Test whether the TA parameter is ok. */
|
||||||
|
if (! ta_ok (ta))
|
||||||
|
return TD_BADTA;
|
||||||
|
|
||||||
/* Write the new value into the thread data structure. */
|
/* Write the new value into the thread data structure. */
|
||||||
if (ps_pdread (ta->ph, ta->pthread_threads_eventsp,
|
if (ps_pdread (ta->ph, ta->pthread_threads_eventsp,
|
||||||
&old_event, sizeof (td_thrhandle_t)) != PS_OK)
|
&old_event, sizeof (td_thrhandle_t)) != PS_OK)
|
||||||
|
|
|
@ -26,5 +26,10 @@ td_ta_setconcurrency (const td_thragent_t *ta, int level)
|
||||||
{
|
{
|
||||||
/* This is something LinuxThreads does not support. */
|
/* This is something LinuxThreads does not support. */
|
||||||
LOG (__FUNCTION__);
|
LOG (__FUNCTION__);
|
||||||
|
|
||||||
|
/* Test whether the TA parameter is ok. */
|
||||||
|
if (! ta_ok (ta))
|
||||||
|
return TD_BADTA;
|
||||||
|
|
||||||
return TD_NOCAPAB;
|
return TD_NOCAPAB;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,24 +26,38 @@ td_ta_thr_iter (const td_thragent_t *ta, td_thr_iter_f *callback,
|
||||||
void *cbdata_p, td_thr_state_e state, int ti_pri,
|
void *cbdata_p, td_thr_state_e state, int ti_pri,
|
||||||
sigset_t *ti_sigmask_p, unsigned int ti_user_flags)
|
sigset_t *ti_sigmask_p, unsigned int ti_user_flags)
|
||||||
{
|
{
|
||||||
int pthread_threads_max = ta->pthread_threads_max;
|
int pthread_threads_max;
|
||||||
size_t sizeof_descr = ta->sizeof_descr;
|
size_t sizeof_descr;
|
||||||
struct pthread_handle_struct phc[pthread_threads_max];
|
struct pthread_handle_struct *phc;
|
||||||
int num;
|
|
||||||
int cnt;
|
int cnt;
|
||||||
|
#ifdef ALL_THREADS_STOPPED
|
||||||
|
int num;
|
||||||
|
#else
|
||||||
|
# define num 1
|
||||||
|
#endif
|
||||||
|
|
||||||
LOG (__FUNCTION__);
|
LOG (__FUNCTION__);
|
||||||
|
|
||||||
|
/* Test whether the TA parameter is ok. */
|
||||||
|
if (! ta_ok (ta))
|
||||||
|
return TD_BADTA;
|
||||||
|
|
||||||
|
pthread_threads_max = ta->pthread_threads_max;
|
||||||
|
sizeof_descr = ta->sizeof_descr;
|
||||||
|
phc = (struct pthread_handle_struct *) alloca (sizeof (phc[0])
|
||||||
|
* pthread_threads_max);
|
||||||
|
|
||||||
/* Read all the descriptors. */
|
/* Read all the descriptors. */
|
||||||
if (ps_pdread (ta->ph, ta->handles, phc,
|
if (ps_pdread (ta->ph, ta->handles, phc,
|
||||||
sizeof (struct pthread_handle_struct) * pthread_threads_max)
|
sizeof (struct pthread_handle_struct) * pthread_threads_max)
|
||||||
!= PS_OK)
|
!= PS_OK)
|
||||||
return TD_ERR; /* XXX Other error value? */
|
return TD_ERR; /* XXX Other error value? */
|
||||||
|
|
||||||
|
#ifdef ALL_THREADS_STOPPED
|
||||||
/* Read the number of currently active threads. */
|
/* Read the number of currently active threads. */
|
||||||
if (ps_pdread (ta->ph, ta->pthread_handles_num, &num, sizeof (int))
|
if (ps_pdread (ta->ph, ta->pthread_handles_num, &num, sizeof (int)) != PS_OK)
|
||||||
!= PS_OK)
|
|
||||||
return TD_ERR; /* XXX Other error value? */
|
return TD_ERR; /* XXX Other error value? */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Now get all descriptors, one after the other. */
|
/* Now get all descriptors, one after the other. */
|
||||||
for (cnt = 0; cnt < pthread_threads_max && num > 0; ++cnt)
|
for (cnt = 0; cnt < pthread_threads_max && num > 0; ++cnt)
|
||||||
|
@ -52,8 +66,10 @@ td_ta_thr_iter (const td_thragent_t *ta, td_thr_iter_f *callback,
|
||||||
struct _pthread_descr_struct pds;
|
struct _pthread_descr_struct pds;
|
||||||
td_thrhandle_t th;
|
td_thrhandle_t th;
|
||||||
|
|
||||||
|
#ifdef ALL_THREADS_STOPPED
|
||||||
/* First count this active thread. */
|
/* First count this active thread. */
|
||||||
--num;
|
--num;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (ps_pdread (ta->ph, phc[cnt].h_descr, &pds, sizeof_descr)
|
if (ps_pdread (ta->ph, phc[cnt].h_descr, &pds, sizeof_descr)
|
||||||
!= PS_OK)
|
!= PS_OK)
|
||||||
|
|
|
@ -25,27 +25,31 @@ td_err_e
|
||||||
td_ta_tsd_iter (const td_thragent_t *ta, td_key_iter_f *callback,
|
td_ta_tsd_iter (const td_thragent_t *ta, td_key_iter_f *callback,
|
||||||
void *cbdata_p)
|
void *cbdata_p)
|
||||||
{
|
{
|
||||||
struct pthread_key_struct *keys = ta->keys;
|
struct pthread_key_struct *keys;
|
||||||
int pthread_keys_max = ta->pthread_keys_max;
|
int pthread_keys_max;
|
||||||
int cnt;
|
int cnt;
|
||||||
|
|
||||||
/* XXX We have to figure out what has to be done. */
|
|
||||||
LOG (__FUNCTION__);
|
LOG (__FUNCTION__);
|
||||||
|
|
||||||
/* Now get all descriptors, one after the other. */
|
/* Test whether the TA parameter is ok. */
|
||||||
for (cnt = 0; cnt < pthread_keys_max; ++cnt, ++keys)
|
if (! ta_ok (ta))
|
||||||
{
|
return TD_BADTA;
|
||||||
struct pthread_key_struct key;
|
|
||||||
|
|
||||||
if (ps_pdread (ta->ph, keys, &key,
|
pthread_keys_max = ta->pthread_keys_max;
|
||||||
sizeof (struct pthread_key_struct)) != PS_OK)
|
keys = (struct pthread_key_struct *) alloca (sizeof (keys[0])
|
||||||
|
* pthread_keys_max);
|
||||||
|
|
||||||
|
/* Read all the information about the keys. */
|
||||||
|
if (ps_pdread (ta->ph, ta->keys, keys,
|
||||||
|
sizeof (keys[0]) * pthread_keys_max) != PS_OK)
|
||||||
return TD_ERR; /* XXX Other error value? */
|
return TD_ERR; /* XXX Other error value? */
|
||||||
|
|
||||||
if (key.in_use
|
/* Now get all descriptors, one after the other. */
|
||||||
/* Return with an error if the callback returns a nonzero value. */
|
for (cnt = 0; cnt < pthread_keys_max; ++cnt)
|
||||||
&& callback (cnt, key.destr, cbdata_p) != 0)
|
if (keys[cnt].in_use
|
||||||
return TD_DBERR;
|
/* Return with an error if the callback returns a nonzero value. */
|
||||||
}
|
&& callback (cnt, keys[cnt].destr, cbdata_p) != 0)
|
||||||
|
return TD_DBERR;
|
||||||
|
|
||||||
return TD_OK;
|
return TD_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,7 @@ td_thr_get_info (const td_thrhandle_t *th, td_thrinfo_t *infop)
|
||||||
infop->ti_startfunc = pds.p_start_args.start_routine;
|
infop->ti_startfunc = pds.p_start_args.start_routine;
|
||||||
memcpy (&infop->ti_events, &pds.p_eventbuf.eventmask,
|
memcpy (&infop->ti_events, &pds.p_eventbuf.eventmask,
|
||||||
sizeof (td_thr_events_t));
|
sizeof (td_thr_events_t));
|
||||||
|
infop->ti_traceme = pds.p_report_events != 0;
|
||||||
|
|
||||||
return TD_OK;
|
return TD_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,4 +50,29 @@ struct td_thragent
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Type used internally to keep track of thread agent descriptors. */
|
||||||
|
struct agent_list
|
||||||
|
{
|
||||||
|
td_thragent_t *ta;
|
||||||
|
struct agent_list *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* List of all known descriptors. */
|
||||||
|
extern struct agent_list *__td_agent_list;
|
||||||
|
|
||||||
|
/* Function used to test for correct thread agent pointer. */
|
||||||
|
static inline int
|
||||||
|
ta_ok (const td_thragent_t *ta)
|
||||||
|
{
|
||||||
|
struct agent_list *runp = __td_agent_list;
|
||||||
|
|
||||||
|
if (ta == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
while (runp != NULL && runp->ta != ta)
|
||||||
|
runp = runp->next;
|
||||||
|
|
||||||
|
return runp != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* thread_dbP.h */
|
#endif /* thread_dbP.h */
|
||||||
|
|
Loading…
Reference in New Issue