3. Logging a sample

As mentioned, the sample is logged into the buffer specific to the current CPU. The CPU buffer is a simple array of pairs of unsigned long values; for a sample, they hold the PC value and the counter for the sample. (The counter value is later used to translate back into the relevant event type the counter was programmed to).

In addition to logging the sample itself, we also log task switches. This is simply done by storing the address of the last task to log a sample on that CPU in a data structure, and writing a task switch entry into the buffer if the new value of current() has changed. Note that later we will directly de-reference this pointer; this imposes certain restrictions on when and how the CPU buffers need to be processed.

Finally, as mentioned, we log whether we have changed between kernel and userspace using a similar method. Both of these variables (last_task and last_is_kernel) are reset when the CPU buffer is read.