diff --git a/cpp/particles/lock_free_bool_array.hpp b/cpp/particles/lock_free_bool_array.hpp
index 4e5ad31b6274ee82b1dd99b0a8b87eba97fb64b7..ae5eb0d4f97420f08954595cb1c7ecd8fa78b080 100644
--- a/cpp/particles/lock_free_bool_array.hpp
+++ b/cpp/particles/lock_free_bool_array.hpp
@@ -27,31 +27,61 @@
 #define LOCK_FREE_BOOL_ARRAY_HPP
 
 #include <vector>
-#include <memory>
+#include <atomic>
+#include <unistd.h>
+#include <cstdio>
+#include <omp.h>
+
 
 class lock_free_bool_array{
-    std::vector<std::unique_ptr<long int>> keys;
+    static const int Available = 0;
+    static const int Busy = 1;
+    static const int NoOwner = -1;
+
+    struct Locker {
+        Locker() : lock(Available), ownerId(NoOwner), counter(0) {}
+        std::atomic_int lock;
+        std::atomic_int ownerId;
+        int counter;
+    };
+
+    std::vector<std::unique_ptr<Locker>> keys;
+
 
 public:
-    explicit lock_free_bool_array(const long int inNbKeys = 512){
+    explicit lock_free_bool_array(const long int inNbKeys = 1024){
         keys.resize(inNbKeys);
-        for(std::unique_ptr<long int>& k : keys){
-            k.reset(new long int(0));
+        for(auto& k : keys){
+            k.reset(new Locker());
         }
     }
 
     void lock(const long int inKey){
-        volatile long int* k = keys[inKey%keys.size()].get();
-        long int res = 1;
-        while(res == 1){
-            res = __sync_val_compare_and_swap(k, 0, res);
+        Locker* k = keys[inKey%keys.size()].get();
+        if(k->ownerId.load() != omp_get_thread_num()){
+            int expected = Available;
+            while(!std::atomic_compare_exchange_strong(&k->lock, &expected, Busy)){
+                usleep(1);
+            }
+            k->ownerId.store(omp_get_thread_num());
+            k->counter = 0; // must remain
         }
+        k->counter += 1;
+        assert(k->lock.load() == Busy);
+        assert(k->counter >= 1);
+        assert(k->ownerId.load() == omp_get_thread_num());
     }
 
     void unlock(const long int inKey){
-        volatile long int* k = keys[inKey%keys.size()].get();
-        assert(k && *k);
-        (*k) = 0;
+        Locker* k = keys[inKey%keys.size()].get();
+        assert(k->lock.load() == Busy);
+        assert(k->counter >= 1);
+        assert(k->ownerId.load() == omp_get_thread_num());
+        k->counter -= 1;
+        if(k->counter == 0){
+            k->ownerId.store(NoOwner);
+            k->lock.store(Available);
+        }
     }
 };