This assumes that Windows executes at least a `#StoreLoad' style memory
barrier when interrupts are processed and/or when user-to-kernal mode
transitions occur. This code uses undocumented native NT API
`NtQuerySystemInformation' to acquire per-cpu information block:
struct SYSTEM_PROCESSOR_TIMES {
LARGE_INTEGER IdleTime;
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER DpcTime;
LARGE_INTEGER InterruptTime;
ULONG InterruptCount;
};
I monitor `SYSTEM_PROCESSOR_TIMES::KernelTime' and
`SYSTEM_PROCESSOR_TIMES::InterruptCount' with a simple polling technique.
Examine the `windows::sync_epoch::poll()' procedure for further context. The
procedure returns true when each processor has entered the kernel or
executed an interrupt at least twice. This assumes that each processor has
executed a memory barrier at least once.
One can use this to implement a critical aspect of exotic synchronization
algorihtms such as RCU, vZOOM, RCU+SMR, asymmetric rw-lock, ect... This uses
a passive detection technique, as opposed to an active one like
`FlushProcessWriteBuffers()'. Therefore, it might be a bit more lightweight
because I don't believe that `NtQuerySystemInformation' sends an IPI to all
processors to gather the per-cpu information.
This code was partially stripped from a portion my vZOOM library; I
converted the C to C++ for brevity. The vZOOM code uses a more robust
technique that can even handle dynamically added processors.
I know this works on XP, but I am not sure about Vista. Can you check that
out for me? The robust version that vZOOM uses can adapt if Vista has added
extra members to the `SYSTEM_PROCESSOR_TIMES' data-structure. This version
does not do that. If Vista added membars to the struct, then you will get
buffer overrun.
Thanks.
Any thoughts?
;^)
I make mistake here. If Vista and/or Windows 7 added members to the struct,
you will not get a buffer overrun. Instead, the function will simply fail,
and return the correct size in the `ReturnLength' parameter:
http://msdn.microsoft.com/en-us/library/ms724509.aspx
The hack code I posted as-is will simply throw in this case; which is MUCH
better than a buffer overrun.
Sorry for any confusions!