2323
2424#pragma once
2525
26+ #include < mutex>
2627#include " cell.h"
2728#include " point.h"
2829#include " shared.h"
@@ -77,6 +78,7 @@ struct grid {
7778 treeT* tree=NULL ;
7879 intT totalPoints;
7980 cellBuf **nbrCache;
81+ std::mutex* cacheLocks;
8082
8183 /* *
8284 * Grid constructor.
@@ -89,10 +91,12 @@ struct grid {
8991
9092 cells = newA (cellT, cellCapacity);
9193 nbrCache = newA (cellBuf*, cellCapacity);
94+ cacheLocks = (std::mutex*) malloc (cellCapacity * sizeof (std::mutex));
9295 parallel_for (0 , cellCapacity, [&](intT i) {
93- nbrCache[i] = NULL ;
94- cells[i].init ();
95- });
96+ new (&cacheLocks[i]) std::mutex ();
97+ nbrCache[i] = NULL ;
98+ cells[i].init ();
99+ });
96100 numCells = 0 ;
97101
98102 myHash = new cellHashT (pMinn, r);
@@ -101,9 +105,10 @@ struct grid {
101105
102106 ~grid () {
103107 free (cells);
104- parallel_for (0 , numCells, [&](intT i) {
105- if (nbrCache[i]) delete nbrCache[i];
106- });
108+ free (cacheLocks);
109+ parallel_for (0 , cellCapacity, [&](intT i) {
110+ if (nbrCache[i]) delete nbrCache[i];
111+ });
107112 free (nbrCache);
108113 if (myHash) delete myHash;
109114 if (table) {
@@ -141,14 +146,24 @@ struct grid {
141146 }
142147 }
143148 return false ;};// todo, optimize
144- if (nbrCache[bait-cells]) {
145- auto accum = nbrCache[bait-cells];
149+ int idx = bait - cells;
150+ if (nbrCache[idx]) {
151+ auto accum = nbrCache[idx];
146152 for (auto accum_i : *accum) {
147153 if (fWrap (accum_i)) break ;
148154 }
149155 } else {
150- floatT hop = sqrt (dim + 3 ) * 1.0000001 ;
151- nbrCache[bait-cells] = tree->rangeNeighbor (bait, r * hop, fStop , fWrap , true , nbrCache[bait-cells]);
156+ // wait for other threads to do their thing then try again
157+ std::lock_guard<std::mutex> lock (cacheLocks[idx]);
158+ if (nbrCache[idx]) {
159+ auto accum = nbrCache[idx];
160+ for (auto accum_i : *accum) {
161+ if (fWrap (accum_i)) break ;
162+ }
163+ } else {
164+ floatT hop = sqrt (dim + 3 ) * 1.0000001 ;
165+ nbrCache[idx] = tree->rangeNeighbor (bait, r * hop, fStop , fWrap , true , nbrCache[idx]);
166+ }
152167 }
153168 }
154169
@@ -160,14 +175,24 @@ struct grid {
160175 return f (cell);
161176 return false ;
162177 };
163- if (nbrCache[bait-cells]) {
164- auto accum = nbrCache[bait-cells];
178+ int idx = bait - cells;
179+ if (nbrCache[idx]) {
180+ auto accum = nbrCache[idx];
165181 for (auto accum_i : *accum) {
166- if (fWrap (accum_i)) break ;
182+ if (fWrap (accum_i)) break ;
167183 }
168184 } else {
169- floatT hop = sqrt (dim + 3 ) * 1.0000001 ;
170- nbrCache[bait-cells] = tree->rangeNeighbor (bait, r * hop, fStop , fWrap , true , nbrCache[bait-cells]);
185+ // wait for other threads to do their thing then try again
186+ std::lock_guard<std::mutex> lock (cacheLocks[idx]);
187+ if (nbrCache[idx]) {
188+ auto accum = nbrCache[idx];
189+ for (auto accum_i : *accum) {
190+ if (fWrap (accum_i)) break ;
191+ }
192+ } else {
193+ floatT hop = sqrt (dim + 3 ) * 1.0000001 ;
194+ nbrCache[bait-cells] = tree->rangeNeighbor (bait, r * hop, fStop , fWrap , true , nbrCache[idx]);
195+ }
171196 }
172197 }
173198
0 commit comments