Archive

Archive for the ‘Windows Vista’ Category

How to make Windows 7 taskbar like Windows Vista

March 31st, 2009 Sarath Comments

As we’ve seen, Windows vista has a whole revamped taskbar. Windows Vista, still follows the old kind of taskbar which we’ve been seeing since the initial version of Windows. Because of this reason, lot of people are not comfortable using the new taskbar. Or some guys are not ready to accept the changes. So for them, here’s tip to change Windows 7 taskbar similar to Windows Vista. But functionally it’s not really similar to windows Vista, it’s ‘almost a replica’ of it.

image

What you’re seeing above is an original Windows 7 taskbar. Windows provides ways to modify it’s appearance.

Right Click on taskbar->Properties. From the appearing dialog, chose “User Small Icons” (it’s again according to your convenience). The also opt for “Combine when toolbar is full” option from Toolbar buttons combo. See the image below.

TBPPT

The resultant taskbar may appear as followsimage

Thanks Tim Sneath for his great tips

 

Categories: Tips, Windows 7, Windows Vista Tags: ,

How to Create a drop down button in Windows Vista, 7?

February 19th, 2009 Sarath Comments

MenuIn this post, I’m introducing the new button style which is introduced in Windows Vista and above. It’s no more painful to create a Drop down button with Windows Vista, earlier it was accomplished by placing two controls side by side and handle it’s message separately.

Windows Vista introduced new button style BS_SPLITBUTTON and you can set this new style by specifying as parameter of CreateWindow API if you’re dynamically creating button control or by modifying the style using ModifyStyle API. To use this style Windows Vista or higher required .


Using with CreateWindow/CButton::Create API

[sourcecode language='cpp']
HWND hWndButtonMain = CreateWindow(_T(”Button”), _T(”Split Button”),
WS_CHILD | WS_VISIBLE | BS_SPLITBUTTON,
10, 10, 120, 50,
m_hWnd, (HMENU)IDC_BTN_BUTTON1, AfxGetApp()->m_hInstance, NULL);
[/sourcecode]

Or

[sourcecode language='cpp']
CButton* pButton = new CButton;
pButton->Create( _T( “Split Button”), WS_CHILD | WS_VISIBLE | BS_SPLITBUTTON,CRect(10,10,120,50),this,IDC_BUTTON1);
[/sourcecode]

Or modifying Existing control

[sourcecode language='cpp']
m_SplitButton.ModifyStyle(0, BS_SPLITBUTTON );
[/sourcecode]

Handling Dropdown Event

Add message handler for BCN_DROPDOWN in your message handler or in message map of your MFC window class

[sourcecode language='cpp']
ON_NOTIFY(BCN_DROPDOWN, IDC_BUTTON1, &CControlSampleDlg::OnBnDropDownButton1)
[/sourcecode]

In the message Handler, Display the popup menu and the menu item can be handled using ON_COMMAND message with associated menu ID.

[sourcecode language='cpp']
void CControlSampleDlg::OnBnDropDownButton1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMBCDROPDOWN pDropDown = reinterpret_cast(pNMHDR);

Button_SetDropDownState( m_SplitButton, TRUE );

RECT rc;

// Get the bounding rectangle of the client area
::GetWindowRect(m_SplitButton, &rc);

HMENU hmenu = LoadMenu(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDR_MENU1));
HMENU hmenuTrackPopup;

hmenuTrackPopup = GetSubMenu(hmenu, 0);
TrackPopupMenuEx(hmenuTrackPopup, TPM_RIGHTBUTTON, rc.left, rc.bottom, m_hWnd, NULL);
DestroyMenu(hmenu);

Button_SetDropDownState( m_SplitButton, FALSE );
*pResult = 0;
}
[/sourcecode]

Virtual CD/DVD for Windows 7 (beta)

January 20th, 2009 Sarath Comments

After installing Windows 7 in my laptop, I had to use some of my DVD image files. As usual I tried installing Magic Disc which is my favorite Virtual DVD Drive. The installation had shown up some problems and finally somehow I was able to launch Magic Disc but I failed to map the image file and instead I tried Virtual Clone Drive. Now things are working fine but Virtual Clone Drive is not having much options and easiness of use like Magic Disc. Bye Magic Disc at least till you fix the problems with Win7.

