mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-09 23:00:07 +00:00
Update.
* 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.
This commit is contained in:
parent
dbd3e8629f
commit
ab86fbb1d2
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
|
@ -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. */
|
||||
@ -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 ();
|
||||
@ -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();
|
||||
|
@ -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.
|
||||
|
@ -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))
|
||||
|
||||
|
49
linuxthreads_db/td_ta_clear_event.c
Normal file
49
linuxthreads_db/td_ta_clear_event.c
Normal file
@ -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
linuxthreads_db/td_ta_event_getmsg.c
Normal file
124
linuxthreads_db/td_ta_event_getmsg.c
Normal file
@ -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;
|
||||
}
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -26,64 +26,72 @@ 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,
|
||||
sigset_t *ti_sigmask_p, unsigned int ti_user_flags)
|
||||
{
|
||||
struct pthread_handle_struct *handles = ta->handles;
|
||||
int pthread_threads_max = ta->pthread_threads_max;
|
||||
size_t sizeof_descr = ta->sizeof_descr;
|
||||
struct pthread_handle_struct phc[pthread_threads_max];
|
||||
int num;
|
||||
int cnt;
|
||||
|
||||
LOG (__FUNCTION__);
|
||||
|
||||
/* 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? */
|
||||
|
||||
/* 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 get all descriptors, one after the other. */
|
||||
for (cnt = 0; cnt < pthread_threads_max; ++cnt, ++handles)
|
||||
{
|
||||
struct pthread_handle_struct phc;
|
||||
for (cnt = 0; cnt < pthread_threads_max && num > 0; ++cnt)
|
||||
if (phc[cnt].h_descr != NULL)
|
||||
{
|
||||
struct _pthread_descr_struct pds;
|
||||
td_thrhandle_t th;
|
||||
|
||||
if (ps_pdread (ta->ph, handles, &phc,
|
||||
sizeof (struct pthread_handle_struct)) != PS_OK)
|
||||
return TD_ERR; /* XXX Other error value? */
|
||||
/* First count this active thread. */
|
||||
--num;
|
||||
|
||||
if (phc.h_descr != NULL)
|
||||
{
|
||||
struct _pthread_descr_struct pds;
|
||||
td_thrhandle_t th;
|
||||
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_descr) != PS_OK)
|
||||
return TD_ERR; /* XXX Other error value? */
|
||||
/* The manager thread must be handled special. The descriptor
|
||||
exists but the thread only gets created when the first
|
||||
`pthread_create' call is issued. A clear indication that
|
||||
this happened is when the p_pid field is non-zero. */
|
||||
if (cnt == 1 && pds.p_pid == 0)
|
||||
continue;
|
||||
|
||||
/* The manager thread must be handled special. The descriptor
|
||||
exists but the thread only gets created when the first
|
||||
`pthread_create' call is issued. A clear indication that
|
||||
this happened is when the p_pid field is non-zero. */
|
||||
if (cnt == 1 && pds.p_pid == 0)
|
||||
continue;
|
||||
/* Now test whether this thread matches the specified
|
||||
conditions. */
|
||||
|
||||
/* Now test whether this thread matches the specified
|
||||
conditions. */
|
||||
/* Only if the priority level is as high or higher. */
|
||||
if (pds.p_priority < ti_pri)
|
||||
continue;
|
||||
|
||||
/* Only if the priority level is as high or higher. */
|
||||
if (pds.p_priority < ti_pri)
|
||||
continue;
|
||||
/* Test the state.
|
||||
XXX This is incomplete. */
|
||||
if (state != TD_THR_ANY_STATE)
|
||||
continue;
|
||||
|
||||
/* Test the state.
|
||||
XXX This is incomplete. */
|
||||
if (state != TD_THR_ANY_STATE)
|
||||
continue;
|
||||
/* XXX For now we ignore threads which are not running anymore.
|
||||
The reason is that gdb tries to get the registers and fails.
|
||||
In future we should have a special mode of the thread library
|
||||
in which we keep the process around until the actual join
|
||||
operation happened. */
|
||||
if (pds.p_exited != 0)
|
||||
continue;
|
||||
|
||||
/* XXX For now we ignore threads which are not running anymore.
|
||||
The reason is that gdb tries to get the registers and fails.
|
||||
In future we should have a special mode of the thread library
|
||||
in which we keep the process around until the actual join
|
||||
operation happened. */
|
||||
if (pds.p_exited != 0)
|
||||
continue;
|
||||
|
||||
/* Yep, it matches. Call the callback function. */
|
||||
th.th_ta_p = (td_thragent_t *) ta;
|
||||
th.th_unique = phc.h_descr;
|
||||
if (callback (&th, cbdata_p) != 0)
|
||||
return TD_DBERR;
|
||||
}
|
||||
}
|
||||
/* Yep, it matches. Call the callback function. */
|
||||
th.th_ta_p = (td_thragent_t *) ta;
|
||||
th.th_unique = phc[cnt].h_descr;
|
||||
if (callback (&th, cbdata_p) != 0)
|
||||
return TD_DBERR;
|
||||
}
|
||||
|
||||
return TD_OK;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Disable specific event.
|
||||
/* Disable specific event for thread.
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
|
||||
@ -18,13 +18,40 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "thread_dbP.h"
|
||||
|
||||
|
||||
td_err_e
|
||||
td_thr_clear_event (const td_thrhandle_t *th, td_thr_events_t *event)
|
||||
td_thr_clear_event (th, event)
|
||||
const td_thrhandle_t *th;
|
||||
td_thr_events_t *event;
|
||||
{
|
||||
/* XXX We have to figure out what has to be done. */
|
||||
td_thr_events_t old_event;
|
||||
int i;
|
||||
|
||||
LOG (__FUNCTION__);
|
||||
return TD_NOCAPAB;
|
||||
|
||||
/* Write the new value into the thread data structure. */
|
||||
if (ps_pdread (th->th_ta_p->ph,
|
||||
((char *) th->th_unique
|
||||
+ offsetof (struct _pthread_descr_struct,
|
||||
p_eventbuf.eventmask)),
|
||||
&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 (th->th_ta_p->ph,
|
||||
((char *) th->th_unique
|
||||
+ offsetof (struct _pthread_descr_struct,
|
||||
p_eventbuf.eventmask)),
|
||||
&old_event, sizeof (td_thrhandle_t)) != PS_OK)
|
||||
return TD_ERR; /* XXX Other error value? */
|
||||
|
||||
return TD_OK;
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "thread_dbP.h"
|
||||
|
||||
@ -66,6 +67,8 @@ td_thr_get_info (const td_thrhandle_t *th, td_thrinfo_t *infop)
|
||||
infop->ti_lid = pds.p_pid;
|
||||
infop->ti_ta_p = th->th_ta_p;
|
||||
infop->ti_startfunc = pds.p_start_args.start_routine;
|
||||
memcpy (&infop->ti_events, &pds.p_eventbuf.eventmask,
|
||||
sizeof (td_thr_events_t));
|
||||
|
||||
return TD_OK;
|
||||
}
|
||||
|
@ -28,14 +28,29 @@ td_thr_set_event (th, event)
|
||||
const td_thrhandle_t *th;
|
||||
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 (th->th_ta_p->ph,
|
||||
((char *) th->th_unique
|
||||
+ offsetof (struct _pthread_descr_struct,
|
||||
p_eventbuf.eventmask)),
|
||||
&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 (th->th_ta_p->ph,
|
||||
((char *) th->th_unique
|
||||
+ offsetof (struct _pthread_descr_struct,
|
||||
p_eventbuf.eventmask)),
|
||||
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;
|
||||
|
@ -331,10 +331,18 @@ extern td_err_e td_ta_tsd_iter (const td_thragent_t *__ta, td_key_iter_f *__ki,
|
||||
extern td_err_e td_ta_event_addr (const td_thragent_t *__ta,
|
||||
td_event_e __event, td_notify_t *__ptr);
|
||||
|
||||
/* Enable EVENT for all threads. */
|
||||
/* Enable EVENT in global mask. */
|
||||
extern td_err_e td_ta_set_event (const td_thragent_t *__ta,
|
||||
td_thr_events_t *__event);
|
||||
|
||||
/* Disable EVENT in global mask. */
|
||||
extern td_err_e td_ta_clear_event (const td_thragent_t *__ta,
|
||||
td_thr_events_t *__event);
|
||||
|
||||
/* Return information about last event. */
|
||||
extern td_err_e td_ta_event_getmsg (const td_thragent_t *__ta,
|
||||
td_event_msg_t *msg);
|
||||
|
||||
|
||||
/* Set suggested concurrency level for process associated with TA. */
|
||||
extern td_err_e td_ta_setconcurrency (const td_thragent_t *__ta, int __level);
|
||||
|
@ -41,6 +41,12 @@ struct td_thragent
|
||||
|
||||
/* Pointer to the `__pthread_threads_events' variable in the target. */
|
||||
psaddr_t pthread_threads_eventsp;
|
||||
|
||||
/* Pointer to the `__pthread_last_event' variable in the target. */
|
||||
psaddr_t pthread_last_event;
|
||||
|
||||
/* Pointer to the `__pthread_handles_num' variable. */
|
||||
psaddr_t pthread_handles_num;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user