The invention relates generally to event tracing programs and, more particularly, to an event tracing program having per-processor log buffers.
An information technology manager who makes purchasing decisions for an organization needs to have an idea about the load the organization""s computer systems are expected to handle. A convenient way of obtaining this information is to track the performance of the system during periods of heavy use. One well known method of tracking system performance data is to use counters, which are stored values that get incremented every time a particular event occurs. For example, an operating system could provide one counter for keeping track of disk reads on a particular drive and another counter for keeping track of disk writes. If a system administrator wanted to know how many I/O operations occur during the day, he could obtain the counters through a program such as PERFORMANCE MONITOR, which is implemented on the MICROSOFT WINDOWS NT or WINDOWS 2000 brand operating systems, or through a published programming interface. On multiprocessor systems, counters are normally contained in globally accessible data structures and are therefore shared among several processors.
Event tracing is a technique often used in conjunction with counters to track system performance data by recording events of interest in a log buffer. For example, a read on disk number one can be recorded as xe2x80x9cread #1.xe2x80x9d The total number of reads can then be tallied in a post-processing phase by analyzing the logged data. On multiprocessor systems, log buffers also tend to be global entities.
There are several disadvantages to using global data structures to track performance on a multiprocessor system. One problem is that when two or more processors simultaneously attempt to update a counter or log their respective events in a shared buffer, the data may become corrupted. A solution to this problem is to use a synchronization variable known as a xe2x80x9cspin lock.xe2x80x9d For example, if two processors are both competing to write to a log buffer, the first processor to initiate the operation xe2x80x9clocksxe2x80x9d out the other processor by setting a spin lock variable to a xe2x80x9clockedxe2x80x9d state and raising the interrupt request level (IRQL) of the first processor. The other processor remains in a loop as long as it detects that the spin lock variable is xe2x80x9clocked.xe2x80x9d After the first processor finishes recording an event in the log buffer, it sets the spin lock to an xe2x80x9cunlockedxe2x80x9d state and lowers the IRQL, thus allowing the other processor to log an event. But using a spin lock causes some processors to waste time waiting for the spin lock to be released. Also, an IRQL change is both time consuming and cannot be easily and efficiently implemented in user mode.
Another problem with using global data structures to track performance data on a multiprocessor system is that when the data is in cache and two or more processors are attempting to manipulate the data, there is a chance that one processor may flush the cache before a second processor has finished its modification. The second processor would then be required to retrieve the block containing the performance data from slower main memory in order to complete the modification.
Reserving separate memory blocks for each processor and storing performance data locally is a more effective way to accomplish event tracing in multiprocessing systems than using global data. Dedicating each active buffer to a single processor allows each processor to log events to its respective buffer independently of other processors, thereby eliminating the need for a synchronization mechanism.
When a processor""s log buffer fills up, the buffer may need to undergo a process known as xe2x80x9cflushing,xe2x80x9d in which the contents of the buffer are written to a more permanent location, such as a disk file, so that the buffer can be reused. However, the processor may experience a context switch while the event tracing program is recording the event data in the buffer, and the buffer may get flushed in the new context before the event data is completely recorded. To prevent a context switch from occurring, it is conventional to raise the processor""s IRQL during the data log write operation. However, on many processors, raising the IRQL requires a large number of cycles, thus making this solution impractical or unacceptable in terms of performance overhead. Furthermore, if event logging takes place in the processor""s user mode (as opposed to the kernel mode), this solution is unworkable, since the IRQL generally cannot be changed from the user mode. Thus, there is a need for a method of recording events in a buffer that maintains the integrity of the buffer data during context switches.
The invention is generally realized as an event tracing program. The event tracing program generally receives performance data about an event occurring on the computer system from a data producer program. The event tracing program responds by recording the event performance data in one of a set of a log buffers. When a log buffer becomes full, the event tracing program places the log buffer on a flush list. The contents of each buffer on the flush list are eventually written out to a more permanent storage location, such as to a log file on a disk, and the buffer itself is transferred to the free list for reuse. To prevent a buffer from being flushed event performance data is being recorded in it, a reference count is incremented prior to the recording process to signify that the buffer is currently being modified.