sync: fix a helgrind false positive, for a data race, on PoolProcessor (#24023)

This commit is contained in:
Felipe Pena 2025-03-24 17:04:10 -03:00 committed by GitHub
parent 42538e19ae
commit 1b52538dff
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 19 additions and 6 deletions

View File

@ -13,7 +13,7 @@ pub struct PoolProcessor {
mut: mut:
njobs int njobs int
items []voidptr items []voidptr
results []voidptr results shared []voidptr
ntask u32 // reading/writing to this should be atomic ntask u32 // reading/writing to this should be atomic
waitgroup sync.WaitGroup waitgroup sync.WaitGroup
shared_context voidptr shared_context voidptr
@ -88,7 +88,9 @@ pub fn (mut pool PoolProcessor) work_on_pointers(items []voidptr) {
} }
unsafe { unsafe {
pool.thread_contexts = []voidptr{len: items.len} pool.thread_contexts = []voidptr{len: items.len}
lock pool.results {
pool.results = []voidptr{len: items.len} pool.results = []voidptr{len: items.len}
}
pool.items = []voidptr{cap: items.len} pool.items = []voidptr{cap: items.len}
pool.items << items pool.items << items
pool.waitgroup.add(njobs) pool.waitgroup.add(njobs)
@ -115,8 +117,10 @@ fn process_in_thread(mut pool PoolProcessor, task_id int) {
if idx >= ilen { if idx >= ilen {
break break
} }
lock pool.results {
pool.results[idx] = cb(mut pool, idx, task_id) pool.results[idx] = cb(mut pool, idx, task_id)
} }
}
pool.waitgroup.done() pool.waitgroup.done()
} }
@ -129,15 +133,19 @@ pub fn (pool &PoolProcessor) get_item[T](idx int) T {
// get_result - called by the main thread to get a specific result. // get_result - called by the main thread to get a specific result.
// Retrieves a type safe instance of the produced result. // Retrieves a type safe instance of the produced result.
pub fn (pool &PoolProcessor) get_result[T](idx int) T { pub fn (pool &PoolProcessor) get_result[T](idx int) T {
rlock pool.results {
return unsafe { *(&T(pool.results[idx])) } return unsafe { *(&T(pool.results[idx])) }
}
} }
// get_results - get a list of type safe results in the main thread. // get_results - get a list of type safe results in the main thread.
pub fn (pool &PoolProcessor) get_results[T]() []T { pub fn (pool &PoolProcessor) get_results[T]() []T {
mut res := []T{cap: pool.results.len} mut res := []T{cap: pool.results.len}
for i in 0 .. pool.results.len { for i in 0 .. pool.results.len {
rlock pool.results {
res << unsafe { *(&T(pool.results[i])) } res << unsafe { *(&T(pool.results[i])) }
} }
}
return res return res
} }
@ -145,8 +153,10 @@ pub fn (pool &PoolProcessor) get_results[T]() []T {
pub fn (pool &PoolProcessor) get_results_ref[T]() []&T { pub fn (pool &PoolProcessor) get_results_ref[T]() []&T {
mut res := []&T{cap: pool.results.len} mut res := []&T{cap: pool.results.len}
for i in 0 .. pool.results.len { for i in 0 .. pool.results.len {
rlock pool.results {
res << unsafe { &T(pool.results[i]) } res << unsafe { &T(pool.results[i]) }
} }
}
return res return res
} }

View File

@ -234,6 +234,9 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
// we can't just do `.str` since we need the extra data from the string struct // we can't just do `.str` since we need the extra data from the string struct
// doing `&string` is also not an option since the stack memory with the data will be overwritten // doing `&string` is also not an option since the stack memory with the data will be overwritten
g.expr(left0) // node.left[0]) g.expr(left0) // node.left[0])
if first_left_type.has_flag(.shared_f) {
g.write('->val')
}
g.writeln('); // free ${type_to_free} on re-assignment2') g.writeln('); // free ${type_to_free} on re-assignment2')
defer { defer {
if af { if af {