Update[3/15/2009 - 10:06 AM IST] : My all-time-favorite Magic Disc is now supporting Windows 7. You can download it from their website.

Categories: Windows 7, Windows Vista Tags:

What you can do if your Dell laptop doesn’t show Bluetooth Device after re-installing Windows Vista?

January 17th, 2009 Sarath Comments

image After re-installing Windows Vista, I was unable to see my Bluetooth device in my XPS 1330 Laptop. None of the devices left unidentified when I checked the device manager. I can’t also see any options in the control panel to configure the device.

When I tried re-installing the Bluetooth driver, it said Turn the Turn on the Bluetooth device by pressing Fn+F2 key or using the radio button on the laptop. I wasn’t lucky with their instructions as none of these options turned on the Bluetooth device.

I immediately contacted the support person and he suggested to download and install “Patch for Dell Wireless 355 Bluetooth Module (Bluetooth 2.0 + EDR)” from http://support.dell.com/. Viola, it worked fine. He said it’s because of some hardware/driver conflicts with wireless device and Bluetooth device.

Make sure of following things before download

1. You will not be able to find this patch under the Driver downloads for Dell XPS 1330.

2. You will have to navigate to “Driver Downloads->Notebooks->Inspiron->Model 6400 and choose operating system as “Windows XP” even you’re running Windows Vista

3. Download and apply patch. Ensure that you’re downloading the patch, not the driver. It’s only 153KB in size (when I downloaded)

4. The given link above is valid when I posted this, so please properly navigate and install the patch. If you’ve any further confusions call Dell support center

5. Do this at your own risk. Don’t blame me if something went wrong. So far this patch worked fine for me.

Categories: Misc, Personal, Tips, Windows Vista Tags:

Where’s my Hibernate option in Windows Vista?

January 7th, 2009 Sarath Comments

I was really greedy when I opted “Hibernate File Cleaner” to save 2 GB of space in my C drive. I rarely use hybernate option. 

image

