On Thu, Jun 08, 2023 at 06:25:55PM +0800, Leo Yan wrote:
[...]
Seems to me, this is a synchronization issue between the field 'tidq->prev_thread' and 'tidq->prev_packet'.
It's still hard for me to understand "two adjacent packets on the same thread will say they branched from the previous thread that ran", IIUC, even we move thread swapping into cs_etm__set_thread(), if the two adjacent packets are in the same thread context, we can skip to update fields 'tidq->prev_thread' and 'tidq->prev_packet'.
Sorry for typo, here should be:
... skip to update fields 'tidq->prev_thread' and 'tidq->thread'.
So I am curious if below cs_etm__set_thread() works or not?
static void cs_etm__set_thread(struct cs_etm_auxtrace *etm, struct cs_etm_traceid_queue *tidq, pid_t tid) { struct machine *machine = &etm->session->machines.host;
/* No context switching, bail out */ if ((tidq->thread->tid != tid) return;
/* If tid is -1, we simply use idle thread context */ if (tid == -1) goto find_idle_thread;
/* * The new incoming tid is different from current thread, * so it's to switch to the next thread context. */
/* Swap thread contexts */ thread__put(tidq->prev_thread); tidq->prev_thread = thread__get(tidq->thread);
/* Find thread context for new tid */ thread__zput(tidq->thread); tidq->thread = machine__find_thread(machine, -1, tid);
find_idle_thread: /* Couldn't find a known thread */ if (!tidq->thread) tidq->thread = machine__idle_thread(machine); }
Thanks, Leo