mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 15:47:01 +02:00
MINOR: debug: slightly change the thread_dump_pointer signification
Now the thread_dump_pointer is returned ORed with 1 once done, or NULL when cancelled (for now noone cancels). The goal will be to permit the callee to provide its own pointer. The ha_thread_dump_fill() function now returns the buffer pointer that was used (without OR 1) or NULL, for ease of use from the caller.
This commit is contained in:
parent
2036f5bba1
commit
091de0f9b2
36
src/debug.c
36
src/debug.c
@ -264,8 +264,9 @@ void ha_backtrace_to_stderr(void)
|
|||||||
* indicate the requesting one. Any stuck thread is also prefixed with a '>'.
|
* indicate the requesting one. Any stuck thread is also prefixed with a '>'.
|
||||||
* The caller is responsible for atomically setting up the thread's dump buffer
|
* The caller is responsible for atomically setting up the thread's dump buffer
|
||||||
* to point to a valid buffer with enough room. Output will be truncated if it
|
* to point to a valid buffer with enough room. Output will be truncated if it
|
||||||
* does not fit. When the dump is complete, the dump buffer will be switched to
|
* does not fit. When the dump is complete, the dump buffer will have bit 0 set
|
||||||
* (void*)0x1 that the caller must turn to 0x0 once the contents are collected.
|
* to 1 to tell the caller it's done, and the caller will then change that value
|
||||||
|
* to indicate it's done once the contents are collected.
|
||||||
*/
|
*/
|
||||||
void ha_thread_dump_one(int thr, int from_signal)
|
void ha_thread_dump_one(int thr, int from_signal)
|
||||||
{
|
{
|
||||||
@ -347,7 +348,7 @@ void ha_thread_dump_one(int thr, int from_signal)
|
|||||||
}
|
}
|
||||||
leave:
|
leave:
|
||||||
/* end of dump, setting the buffer to 0x1 will tell the caller we're done */
|
/* end of dump, setting the buffer to 0x1 will tell the caller we're done */
|
||||||
HA_ATOMIC_STORE(&ha_thread_ctx[thr].thread_dump_buffer, (void*)0x1UL);
|
HA_ATOMIC_OR((ulong*)&ha_thread_ctx[thr].thread_dump_buffer, 0x1UL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Triggers a thread dump from thread <thr>, either directly if it's the
|
/* Triggers a thread dump from thread <thr>, either directly if it's the
|
||||||
@ -355,10 +356,11 @@ void ha_thread_dump_one(int thr, int from_signal)
|
|||||||
* a signal if it's a remote one and the feature is supported. The buffer <buf>
|
* a signal if it's a remote one and the feature is supported. The buffer <buf>
|
||||||
* will get the dump appended, and the caller is responsible for making sure
|
* will get the dump appended, and the caller is responsible for making sure
|
||||||
* there is enough room otherwise some contents will be truncated. The function
|
* there is enough room otherwise some contents will be truncated. The function
|
||||||
* waits for the called thread to fill the buffer before returning. It does not
|
* waits for the called thread to fill the buffer before returning (or cancelling
|
||||||
* release the called thread yet.
|
* by reporting NULL). It does not release the called thread yet. It returns a
|
||||||
|
* pointer to the buffer used if the dump was done, otherwise NULL.
|
||||||
*/
|
*/
|
||||||
void ha_thread_dump_fill(struct buffer *buf, int thr)
|
struct buffer *ha_thread_dump_fill(struct buffer *buf, int thr)
|
||||||
{
|
{
|
||||||
struct buffer *old = NULL;
|
struct buffer *old = NULL;
|
||||||
|
|
||||||
@ -381,22 +383,32 @@ void ha_thread_dump_fill(struct buffer *buf, int thr)
|
|||||||
#endif
|
#endif
|
||||||
ha_thread_dump_one(thr, thr != tid);
|
ha_thread_dump_one(thr, thr != tid);
|
||||||
|
|
||||||
/* now wait for the dump to be done */
|
/* now wait for the dump to be done (or cancelled) */
|
||||||
while (HA_ATOMIC_LOAD(&ha_thread_ctx[thr].thread_dump_buffer) != (void*)0x1UL)
|
while (1) {
|
||||||
|
old = HA_ATOMIC_LOAD(&ha_thread_ctx[thr].thread_dump_buffer);
|
||||||
|
if ((ulong)old & 0x1)
|
||||||
|
break;
|
||||||
|
if (!old)
|
||||||
|
return old;
|
||||||
ha_thread_relax();
|
ha_thread_relax();
|
||||||
|
}
|
||||||
|
return (struct buffer *)((ulong)old & ~0x1UL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Indicates to the called thread that the dumped data are collected. It waits
|
/* Indicates to the called thread that the dumped data are collected. It waits
|
||||||
* for the dump to be completed if it was not the case.
|
* for the dump to be completed if it was not the case, and can also leave if
|
||||||
|
* the pointer is NULL (e.g. if a thread has aborted).
|
||||||
*/
|
*/
|
||||||
void ha_thread_dump_done(struct buffer *buf, int thr)
|
void ha_thread_dump_done(struct buffer *buf, int thr)
|
||||||
{
|
{
|
||||||
struct buffer *old;
|
struct buffer *old;
|
||||||
|
|
||||||
/* now wait for the dump to be done, and release it */
|
/* now wait for the dump to be done or cancelled, and release it */
|
||||||
do {
|
do {
|
||||||
old = HA_ATOMIC_LOAD(&ha_thread_ctx[thr].thread_dump_buffer);
|
old = HA_ATOMIC_LOAD(&ha_thread_ctx[thr].thread_dump_buffer);
|
||||||
if (old != (void*)0x1UL) {
|
if (!((ulong)old & 0x1)) {
|
||||||
|
if (!old)
|
||||||
|
return;
|
||||||
ha_thread_relax();
|
ha_thread_relax();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -2106,7 +2118,7 @@ void debug_handler(int sig, siginfo_t *si, void *arg)
|
|||||||
/* first, let's check it's really for us and that we didn't just get
|
/* first, let's check it's really for us and that we didn't just get
|
||||||
* a spurious DEBUGSIG.
|
* a spurious DEBUGSIG.
|
||||||
*/
|
*/
|
||||||
if (!buf || buf == (void*)(0x1UL))
|
if (!buf || (ulong)buf & 0x1UL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* now dump the current state into the designated buffer, and indicate
|
/* now dump the current state into the designated buffer, and indicate
|
||||||
|
Loading…
Reference in New Issue
Block a user