I thought Windows would cleanup 2GB space and takes it whenever necessary (if I opt hibernate). But I was wrong. Soon after “Hybernate” option went out from system start menu on opting “Hybernate File Cleaner”. I searched over the whole control panel to get an option to re-enable hybernate in my machine. But I wasn’t lucky enough :(

Finally a google search blessed me with a KB article.

So how you can re-enable Hybernate option if it’s not there?

  1. Click Start, and then type cmd in the Start Search box.
  2. In the search results list, right-click Command Prompt, and then click Run as Administrator.
  3. When you are prompted by User Account Control, click Continue.
  4. At the command prompt, type powercfg.exe /hibernate on , and then press ENTER.
  5. Type exit, and then press ENTER.
  6. If you give powercfg.exe /hibernate off will make Hybernate option unavailable.

How to geek also has a related entry

Categories: Misc, Softwares, Tips, Windows Vista Tags:

What the hell Happened with Dell XPS M1330 Display Driver/Hardware?

November 12th, 2008 Sarath Comments

I was watching movie “Happy Days” in my laptop and after few minutes the screen goes to a rainbow colored pixels and soon my PC got stuck and I had to “Hard Reboot” my dear lappy. I thought it might be some codec issue or something. After rebooting I started watching the remaining part of the movie and in between the screen went again as previous and I could actually see a BSOD in my notebook for the first time.

Anyway I rebooted again and checked the dump file from C:\Windows\MiniDump with the help of WinDBG. It’s reported that probably

Probably caused by : nvlddmkm.sys ( nvlddmkm+518d3 )

The stack back trace shown as follows

ChildEBP RetAddr  Args to Child            
WARNING: Stack unwind information not available. Following frames may be wrong.
8a316ce4 8be5c5bc 862ea000 00000000 00000001 nvlddmkm+0×518d3
8a317a88 8be5c46c 862ea000 00000000 8c4b26c8 nvlddmkm+0×525bc
8a317b04 8be5b7c3 863388c0 00000006 b4adca36 nvlddmkm+0×5246c
8a317b2c 8be5c938 00000117 0001fa08 92546200 nvlddmkm+0×517c3
8a317b50 8be146f2 862ea000 92546040 8a317b80 nvlddmkm+0×52938
8a317b60 8c57a154 862ea000 8a317bb8 00020000 nvlddmkm+0xa6f2
8a317b80 8c5803c5 8a317bb8 925dd5c8 845e4008 dxgkrnl+0×75154
8a317be8 8c580a97 9aebc4d0 00000001 845e4008 dxgkrnl+0×7b3c5
8a317c04 8c51ded1 00000000 00000102 925dd5c8 dxgkrnl+0×7ba97
8a317c6c 8c52eef4 925dd5c8 00042a55 00000000 dxgkrnl+0×18ed1
8a317c98 8c52ec54 925dd5c8 00000000 00000000 dxgkrnl+0×29ef4
8a317cc4 8c50ba4c 00000002 9d7efc18 00000000 dxgkrnl+0×29c54
8a317cc8 00000000 9d7efc18 00000000 00000000 dxgkrnl+0×6a4c

It’s hard to figure out what happened with this minimal information but one thing was sure, my display driver is the center point for the crash. I removed the driver and rebooted again. Windows Vista provided the default driver for the hardware and it could not solve the issue again. This time I got a new message after blinking to a black screen that, nVidia Driver(nvlddmkm) failed to perform and windows recovered from the error. On reading few blogs, I understood that this problem is not happening with the classic theme in Vista. Anyway I downloaded the latest version of Video Driver from dell’s website and upgraded still the problem persists :( . Even I was unable to enable Windows Vista theme. I was much desperate and closed hard the lid of laptop and went to bed after trying lot of different options.

Today I just downloaded the latest version of BIOS Software from Dell’s website and I upgraded to version 8 to Version 13 of the bios software. As a magic the problem flew away. I also downloaded the other latest drivers and upgraded my PC.

In Dell’s website, it’s said that this could be hardware problem and Dell will be replacing the problematic hardware. They had asked to update BIOS to resolve this issue. BUT STILL I’M CONFUSED TO GO FOR A REPLACEMENT OF GPU. I brought this laptop from Japan and now I’m in India. I dint opted for International warranty. Thus I’ve to send across to get my proper service :( .

According to Engadget, what I understood that, it’s a serious problem and Dell is trying to fix it by increasing the fan speed to compensate the heat sink issues.

So yeah, quite a few NVIDIA GPUs have been acting up. Nothing new there. However, Dell’s attempting to help its laptop owners out by making a few notable BIOS updates readily available for download. Apparently the issue “is a weak die / packaging material set, which may fail with GPU temperature fluctuations.” In order to combat the problem, Dell’s BIOS flashes “modify the fan profile to help regulate GPU temperature fluctuations,” though the Round Rock powerhouse only promises that the updates will “help reduce the likelihood of GPU issues.” Hit the read link and give it a go — it can’t hurt… we hope.

If someone has any idea, please tell me, should I go for a hardware replacement?

—– update (Wednesday 11/19/2008 4:48 PM IST)—-

I just called the Dell-India support center. The awesome guy offered technical support for me even I purchased it outside India. After few reboots, the whole system went blank. I’m not even able to see the BIOS screen in the startup. It’s the problem with the graphics hardware. Thanks Dell for your great support but still I feel sad about the poor quality of your most demanding line of laptop. Even I’m suffering the heat on arm rest area after few minutes of operation. That’s really bad :(

Categories: Misc, Windows Vista Tags: ,

Double Buffering Helpers in Windows Vista

November 4th, 2008 Sarath Comments

image In these days, double buffering with windows was a bit tedious task. You will have to write your own double buffering classes to avoid flickering in your drawing. Those who don’t know, why we’re using double buffering, just Google and find it out yourself… If we write as pseudocode, the double buffering can be carried out in the following steps.

[sourcecode language='cpp']
CPaintDC dcWnd(this);
// Create offscreen DC
CDC dcOff;
dcOff.CreateCompatibleDC(&dc);

CBitmap bmp;
bmp.CreateCompatibleBitmap();

dcOff.SelectObject(&bmp)// Now all drawings will be recorded on the bitmap
dcOff.YourDrawingFxn(); // you can do your own drawing
dcWnd.BitBlt( …, &dcOff, ); // Directly blit to screen
[/sourcecode]

Anyway Windows Vista UxTheme DLL provides built-in functionalities to support double buffering for your application. It again follows the trivial method of drawing but it’s more flexible and easy to use. You don’t have to burn your brain cells to create off-screen DC and rendering. The new UxTheme.DLL provides following functions for basic buffered painting. Actually I noticed these functions when I was writing the previous post on Getting theme information. Then I just saw the PPT and video of Raymond Chen from PDC 2008. I’m really impressed with his session.

BufferedPaintInit – Initialize buffered painting for the current thread.

BufferedPaintUnInit – Closes down buffered painting for the current thread

BeginBufferedPaint – begins buffered paint operation

EndBufferedPaint – Completes buffer pain operations

There are few things you should notice before using the buffered functions. Since the buffered operations are based on the bitmap blitting functions, the default background for the drawing will be black (RGB(0,0,0)). So you should draw the background before starting the actual drawing. Otherwise the background will be black by default. The next thing is that, it’s better to add the message handler for WM_ERASEBKGND and just return TRUE; instead of calling base class functions. This will avoid further flickering on resizing your window. The sample snippet below implemented buffered painting and a time has been added to call Invalidate() function in each 10ms to test the flickering. See the sample snippet below. Note that after initializing the buffered painting you should not use the original window DC for painting you should use the DC output from BeginBufferedPaint() function. The code will be running only in Windows Vista.

[sourcecode language='cpp']
void CFlickerSampleDlg::OnPaint()
{
BP_PAINTPARAMS paintParams = {0};
paintParams.cbSize = sizeof(paintParams);

CRect rect;
GetClientRect( rect );
CPaintDC dc(this);
HDC hdcBuffer;
HPAINTBUFFER hBufferedPaint = BeginBufferedPaint(dc, rect,
BPBF_COMPATIBLEBITMAP,
&paintParams, &hdcBuffer);
CDC* pDc = CDC::FromHandle( hdcBuffer ); // Use output DC for further painting. Dont use windows DC

if (hBufferedPaint)
{
// Draw your background. otherwise it will be black
FillRect( pDc->m_hDC, rect, GetSysColorBrush(COLOR_3DFACE));

// Application specific painting code
for (int i =0;i<10;i++)
{
pDc->TextOut( 0,i*20,_T(”Quick Brown Fox Jumps over lazy dog”));
}
EndBufferedPaint(hBufferedPaint, TRUE);
}
else
{
// Error occurred, default to unbuffered painting
}
}

void CFlickerSampleDlg::OnTimer(UINT_PTR nIDEvent)
{
Invalidate(); // Repaint the window for testing purpose
CDialog::OnTimer(nIDEvent);
}

void CFlickerSampleDlg::OnDestroy()
{
CDialog::OnDestroy();
BufferedPaintUnInit(); // Uninit
}

BOOL CFlickerSampleDlg::OnEraseBkgnd(CDC* pDC)
{
return 1;
}
[/sourcecode]

Categories: C++, Code, Misc, Tips, Visual Studio, Windows Vista Tags: , , ,

Describing Windows XP and Vista Shutdown in Application context

September 22nd, 2008 Sarath Comments

In this post, I’m talking about some internals of Windows Shutdown in the context of applications.

When the user or an application initiates shutdown request through ExitWindowsEx function, the Csrss.exe will be initiating the shutdown operation by sending a window message to the hidden window owned by Winlogon process. The subsystem process Csrss.exe contains handles, Console (text) windows, creation and deletion of processes and threads and other various supports like ExitWindowEx etc…

The Winlogon process calls ExitWindowsEx function with some internal flags to continue the shutdown based on the security access rights of the currently-logged in user. Since the ExitWindowEx call has been made again, it falls back in the hand of Csrss.exe.

Csrss sends the WM_QUERYENDSESSION message to each thread in the process that has a Windows message loop. This message is like warning from the system that, the application has to respond for the shutdown operation. The shutdown can be preceded when the thread returns TRUE. If the thread returns FALSE, in most cases, the shutdown operation will be cancelled. The shutdown should be cancelled only for the valid reasons like CD burning, live recording etc…

clip_image002Windows Vista supports more interactive shutdown(When the screen like left appears and I wondered when try to shutdown while the office applications are running. Now got the nuts and bolts of it :D ). One or many applications can cancel the shutdown operation under windows XP. In windows vista, if either of the application cancels shutdown operation, windows shows the list of currently running application and also the blocking application on the top of the window. If the user wants to shut his computer down, he can forcefully do that by clicking on the “Shut down now” button(red button in the figure). In this case windows sends WM_QUERYENDSESSION again with ENDSESSION_FORCEFULSHUTDOWN flag. If an application responds FALSE, Windows will continue shutdown instead of canceling it.

Windows Vista provides a facility to pro-actively describe about the reason for cancelling the shutdown. There are three new APIs at our disposal to manage shutdown cancellation string.

[sourcecode language='cpp']
BOOL ShutdownBlockReasonCreate(HWND hWnd, LPCWSTR pwszReason);
BOOL ShutdownBlockReasonDestroy(HWND hWnd);
BOOL ShutdownBlockReasonQuery(HWND hWnd, LPWSTR pwszBuff, DWORD *pcchBuff);
[/sourcecode]


The above functions are used to create, destroy and query the cancellation string for the window. The best time to create the string is at WM_QUERYENDSESSION function and destroys it once the application finished using it. (See the sample below for the usage)


Once the Query end session function returns true or managed to get out from the above described scenarios, Csrss then sends the WM_ENDSESSION Windows message to the thread to request it to exit. The application will get 5 second as time out as default (it’s defined in HKCU\Control Panel\Desktop\HungAppTimeout). If an application times out responding to WM_QUERYENDSESSION or WM_ENDSESSION, Windows will terminate it.

The behavior of the application time out is slightly different in Windows Vista and XP as we see in the picture below. Please check MSDN (I don’t want to copy paste it here) to get the detailed table.

If the thread doesn’t exit before the timeout, Csrss displays the hung-program dialog box (End Now). You can disable this dialog box by changing the registry value HKCU\Control Panel\Desktop\AutoEndTasks to 1. This dialog box indicates that a program isn’t shutting down in a timely manner and gives the user a choice of either killing the process or aborting the shutdown. There is no timeout on this dialog box, which means that a shutdown request could wait forever at this point.

Once all the threads that own windows in the process have exited, Csrss terminates the process and goes on to the next process in the interactive session.

OK Now you’re capable of handling the shutdown message for your application. Here’s a sample snippet for doing the same (MFC)

[sourcecode language='cpp']
/* Map the following functions manually in your application (Win32 style)
*/

BEGIN_MESSAGE_MAP(CShutDownTestDlg, CDialog)
ON_MESSAGE( WM_QUERYENDSESSION, QueryEndSession )
ON_MESSAGE( WM_ENDSESSION, EndSession )
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

LRESULT CShutDownTestDlg::QueryEndSession(WPARAM,LPARAM)
{
// Block shut down
ShutdownBlockReasonCreate(m_hWnd, L”TV Show being recorded” );
return FALSE;
// return TRUE; // continue shutdown
}

LRESULT CShutDownTestDlg::EndSession(WPARAM,LPARAM)
{
// Destroy the shutdown string used earlier
ShutdownBlockReasonDestroy(m_hWnd);
return TRUE;
}
[/sourcecode]

Here’s the pure MFC way to do the same

[sourcecode language='cpp']
/* Add the function using class wizard or through property window (VS2003 or above)
*/

BEGIN_MESSAGE_MAP(CShutDownTestDlg, CDialog)
ON_WM_QUERYENDSESSION()
ON_WM_ENDSESSION()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

BOOL CShutDownTestDlg::OnQueryEndSession()
{
// Block shut down
ShutdownBlockReasonCreate(m_hWnd, L”TV Show being recorded” );
return FALSE;

}

void CShutDownTestDlg::OnEndSession(BOOL bEnding)
{
// Destroy the shutdown string used earlier
ShutdownBlockReasonDestroy(m_hWnd);
CDialog::OnEndSession(bEnding);
}
[/sourcecode]

Hope you enjoyed this lengthy post. Thanks for MSDN articleand Mark Russinovich for his book Windows Internals. Those were the light for my path.

Sharing my thoughts...

Categories: C++, Code, Tips, Windows Vista Tags: , , , ,

Windows Vista Synchronization: Slim Read Writer Locks

August 24th, 2008 Sarath Comments

In the previous post we had discussed about condition variable and we demonstrated it using the commonly used Critical Section Synchronization objects. Now let’s check what Slim Reader Writer Lock is.

It’s again a user mode synchronization object which allows concurrent access to a shared resource for multiple threads and exclusive write access to the writer thread. Earlier if you had to implement suck kind of mechanism, we’ll have to write your own code or to get expert written code from some text books or to steal somewhere. This mechanism is broadly used where data is reads frequently with multiple thread and infrequent update of the shared resource.

It designed to be fast, small and for resource efficiency hence it wont support recursive acquisition of resources as it may create additional overhead.

Here are the functions used to implement Slim Reader and writer locks.

SRW API

Description

AcquireSRWLockExclusive 

Acquires an SRW lock in exclusive mode.

AcquireSRWLockShared 

Acquires an SRW lock in shared mode.

InitializeSRWLock 

Initialize an SRW lock.

ReleaseSRWLockExclusive 

Releases an SRW lock that was opened in exclusive mode.

ReleaseSRWLockShared 

Releases an SRW lock that was opened in shared mode.

SleepConditionVariableSRW 

Sleeps on the specified condition variable and releases the specified lock as an atomic operation.

 There are two modes to access the resource

  • Shared mode
    grants shared read-only access to multiple reader threads, which enables them to access data from the shared resource concurrently. If read operations exceed write operations, this concurrency increases performance and throughput compared to critical sections.
  • Exclusive mode grants read/write access to one writer thread at a time. When the lock has been acquired in exclusive mode, no other thread can access the shared resource until the writer releases the lock.

The locks should be initilized by using InitializeSRWLock function with SRWLOCK structure.

VOID WINAPI InitializeSRWLock(PSRWLOCK SRWLock);

AcquireSRWLockExclusive and ReleaseSRWLockExclusive apis can be used to acquire and release exclusive access to resource respectively. On the other hand, AcquireSRWLockShared and ReleaseSRWLockShared functions can be used to acquire and release shared access to the resource.

We’ve discussed about condition variables before. SRW locks can be used with condition variables apis to implement user mode wait operations for the threads running in a single process. SleepConditionVariableSRW api can be used to wait for a condition variables with SRW lock. SRW lock will be released when it’s being used with SleepConditionVariableSRW lock function.

[sourcecode language='cpp']
BOOL WINAPI SleepConditionVariableSRW(
PCONDITION_VARIABLE ConditionVariable,
PSRWLOCK SRWLock,
DWORD dwMilliseconds,
ULONG Flags
);
[/sourcecode]

The parameter is Flag to this API is important because there we can specify the mode of locking the resource as shared or exclusive access upon the successful execution of the API. If the flag parameter is CONDITION_VARIABLE_LOCKMODE_SHARED on returning the function the SRW lock will be granted with shared access and otherwise an exclusive access.

Let’s take a simple example which is available with Jeffry Richter’s “Windows Via C++” published in his website. I’ve made it short for the sake of expressing it here.

[sourcecode language='cpp']
BOOL ConsumeElement(int nThreadNum, int nRequestNum, HWND hWndLB)
{
// Get access to the queue to consume a new element
AcquireSRWLockShared(&g_srwLock);
// Fall asleep until there is something to read.
while (…) {
// There was not a readable element
SleepConditionVariableSRW(&g_cvReadyToConsume, &g_srwLock,
INFINITE, CONDITION_VARIABLE_LOCKMODE_SHARED);
}

// Get the first new element
CQueue::ELEMENT e;
// Note: No need to test the return value since IsEmpty
// returned FALSE
g_q.GetNewElement(nThreadNum, e);
// No need to keep the lock any longer
ReleaseSRWLockShared(&g_srwLock);
// A free slot is now available for writer threads to produce
// –> wake up a writer thread
WakeConditionVariable(&g_cvReadyToProduce);
return(TRUE);
}

DWORD WINAPI ReaderThread(PVOID pvParam)
{
for (…)
{
if (!ConsumeElement(nThreadNum, nRequestNum, hWndLB))
return(0);
Sleep(2500); // Wait before reading another element
}
return(0);
}

DWORD WINAPI WriterThread(PVOID pvParam) {

int nThreadNum = PtrToUlong(pvParam);
for (…)
{
CQueue::ELEMENT e = { nThreadNum, nRequestNum };

// Require access for writing
AcquireSRWLockExclusive(&g_srwLock);

// If the queue is full, fall asleep as long as the condition variable
// is not signaled
if (…) {
// No more room in the queue Need to wait for a reader to empty a slot before acquiring the lock again
SleepConditionVariableSRW(&g_cvReadyToProduce, &g_srwLock,
INFINITE, 0);
}

// Add the new ELEMENT into the queue
g_q.AddElement(e);
// No need to keep the lock any longer
ReleaseSRWLockExclusive(&g_srwLock);
// Signal reader threads that there is an element to consume
WakeAllConditionVariable(&g_cvReadyToConsume);
// Wait before adding a new element
Sleep(1500);
}

return(0);
}
[/sourcecode]

I removed lot of lines from the original code written by Jeff. You can download the entire source code from his website. One comment about his code is, it’s remarkably professional.

And finally a SRW lock doesn’t have APIs to destroy the SRW lock handle.

You might be interested to see the some performance figure presented in MSDN magazine on SRW locks.

Sharing my thoughts...

Categories: C++, Code, Windows Vista Tags:

Windows Vista Synchronization: Condition Variables

August 20th, 2008 Sarath Comments

There are few new synchronization primitives has been introduced with Windows Vista like Condition Variables, Slim Reader/Writer Lock, One Time Initialization, Double Checked locking etc…
Let’s take a look to Condition variables

Condition variable is a user mode synchronization primitive to wait the thread(s) until a particular condition occurs. The conditional variable can be used with either Critical Section Objects and SRW Objects. We can either wake one or all threads waiting for condition variables according to our requirements. This type of synchronization mechanism can’t be shared among the multiple process as it’s user mode synchronization object. The following are the APIs used with Condition Variables.

InitializeConditionVariable Initializes a condition variable.
SleepConditionVariableCS Sleeps on the specified condition variable and releases the specified critical section as an atomic operation.
SleepConditionVariableSRW Sleeps on the specified condition variable and releases the specified SRW lock as an atomic operation.
WakeAllConditionVariable Wakes all threads waiting on the specified condition variable.
WakeConditionVariable Wakes a single thread waiting on the specified condition variable.

OK Let’s take a simple sample provided from MSDN. We will be having a producer who should always write some data to a shared queue and we’re having a client reading data from the same queue.
[sourcecode language='cpp']
// Producer
for (unsigned int i = 0;i < g_uiIterations;i++)
{
EnterCriticalSection(&g_csLock); // Produce work
g_listWork.push_back(i);
LeaveCriticalSection(&g_csLock);
WakeConditionVariable(&g_condNotEmpty);
Sleep(g_uiProducerDelay);
}

//Consumer
while (true)
{
EnterCriticalSection(&g_csLock);
while (g_listWork.empty())
{
SleepConditionVariableCS(&g_condNotEmpty,&g_csLock,INFINITE);
}
i = g_listWork.front();
g_listWork.pop_front();
LeaveCriticalSection(&g_csLock);
Sleep(g_uiConsumerDelay); // Simulating work
}
[/sourcecode]
The above example is quite straight forward. It shows how we can sleep and wait using condition variables. The producer acquire the critical section for writing data in to queue. At this time the consumer thread will be waiting for the condition variables. When the producer calls "WakeConditionVariable", the consumer thread will be release and sooner it will acquire the lock for critical section in the SleepConditionVariableCS call itself. After completing the usage of resource as usual we've to call LeaveCritical Section.
The synchronization object used here is Critical Section. Of course as part of initialization, The critical section object should be initialized using InitializeCriticalSection API and the Condition variable (CONDITION_VARIABLE) with InitializeConditionVariable API. If you notice, there are no API to clean up or destroy the CONDITION_VARIABLE structure as it’s not needed by the underlying implementation.
The above examples can be implemented in conventional style using event and critical section. The drawback of the method is, the event which we’re waiting will be a kernel object and it makes a costly kernel mode roundtrip for execution. While the condition variables are user mode synchronization objects.
You can see a sophisticated example in MSDN.

Technorati Tags: ,

Sharing my thoughts...

Categories: C++, Code, Windows Vista Tags: