Forcing termination of Win32 thread before its uantum expiration

Forcing termination of Win32 thread before its uantum expiration

iliyapolak's picture

Hi everybody,

Hope that this is right forum for my question.

i am experimenting with native Win32 multithreading and trying to force currently executing to thread to relinquish its cpu time by calling Win API function sleep() with 0 argument.When sleep(0) is called from within thread function then currently executing thread will be swapped and put in wait queue.

One interesting question arises which is related to exact moment of quantum interval when the execution is postponed and how to control it programmatically.If  new thread is created from within the main function thread and that new thread has priority rised to high and it is scheduled to run immediatly after creation so how (inside thread's function) or better when sleep(0) call will be executed in order for example to stop the execution after 1/2 of quantum expires.I am thinking about the inserting call to sleep at begining oof the function thread and verifying it in disassembly so I could be able to theoretically postpone the execution as a function of location(at address space) of call instruction.By insering some job/task or calculation which will keep thread busy for quantum period ~30ms and insering inside loop call to sleep function I can postpone the execution of thread before it quantum expires.

Does anyone have some experience with this?

Source code is included.

Thanks in advance

AttachmentSize
Download threadquantumtestapp.cpp9.8 KB
12 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.
iliyapolak's picture

Sorry it should be "quantum expiration"

jimdempseyatthecove's picture

sleep(0) relinquishes remainder of time-slice and places current thread at end of current thread's priority of run queue (which may have 0 or more pending threads).

In your code supplied, and relating to your concern about initiating thread being of lower priority of launched threads, have the initiating thread create a single event with manual reset and initialized to the reset state. Then create the additional higher priority threads. The start of the thread function should have a WaitForSingleEvent on the new event object (IOW all newly created highr priority threads will wait until the initiating thread signals completion of launching all new threads).

Jim Dempsey

www.quickthreadprogramming.com
jimdempseyatthecove's picture

By the way, should you use sched_yield() or equivilent Windows function SwitchToThread, then note that the current thread relinquishes remaining thread time slice and is not inserted at the back of the current priority queue, but rather is inserted in between the curent runable threads at its priority level and the threads waiting for I/O completion (or other event) having the same priority level. These waiting for I/O or event threads will not progress out of this this state on I/O completion (or other event) in front of a sched_yield()-ing thread. (at least this was my experience). The net effect is if the high priority thread is in a polling loop with sched_yield() waiting for a different thread to complete an I/O and there are insufficient cores available for it to run, then the high priority polling threads will not permit the I/O completion thread to run to the point of setting its "done" flag. (IOW use sleep(0))

Jim Dempsey

www.quickthreadprogramming.com
iliyapolak's picture

Thanks Jim for answer.

I must admit that uploaded code still does not implement calls to thread priority functions.My question was more related to how in controllable way postpone the execution of thread before quantum expiration.I mean if is it possible to do it only by changing the location at (assembly level) of  call to sleep(0) function.Thread must execute at high priority in order to be not postponed by other more priviledged thread  before the call to sleep().

iliyapolak's picture

I did not see your second answer when I posted my response.I will do as you advised me and report back the results.

jimdempseyatthecove's picture

>>Thread must execute at high priority in order to be not postponed by other more privileged thread  before the call to sleep().

What differenc does it make if the thread about to execute sleep(0) gets preempted or time sliced out?

In my earlier post the term "Should" is a conditional clause like an "if" statement in programming.

If (should) you desire to use compute loops using sleep(0) when nothing to do then either use events (Windows) or condition variables (pthread) or other constructs available to you for example a mutex or semaphore etc.... An alternative technique is after n trips through sleep(0) with nothing to do, then tweak up the sleep duration: sleep(1), 10, 100,....

In your posted code, The thread running ThreadFunc will compute its result, search the ThreadArr for its thread handle, print info, sleep(0), then resume searching ThreadArr, then exit. There is no logic to what you are attempting to do. This thread will almost immeiately exit after searching the remainder of ThreadArr.

Jim Dempsey

www.quickthreadprogramming.com
iliyapolak's picture

>>>There is no logic to what you are attempting to do. This thread will almost immeiately exit after searching the remainder of ThreadArr.>>>

I know that.Uploaded code is still unfinished and call to sleep from within ThreadArr loop was used for testing with debugger.

>>...By insering some job/task or calculation which will keep thread busy for quantum period ~30ms and insering inside loop
>>call to sleep function I can postpone the execution of thread before it quantum expires...

This is possible and I would use RDTSC instruction to verify that the thread is executed for some number of ms, or even a couple of hundreds of nano-seconds (!). Take a look at several threads related to synchronization of TSCs ( Time Stamp Counter ) between different CPUs on IDZ forums ( there are two threads at the moment ). Also, instead of a call to Win32 API function Sleep( 0 ) I would use some synchronization object, Event for example, and that object needs to be controlled from a different active thread with the same or even higher priority.

iliyapolak's picture

This exactly what I plan to do.Executing thread will have its priority set to High or even Real Time and RDTSC instruction will be used to measure for-loop block to gauge the exact time needed to accomplish the task and later call to sleep(0) eill be issued.The other option is to use some logic inside for loop to postpone the execution after some number of loop iterations or even try to postpone the execution after some time was spent executing the code.

>>...The other option is to use some logic inside for loop to postpone the execution after some number of loop iterations...

That logic could be based on a call to:
...
::SuspendThread( hThread );
...

iliyapolak's picture

Thanks for info.

Login to leave a comment.