QueueLock to lock data with pending lock requesting threads in queue with local spinning to reduce memory contention and traffic
diff --git a/ConcQueue.h b/ConcQueue.h
index 6ac15f5..9e0fcfe 100644
--- a/ConcQueue.h
+++ b/ConcQueue.h
@@ -115,9 +115,9 @@
QueueElement<data_val_type>* GetElement()
{
- QueueElement<data_val_type>* current_element = NULL;
+ const QueueElement<data_val_type> *current_element = head;
+ QueueElement<data_val_type> *temp = NULL;
- current_element = head;
while(!(CAS(&(deletion_lock.lock_value), 0, 1)))
{
//Spin waiting for the lock
@@ -129,8 +129,14 @@
}
CAS(&(deletion_lock.lock_value) ,1, 0);
+ /* When popping an element from the queue and returning it,the
+ * ownership of the element is changed from the queue to the
+ * calling function. Hence, the element is no longer required
+ * to be const.
+ */
+ temp = const_cast<QueueElement<data_val_type>*> (current_element);
- return (current_element);
+ return (temp);
}
~ConcQueue()
diff --git a/QueueLock.h b/QueueLock.h
new file mode 100644
index 0000000..2a23863
--- /dev/null
+++ b/QueueLock.h
@@ -0,0 +1,48 @@
+#include "ConcQueue.h"
+
+class QueueLock
+{
+ ConcQueue<int> lock_queue;
+ int lock_taken;
+public:
+ QueueLock():lock_taken(0)
+ {
+ }
+
+ int GetLock()
+ {
+
+ if(lock_taken != 0)
+ {
+ const QueueElement<int> *p_add = lock_queue.AddElement(0);
+ const int *p_spin = p_add->GetPointerToData();
+
+ while(*(p_spin) != 1)
+ {
+ //Spinning waiting for lock
+ }
+
+ }
+
+ lock_taken = 1;
+
+ return 1;
+ }
+
+ void ReleaseLock()
+ {
+ QueueElement<int> *p_release = lock_queue.GetElement();
+
+ if(p_release == NULL)
+ {
+ lock_taken = 0;
+ }
+ else
+ {
+ p_release->SetData(1);
+ }
+
+ }
+};
+
+