“” Is Not The Same As NULL

I have been very busy recently. Aside from Starcraft II, I picked up another side programming project. I am reworking an old MFC app and see how far I can bring it into modern age with MFC9.0.

MFC is horrible in practice because it forces you to deal all the details, such as resizing and redrawing. But it suits my purpose because it forces me to learn all the details.

As I was testing the application across Window XP and Window 7, I noticed a strange error. The Create() function of CAsyncSocket returns an error 10022 on Window 7, and not Window XP.

// pueudocode

// Create a server socket, CMyAsyncSocket is derived from CAsyncSocket.
m_serverSocket = new CMyAsyncSocket();
BOOL hasError = m_serverSocket->Create(
   m_listenPort, // some port number to bind to
if(TRUE == hasError)
   int error = GetLastError();
   ... // report and print error
... // more code here

Error 10022 is WSAEINVAL, where it indicates that an invalid argument was supplied.

Instead of reading the error code, my cognitive bias convinced me that the above code is flawless since it worked in XP. I jumped through the hoops to change firewall settings, network card settings, and tried to blame everything but the source.

Eventually I went back and inspect the API again, and realized that the third and fourth arguments are already defaulted to the appropriate values.

// CAsyncSocket signature
BOOL Create(
   UINT nSocketPort = 0,
   int nSocketType = SOCK_STREAM,
   LPCTSTR lpszSocketAddress = NULL

So I cleaned up the function call to Create().


   m_listenPort, // some port number to bind to


Apparently the application was setting lpszSocketAddress to “” instead of NULL, it is an invalid argument (as indicated by the MFC for ~5000 times before it penetrated my thick head).

With the appropriate argument, everything works.

Do Suspended or Blocked Threads Consume CPU Time?

The short answer is no. Suspended or blocked thread do not consume any CPU time.

Of course, I didn’t know that. This is just a journal on how I wasted a perfectly nice afternoon.


I searched the internet, and found a MSDN article on scheduling priorities.

The system assigns time slices in a round-robin fashion to all threads with the highest priority. If none of these threads are ready to run, the system assigns time slices in a round-robin fashion to all threads with the next highest priority. If a higher-priority thread becomes available to run, the system ceases to execute the lower-priority thread (without allowing it to finish using its time slice), and assigns a full time slice to the higher-priority thread.

To me, the above paragraph sounded like all threads, regardless of state, are assigned to some time slices based on priority. So I wrote some test code to gain some insight.

Below is a test program that runs four threads to calculate Pi (on my quad-core CPU), and 1000 real-time priority sleeper thread that runs Sleep(). If suspended threads use any CPU cycles, it will definitely slow down the Pi calculation.

#include <Windows.h>
#include <iostream>
#include <boost/thread.hpp>
#include <boost/cstdint.hpp>

using boost::bind;
using boost::thread;
using boost::mutex;
using boost::condition_variable;

void calculatePi()
	double retPi = 0;
	for (boost::uint64_t denom = 1; denom <= 30000000000; denom += 2)
		if ((denom - 1) % 4)
			retPi -= (4.0 / denom);
			retPi += (4.0 / denom);

void sleepForever()

int main()
	std::vector<thread> tv;
	std::vector<thread> stv;

	// 1000 real time priority thread that sleeps
	for(int i=0; i<1000; ++i)
		thread s(bind(&sleepForever));
		SetPriorityClass(s.native_handle(), REALTIME_PRIORITY_CLASS);

	// four normal priority thread that calculates pi
	for(int i=0; i<4; ++i)
		thread w(bind(&calculatePi));

	for(size_t i=0; i<tv.size(); ++i)
	return 0;

The Result

There is absolutely no difference in performance when the test program runs 10, 100, or 1000 sleeper threads.

Using the concurrency profiler in VC10, it shows that threads in suspended state are never context-switched or woken up during its lifetime.

Last four threads calculates Pi, the the other threads are sleeping. Sleeping thread did not execute, and therefore did not consume any CPU cycles.

Then I ran into another MSDN documentation on context switches.

Until threads that are suspended or blocked become ready to run, the scheduler does not allocate any processor time to them, regardless of their priority.

Yup. I have verified that the documentation is accurate. 😥