OS: Windows 7
When calling the WinAPI Sleep() function as Sleep(1) the thread actually sleeps for 15ms. I did it 100 times in a loop and the total sleep time was 150
(debug or release build ?)
How are you measuring the delay ? are you using a precise method ? (queryperformancecounter)
I don't think you should rely on the Windows OS for accurate timing; it is not a real-time operating system, and there will be external "forces" that will steal time from your process.
Is this common behavior
It is.
Window's thread scheduler works on a time quantum (exact length depends of various factors including Windows version and edition). Effectively any non-zero delay is rounded up to a complete quantum.
Sleep
can cause the thread to sleep for longer than the timeout specified, it only guarantees that the thread will sleep for at least that length of time.
From the documentation:
After the sleep interval has passed, the thread is ready to run. If you specify 0 milliseconds, the thread will relinquish the remainder of its time slice but remain ready. Note that a ready thread is not guaranteed to run immediately. Consequently, the thread may not run until some time after the sleep interval elapses. For more information, see Scheduling Priorities.
This is pretty normal behavior, as most clock resolutions are around 10-15 ms. Therefore, if you call it with a value less than the clock resolution (in your case, 1), it will likely have to wait at least for one clock cycle, which is why it sleeps longer than you want to.
Generally, you should not use Sleep for things requiring such precision due to these issues.
The best articles I have found regarding timing on Windows are here and here. The useful part is that once you change the multimedia timer resolution (e.g. timeBeginPeriod(1) for 1ms) it also affects the Sleep command, because it affects the scheduler in general. This said, achieving 1ms accuracy is not feasible on a non-realtime OS.
The behavior is OK. Underlying hardware, version of OS, and even running software are influencing the habit of the OS with respect to the sleep() function.
If a sleep is called with dwMilliseconds smaller than the systems interrupt period, the call will return at the next interrupt. This way the actual delay depends on the time at which the sleep was called (with respect to the interrupt period).
It is advisable to use the multimedia timer interface to increase the interrupt frequency to the maximum supported by the hardware, when a sleep(1) is desired.
A detailed overview about the sleep() function, waitable timer functions, timer resolutions, and multimedia timer settings can be found at the Windows Timestamp Project