For some reasons, i need to be able to detect the current active core, ie the one on which my code is currently running. Sounds like a basic thing, but really don't find a way to do it...
For info I'm running on WinXP/Vista, with several multicore computers, so any generic answer would be more than welcome.
Thanks in advance for any tip!
If you have access to Visual Studion C++ there are several functions to look at.
First thing to know is WinXP/Vista use logical processor information structures where core association is not necessarily in sequential order. HT capable processors as well as dual/quad core processors complicate issues.
The WindowsC++ library has a system function call GetLogicalProcessorInformation. Look up this function in your MSDN if you have it or Google for it
You are warned against calling this function directly since your application with the call may be running ona version of the O/S that does not have this function. To accomidate ths, it is recommended to make a system call to check for and obtain the address of this function. (returns NULL if not available.) If you receive the address of the function then you use this address to make the call.
The information returned by GetLogicalProcessorInformation is complex but the documentation will guide you in the right direction.
Alternately you can use the __cpuid function call
This function is processor dependent. Anything WinXP runs on is likely to support this function however the return data is processor dependent. Various flavors of Intel processors return different extents of data and AMD,Transmeta and other "x86" processors have different return values. So there is no simple answer.
Additionaly, the __cpuid will return the information regarding the processor your code was on at the moment of the CPUID instruction. If your application affinity is not locking you to a specific logical processor then the data returned from CPUID could refer to a different processor (i.e. when your code is examining the return data your thread could have migrated to a different processor). Similar thing with GetLogicalProcessorInformation.
The information returned from GetLogicalProcessorInformationwill remain static from boot time (unless your system permits hot-swap of processors available on some servers) but unless your thread has it's affinity locked to a logical processor you won't know which processor you are running on (logical or physical).
There is your tip (of the iceburg).
Thanks alot for you detailled answer.
So to sum it up, there's no proper way on XP+vista to determine on which LP a thread is currently running, when this thread has not its affinity locked to a specific LP. That would indeed explain why i don't find a solution to that :)
Well i'll find out an alternative solution to my problem, thanks for the tip!
Why not use Affinity to lock the thread to s specific (list of) processor(s)?
What it sounds like is you want an after the fact thing. This may require you to hook into the O/S thread scheduler. Something not for the timid.
You can statistically sample which CPU the thread is running on (as with a thread profiler), but this will not give you an absolutely correct assessment. Sometimes "good enough approximation" is good enough.
For your desktop machine try using CPUID with EAX=1 and use the high byte of EBX. This is the APIC ID field. This may be good enough to identify the processor at the time of the CPUID. Do not assume APIC ID is sequentially numbered. Make an array of 256 counters (64-bit), initialize all to 0. Then in your app, periodically poll with CPUID, use the APIC ID as an index, then accumulate runtime ticks using interlocked add. With long enough run times you should get a good enough statistical sample.
When a thread with an affinity lockcrashes there is nothing to hold the lock. Note, affinity lock does not exclude other threads (of your or other apps) from using the processor(s) in the affinity. Your main thread should know when one of it's spawned threads crashes. You don't need a mutex for that. Using an "I'm still running" mutex probably has no disadvantage so changing the code would have no benefit.
I made this suggestion to a different thread. I will rephrase it here.
Have the control thread spawn a new thread without affinity selected. I would imagine that each spawned thread has some major loop. In the major loop, have each thread determine if it is running without an affinity selected. (static bool or int) if not, determine the processor it is currently running on, tick a counter specific to the processor. Continue running without affinity setting until one of the counters reaches a threshold (could be 1).When the threshold is reached, set the thread'saffinity to that processor.
The main thread, in addition to it's other duties, monitors thread toprocessor association. Having more than one thread assigned to one processor is OK if you have more assigned threads than processors. As threads retire or expire the main control thread might notice one processor having fewer than the average number of thread assignments and a different processor having more than the average number of thread assignments. The main thread would then notify (via shared variable)one of the threads in the more than group to releaseits affinity association and then re enable the favorable affinity discovery routine.
A few shared variables and a tad of code is all it takes.
Application Process 1instance ("main thread")
worker thread 1.1
worker thread 1.n
Application Process2instance ("main thread")
worker thread 2.1
worker thread 2.n
Application Processminstance ("main thread")
Where "controlling thread" code is included in all Application Processes (peer managed) but performed by one of the Application Processes worker threads.
What I would suggest doing (you probably figured this out already) is to use a named mutex for purpose of the "controlling thread". Then when an Application Processbegins always start the controlling thread which creates/opens thenamed mutex andgets blocked on named mutex if mutex held by another application thread. Then if later, the application holding the named mutex exits or crashes, the named mutex is released and if another application is running, its "controlling thread" takes over. There is no need to check for "controlling thread" active since if any application is running then there is always a controlling thread active.
Inter-Application Process communication would use pipe, disk file, or memory mapped file.
The situation is not as easy as described above. Your prior posts indicated that your Application Process is susceptible to crashing. In which case your "controlling thread" code must be written with this consideration in mind. If the "controlling thread" monitors progress and accepts guidance controls (dialog box input) then there is likely little to no defensive code to write. If the "controlling thread" takes an active part in populating a database then you may have a significant chore ahead in writing defensive code.
Good luck, and sorry about the deadline pressure.