Recommended

Multicore community

 

Articles

Intel.com

Microsoft.co.il

 

Community

Microsoft Forums

Intel's Forum

Intel's Multicore Community

 

Resources

http://msdn.com/concurrency

Intel Multicore

NVidia Multicore GPU

 

Downloads

.Net Parallel Extensions

Intel's TBB

WinModules   

 

Tools

AsyncOp Logger

Intel thread analysis

Intel VTune

 

Contact

Asaf Shelly

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ichilov

-->

 

 

 

 

 

 
2 / 1
 
 
 
 
 
 
 

APC

Asynchronous Procedure Call is a synchronization mechanism that works somewhat differently from the common and simpler synchronization objects.

We use the basic synchronization objects such as a MUTEX in our thread to signal another thread that it should stop execution and wait until our thread is done with its work. APCs use a different strategy and thus may require a different design for the application. An APC is a type of callback function that we can call. In a way it is similar to using a regular function pointer and calling it. We would call such a function when we need to notify another Task about something. This Task will then handle the event inside the callback function so that instead of waiting on an event and then working after the event is signaled, the actual work is coded in the callback function. The problem with a regular callback function is that it is called under the context of the caller, so for example when thread A is calling the callback then the callback is running under the context of thread A and thread B is probably doing something else in parallel. Think about a thread that is repainting a window when another thread has some new information to draw on that window.

The mechanism of APC is here to solve this synchronization problem without protecting resources with a MUTEX and without using an Event for signaling. When we use an APC our thread is telling the operating system to make the other thread call the callback function under its own context. In other word Task A is telling Task B to execute a function. Task B will not interrupt its work to perform this action. Instead it will finish all the things that it started with and then when it is done it will begin the execution of the callback function. This is synchronous because it is assumed that the callback function is called only after the Task has completed anything that it was doing and so it has finished using any resources. If we take a look at the example of a window then the task that is painting the window will finish painting the entire window and only then it will begin updating to the new data.

The mechanism of APC will wait for the target Task to finish all of its work. Since applications today are idle most of the times, waiting for the next system event to respond to, it is assumed that when the Task is finished with all of its work then it will enter a wait until the next system even t comes. The operating system (or synchronization library) will steal the Task when it is in a wait state and make it jump to the address of the callback function. When the function returns then the Task goes back to continue the wait state on the original code and function.

Using this synchronization mechanism requires that we do not wait during an operation so we do not use a MUTEX or an Event when we are dealing with a resource.

This is OK:

bool MyFunc( )
{
   Wait for MUTEX A
 
      Wait for MUTEX B
         Use resource A
         Use resource B
         Use resource A
      Release MUTEX B
 
   Release MUTEX A

}

 

The following is not:

bool MyFunc( )
{
   Wait for MUTEX A
      Use resource A
 
      Wait for MUTEX B
         Use resource B
         Use resource A
      Release MUTEX B
 
   Release MUTEX A

}

Our design has to be aware of the existence of APCs and we should not use the Wait API during the work with a shared resource.

 

The advantage in using the APC mechanism is obvious: We don't need to synchronize access to our resources. The performance of the application increases and the complexity for the programmer decreases. This is one of the really few cases where there is no tradeoff between code manageability and runtime performance.

A special feature that can be implemented using an APC for a system that does make extensive use of simple synchronization mechanisms is that the APC mechanism allows us to externally instruct the Task to run code when it is in a Wait State. In other words even though the Task is still waiting we can order it to do something. By using an APC we can write a Watchdog mechanism that can help the Task recover from a Deadlock as gracefully as possible, saving data, checking statuses, closing open files, devices and Handles, and performing some cleanup. This is better than the alternative which is most times just keep the Task running or terminate the Task without knowing what had happened to it.

In Kernel and Real-time operating systems an APC is used to complete a task that has several stages. Such tasks usually start on a high priority and have some additional processing to be done that can happen under lower priority. This is not the same kind of APC that applications in User Mode use.

 

 

 

More on Microsoft's MSDN

No information on Wikipedia