This routine raises the IRQL level to DISPATCH_LEVEL when acquiring the spin lock. For a description of when to use spin locks, see KeAcquireSpinLock. Like ordinary spin locks, queued spin locks must only be used in very special circumstances. The caller releases the spin lock by calling the KeReleaseInStackQueuedSpinLock routine. For more information, see Queued Spin Locks. KeAcquireInStackQueuedSpinLock acquires a spin lock as a queued spin lock. A driver should not use the same KLOCK_QUEUE_HANDLE from multiple calling sites. Drivers should normally allocate the structure on the stack each time they acquire the lock. The caller passes this value to KeReleaseInStackQueuedSpinLock when releasing the lock. A pointer to a caller-supplied KLOCK_QUEUE_HANDLE variable that the routine can use to return the spin lock queue handle. This parameter must have been initialized with KeInitializeSpinLock. Syntax void KeAcquireInStackQueuedSpinLock( Nor stress or verify this module in any way.The KeAcquireInStackQueuedSpinLock routine acquires a queued spin lock. The usage example is not self-evaluating and is geared toward Other than that we see very few explicit checks. Review yet, in the sense that it does not This codebase does not appear to be ready for Orthogonal to some technical details raised. Of keeping the Reader in mind when authoring code, OTOH whether the machine can read your intent is justĪ Green / Red indicator displayed when tests run. That is a challenging task, hard to anticipate the outcome. When you write, do it so people will successfully read. Programs must be written for people to read,Īnd only incidentally for machines to execute. It's worth understanding that particular failure to communicate, so as to generalize and to avoid it in future works. In at least one instance it didn't work, for reasons described below. The OP successfully communicated certain details to the machine, and tried to communicate technical ideas to an audience of collaborators. We learn from both positive and negative examples. But why are you even reading this (or any) review? To get better at communicating. I'm not complaining about what seem well-deserved downvotes. Nor are -1's likely to motivate deletion of the answer, as I have already considered that a few times and feel it would be a disservice to the community. Sliepen was kind enough to show how my technical analysis was inaccurate - my answer is incorrectly stating that there is a locking problem in push(), which I could correct, at the cost of papering over the communication failure. Additional -1's won't cause me to better understand the technical details, since G. When supplied unit tests do not exercise a line of code, that will not instill confidence in the Reader that the line runs correctly.ĭear downvoter: Let me explain myself. To the extent that code resembles a page of a text book or a file on GitHub, it is useful to cite your references. Tl dr: Writing down invariants helps the Gentle Reader better understand the technical ideas which code is trying to communicate. Since you cannot rely on the return value of these functions, it is better to remove them entirely. That means that by the time the caller looks at the return value, that value might no longer be representative of the state of the queue anymore another thread might have come and added or removed items. While you take the lock inside those functions, the lock is released right before these functions return. While most standard containers provide empty() and size() member functions, there is a problem with those functions in a thread-safe queue. You could do that in the constructor of ThreadPool by calling jobs.shutdown() inside the catch-block. You then need to ensure the queue is shut down properly. One issue to worry about is what to do when creating worker threads fails. That also means there is no need for ThreadPool::wait(). LockFreeQueue() : max_size(std::numeric_limits::max()), active_producers(1). Std::atomic_uint active_producers // to throw poison pill when needed Std::condition_variable space_available // keep control of queue size Std::condition_variable element_available As far as I know, everything is working well, but I feel like there is much to improve, as I'm a beginner in this field, and probably I can miss something pretty easily. I'm looking for your review to ensure it's bug-free and well-constructed. I've tried implementing the above structures and wonder about their safety and performance. In a project I'm currently working on, I need the implementation of ThreadPool along with a thread-safe queue. Topic: C++ Implementation of Lock-Free Queue and ThreadPool classes
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |