9
9
#include < memory>
10
10
#include < mutex>
11
11
12
+ /* *
13
+ * @class SVSMultiThreadJob
14
+ * @brief Represents a multi-threaded asynchronous job for the SVS algorithm.
15
+ *
16
+ * This class is responsible for managing multi-threaded jobs, including thread reservation,
17
+ * synchronization, and execution of tasks. It uses a control block to coordinate threads
18
+ * and ensure proper execution of the job.
19
+ *
20
+ * @details
21
+ * The SVSMultiThreadJob class supports creating multiple threads for a task and ensures
22
+ * synchronization between them. It uses a nested ControlBlock class to manage thread
23
+ * reservations and job completion. Additionally, it includes a nested ReserveThreadJob
24
+ * class to handle individual thread reservations.
25
+ *
26
+ * The main job executes a user-defined task with the number of reserved threads, while
27
+ * additional threads wait for the main job to complete.
28
+ *
29
+ * @note This class is designed to work with the AsyncJob framework.
30
+ */
12
31
class SVSMultiThreadJob : public AsyncJob {
13
32
14
33
// Thread reservation control block shared between all threads
@@ -32,16 +51,11 @@ class SVSMultiThreadJob : public AsyncJob {
32
51
// reserve a thread and wait for the job to be done
33
52
void reserveThreadAndWait () {
34
53
// count current thread
35
- {
36
- std::lock_guard lock{mutex};
37
- ++reservedThreads;
38
- }
39
- cv.notify_one ();
40
- // wait for the job to be done
41
- {
42
- std::unique_lock lock{mutex};
43
- cv.wait (lock, [&] { return jobDone; });
44
- }
54
+ std::unique_lock lock{mutex};
55
+ ++reservedThreads;
56
+ cv.notify_all ();
57
+ // Wait until the job is marked as done, handling potential spurious wakeups.
58
+ cv.wait (lock, [&] { return jobDone; });
45
59
}
46
60
47
61
// wait for threads to be reserved
@@ -528,7 +542,7 @@ class TieredSVSIndex : public VecSimTieredIndex<DataType, float> {
528
542
// Use the frontend parameters to manually prepare the blob for its transfer to the SVS
529
543
// index.
530
544
auto storage_blob = this ->frontendIndex ->preprocessForStorage (blob);
531
- std::unique_lock<std::shared_mutex> svs_lock ( this ->mainIndexGuard );
545
+ std::scoped_lock lock ( this -> updateJobMutex , this ->mainIndexGuard );
532
546
return svs_index->addVectors (storage_blob.get (), &label, 1 );
533
547
}
534
548
bool index_update_needed = false ;
@@ -557,7 +571,7 @@ class TieredSVSIndex : public VecSimTieredIndex<DataType, float> {
557
571
return !this ->frontendIndex ->isLabelExists (label);
558
572
}());
559
573
560
- std::unique_lock<std::shared_mutex> svs_lock ( this ->mainIndexGuard );
574
+ std::scoped_lock lock ( this -> updateJobMutex , this ->mainIndexGuard );
561
575
return svs_index->deleteVectors (&label, 1 );
562
576
}
563
577
0 commit comments