/*----------------------------------------------------- Script for AdSense -----------------------------------------------------*/ /* */ /* Footer ----------------------------------------------- */ #footer { clear: both; text-align: center; color: #333333; } #footer .widget { margin:.5em; padding-top: 20px; font-size: 85%; line-height: 1.5em; text-align: left; } /** Page structure tweaks for layout editor wireframe */ body#layout #header { width: 750px; } -->

Friday, April 23, 2010

Thread Synchronization in User Mode:2

Critical Sections:
A critical section is a small section of code that requires exclusive access to some shared resource before the code can execute. This is a way to have several lines of code "atomically" manipulate a resource. By atomic, I mean that the code knows that no other thread will access the resource.system will not schedule any other threads that want to access the same resource until your thread leaves the critical section.


CRITICAL_SECTION g_cs;
DWORD WINAPI ThreadFun1(PVOID pvParam)
{

while
()
{

EnterCriticalSection(&g_cs);
//......write code. do manipulation (use global resource)
LeaveCriticalSection(&g_cs);
}

return
(0);
}

DWORD WINAPI ThreadFun2(PVOID pvParam)
{

while
()
{

EnterCriticalSection(&g_cs);
//......write code. do manipulation (use global resource)
LeaveCriticalSection(&g_cs);
}

return
(0);
}


allocate a CRITICAL_SECTION data structure, g_cs, and then wrapp any code that touches the shared resource.
Notice that I passed the address of g_cs in all calls to EnterCriticalSection and LeaveCriticalSection.
CRITICAL_SECTION is defined in WinNT.h.
Normally CRITICAL_SECTION structures are allocated as global variables.
CRITICAL_SECTION structures can be allocated as local variables or dynamically allocated from a heap.
There are just two requirements. The first is that all threads that want to access the resource must know the address of the CRITICAL_SECTION structure that protects the resource. You can get this address to these threads using any mechanism you like. The second requirement is that the members within the CRITICAL_SECTION structure be initialized before any threads attempt to access the protected resource.
CRITICAL_SECTION structure is initialized by calling VOID InitializeCriticalSection(PCRITICAL_SECTION pcs);
CRITICAL_SECTION structure can be clean up by calling VOID DeleteCriticalSection(PCRITICAL_SECTION pcs);

Don't Hold Critical Sections for a Long Time
When a critical section is held for a long time, other threads might enter wait states, which will hurt your application's performance.
It's impossible to tell how much time the window procedure requires for processing the WM_SOMEMSG message—it might be a few milliseconds or a few years. During that time, no other threads can gain access to the g_s structure. It's better to write the code as follows:
SOMESTRUCT g_s;
CRITICAL_SECTION g_cs;

DWORD WINAPI SomeThread(PVOID pvParam) {

EnterCriticalSection(&g_cs);
SOMESTRUCT sTemp = g_s;
LeaveCriticalSection(&g_cs);

// Send a message to a window.
SendMessage(hwndSomeWnd, WM_SOMEMSG, &sTemp, 0);
return
(0);
}


This code saves the value in sTemp, a temporary variable. You can probably guess how long the CPU requires to execute this line—only a few CPU cycles. Immediately after the temporary variable is saved, LeaveCriticalSection is called because the global structure no longer needs to be protected.
other threads are stopped from using the g_s structure for only a few CPU cycles instead of for an unknown amount of time.

Source: Summary note from my diary.(when I learnt these concepts long back.

No comments: