OverviewFilesCommitsIssuesDocsReleasesPeers

opencog-cogutil commits / 2ffbf08

Rework barrier to take a factory function.
2ffbf08490066a60d11739d7c60101af4301e9bd
by Linas Vepstas <linasvepstas@gmail.com> · 2025-12-07T17:06:35.000Z

Changed files (2) +25 -14

opencog/util/async_buffer.h +13 -7
……@@ -162,7 +162,8 @@ class async_buffer
162162 void insert(const Element&);
163163 void flush();
164164 void barrier(void);
165 void barrier(const Element&);
165 template<typename Factory>
166 void barrier(Factory&& make_element);
166167
167168 void set_watermarks(size_t, size_t);
168169 void stall(bool);
……@@ -435,18 +436,23 @@ void async_buffer<Writer, Element>::barrier()
435436 drain();
436437}
437438
438/// Barrier that ensures every worker processes the given element.
439/// Barrier that ensures every worker processes a provided element.
439440/// This first drains existing work queues, then gives each worker
440/// a copy of `elt` for processing. It then waits for all workers
441/// to complete. This guarantees that every worker has run at least
442/// once.
441/// an element provided by the factory. It then waits for all
442/// workers to complete. This guarantees that every worker has run
443/// at least once.
444///
445/// The factory callable is invoked once per worker thread to create
446/// a unique element. Since the async_buffer is deduplicating for
447/// work elements, each element must be distinct.
443448///
444449/// The intended use case for this function are systems that have
445450/// workers that do caching or lazy initialization or implement
446451/// other actions that require synchronization that the default
447452/// `barrier(void)` would miss.
448453template<typename Writer, typename Element>
449void async_buffer<Writer, Element>::barrier(const Element& elt)
454template<typename Factory>
455void async_buffer<Writer, Element>::barrier(Factory&& make_element)
450456{
451457 std::unique_lock<std::mutex> lock(_enqueue_mutex);
452458
……@@ -460,7 +466,7 @@ void async_buffer<Writer, Element>::barrier(const Element& elt)
460466
461467 // Enqueue one element for each thread.
462468 for (unsigned int i = 0; i < _thread_count; i++)
463 do_insert(elt);
469 do_insert(make_element());
464470
465471 // Wait for all threads to complete their barrier work
466472 completion.wait();
opencog/util/async_method_caller.h +12 -7
……@@ -135,7 +135,8 @@ class async_caller
135135 void enqueue(Element&&);
136136 void flush_queue();
137137 void barrier(void);
138 void barrier(const Element&);
138 template<typename Factory>
139 void barrier(Factory&& make_element);
139140
140141 void set_watermarks(size_t, size_t);
141142
……@@ -349,18 +350,22 @@ void async_caller<Writer, Element>::barrier()
349350 drain();
350351}
351352
352/// Barrier that ensures every worker processes the given element.
353/// Barrier that ensures every worker processes an element.
353354/// This first drains existing work queues, then gives each worker
354/// a copy of `elt` for processing. It then waits for all workers
355/// to complete. This guarantees that every worker has run at least
356/// once.
355/// an element provided by the factory. It then waits for all
356/// workers to complete. This guarantees that every worker has run
357/// at least once.
358///
359/// The factory callable is invoked once per worker thread to create
360/// an element.
357361///
358362/// The intended use case for this function are systems that have
359363/// workers that do caching or lazy initialization or implement
360364/// other actions that require synchronization that the default
361365/// `barrier(void)` would miss.
362366template<typename Writer, typename Element>
363void async_caller<Writer, Element>::barrier(const Element& elt)
367template<typename Factory>
368void async_caller<Writer, Element>::barrier(Factory&& make_element)
364369{
365370 std::unique_lock<std::mutex> lock(_enqueue_mutex);
366371
……@@ -376,7 +381,7 @@ void async_caller<Writer, Element>::barrier(const Element& elt)
376381 for (unsigned int i = 0; i < _thread_count; i++)
377382 {
378383 _pending ++;
379 _store_queue.push(elt);
384 _store_queue.push(make_element());
380385 _item_count++;
381386 }
382387