Various tweaks to semaphore (and makefile) #3
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This is a bit of a mixed bag of a commit, so I totally understand if you don't want to merge it as-is. I figured I'd let you choose what you like, if anything, instead of just forking silently.
First, thank you for writing the cross-platform + lightweight semaphore! I had had in mind to do something remarkably similar for absolute ages, but just never had the time to get around to it. Now I don't have to :-) Your blog post, too, was high-quality as usual. I've taken the lightweight semaphore and used it to implement a blocking wrapper around both of my lock-free queues (spsc and mpmc).
The changes I made are:
#include
of windows.h with manually-declared prototypes for the specific Win32 semaphore functions called. This is definitely a controversial change, as Microsoft tends to frown on this sort of thing, but I absolutely hate including windows.h in a header. Matter of preference, I suppose.int
type, but there's no reason the lightweight semaphore can't go beyond that and use the signed equivalent ofsize_t
-- after all, the only values passed on to the platform-specific semaphores are the negative counts corresponding to the number of waiting threads, and those should fit in anint
, even if the maximum count can go beyond that limit. So I changed this, introducing assize_t
type.availableApprox()
method to the lightweight semaphore that returns the available count. This is useful for debugging, unit tests, probabilistic algorithms, etc.tryWaitMany()
andwaitMany()
methods that "acquire" many items at once, instead of just one; this is required in order to implement e.g. a blocking bulk dequeue like the one I have in my MPMC queue. They could potentially be useful to others looking to do bulk operations with a semaphore.tryWait()
method to use a CAS-loop instead of just a single CAS, since under contention the CAS will often fail even if the count is way above 0. (Obviously, thewait()
method doesn't strictly need this since it proceeds to spin-wait after anyway, but it matters for those who call thetryWait()
method directly without a follow-up call towait()
.)Your unit tests still pass. I can't tell if there's any effect on performance since the tests seem to take a wildly different amount of time to execute each time on my PC (which admittedly is a rather wimpy AMD C-50 dual-core netbook processor -- I had to lower the iteration count temporarily on some of them otherwise it would have taken over half an hour to get the test results, heh).
Thank you for your hard work!