A method for profiling software programs uses a small pinned buffer and a
large unpinned histogram buffer. When a process that is being profiled
receives a time slice, the process' program counter is written to the
small pinned buffer by a kernel routine. The small pinned buffer is
configured to be large enough to store several program counters. When the
small pinned buffer is full, or almost full, an internal profiling signal
is sent by the kernel routine. When the process is resumed, any
outstanding signals (including the profiling signal) are processed before
resuming the process. The profiling signal is handled by reading the
program counters from the small pinned buffer, calculating a slot in the
histogram buffer that corresponds to each of the program counters,
incrementing the value in the corresponding histogram slots, and clearing
the small pinned buffer so that it can be reused.