diff --git a/vlib/sync/pool.v b/vlib/sync/pool.v index 457e0bbf26..59bef8e136 100644 --- a/vlib/sync/pool.v +++ b/vlib/sync/pool.v @@ -98,9 +98,10 @@ pub fn (pool mut PoolProcessor) set_max_jobs(njobs int) { // by the number of available cores on the system. // work_on_items returns *after* all threads finish. // You can optionally call get_results after that. -pub fn (pool mut PoolProcessor) work_on_items(items []T) { - pool.work_on_pointers( items.pointers() ) -} +// TODO: uncomment, when generics work again +//pub fn (pool mut PoolProcessor) work_on_items(items []T) { +// pool.work_on_pointers( items.pointers() ) +//} pub fn (pool mut PoolProcessor) work_on_pointers(items []voidptr) { mut njobs := runtime.nr_jobs() @@ -115,7 +116,9 @@ pub fn (pool mut PoolProcessor) work_on_pointers(items []voidptr) { pool.thread_contexts << [voidptr(0)].repeat(pool.items.len) pool.waitgroup.add(njobs) for i := 0; i < njobs; i++ { - go process_in_thread(pool,i) + // TODO: uncomment when `go func()` works again with v2 + // go process_in_thread(pool,i) + process_in_thread(pool,i) } pool.waitgroup.wait() } @@ -145,36 +148,44 @@ fn process_in_thread(pool mut PoolProcessor, task_id int) { // get_item - called by the worker callback. // Retrieves a type safe instance of the currently processed item -pub fn (pool &PoolProcessor) get_item(idx int) T { - return *(&T(pool.items[idx])) -} +// TODO: uncomment, when generics work again +//pub fn (pool &PoolProcessor) get_item(idx int) T { +// return *(&T(pool.items[idx])) +//} +// TODO: the below is a hack, remove it when v2 &string() casting works again +type mystring string // get_string_item - called by the worker callback. // It does not use generics so it does not mess up vfmt. // TODO: remove the need for this when vfmt becomes smarter. pub fn (pool &PoolProcessor) get_string_item(idx int) string { - return *(&string(pool.items[idx])) + // return *(&string(pool.items[idx])) + // TODO: the below is a hack, remove it when v2 casting works again + return &mystring( pool.items[idx] ) } // get_int_item - called by the worker callback. // It does not use generics so it does not mess up vfmt. // TODO: remove the need for this when vfmt becomes smarter. pub fn (pool &PoolProcessor) get_int_item(idx int) int { - return *(&int(pool.items[idx])) + item := pool.items[idx] + return *(&int(item)) } -pub fn (pool &PoolProcessor) get_result(idx int) T { - return *(&T(pool.results[idx])) -} +// TODO: uncomment, when generics work again +//pub fn (pool &PoolProcessor) get_result(idx int) T { +// return *(&T(pool.results[idx])) +//} +// TODO: uncomment, when generics work again // get_results - can be called to get a list of type safe results. -pub fn (pool &PoolProcessor) get_results() []T { - mut res := []T - for i in 0 .. pool.results.len { - res << *(&T(pool.results[i])) - } - return res -} +//pub fn (pool &PoolProcessor) get_results() []T { +// mut res := []T +// for i in 0 .. pool.results.len { +// res << *(&T(pool.results[i])) +// } +// return res +//} // set_shared_context - can be called during the setup so that you can // provide a context that is shared between all worker threads, like @@ -203,3 +214,38 @@ pub fn (pool mut PoolProcessor) set_thread_context(idx int, context voidptr) { pub fn (pool &PoolProcessor) get_thread_context(idx int) voidptr { return pool.thread_contexts[idx] } + +// TODO: remove everything below this line after generics are fixed: +pub struct SResult { +pub: + s string +} +pub struct IResult { +pub: + i int +} + +// + +pub fn (pool mut PoolProcessor) work_on_items_s(items []string) { + pool.work_on_pointers( items.pointers() ) +} + +pub fn (pool mut PoolProcessor) work_on_items_i(items []int) { + pool.work_on_pointers( items.pointers() ) +} + +pub fn (pool &PoolProcessor) get_results_s() []SResult { + mut res := []SResult + for i in 0 .. pool.results.len { + res << *(&SResult(pool.results[i])) + } + return res +} +pub fn (pool &PoolProcessor) get_results_i() []IResult { + mut res := []IResult + for i in 0 .. pool.results.len { + res << *(&IResult(pool.results[i])) + } + return res +} diff --git a/vlib/sync/pool_test.v b/vlib/sync/pool_test.v index 0834617bd6..4a65a13d28 100644 --- a/vlib/sync/pool_test.v +++ b/vlib/sync/pool_test.v @@ -1,10 +1,5 @@ import sync import time -import rand - -struct SResult { - s string -} fn worker_s(p &sync.PoolProcessor, idx int, worker_id int) voidptr { // TODO: this works, but confuses vfmt. It should be used instead of @@ -12,12 +7,8 @@ fn worker_s(p &sync.PoolProcessor, idx int, worker_id int) voidptr { // item := p.get_item(idx) item := p.get_string_item(idx) println('worker_s worker_id: $worker_id | idx: $idx | item: ${item}') - time.sleep_ms(rand.next(3)) - return &SResult{item + item} -} - -struct IResult { - i int + time.sleep_ms(3) + return voidptr( &sync.SResult{ '${item} ${item}' } ) } fn worker_i(p &sync.PoolProcessor, idx int, worker_id int) voidptr { @@ -25,33 +16,47 @@ fn worker_i(p &sync.PoolProcessor, idx int, worker_id int) voidptr { // item := p.get_item(idx) item := p.get_int_item(idx) println('worker_i worker_id: $worker_id | idx: $idx | item: ${item}') - time.sleep_ms(rand.next(5)) - return &IResult{item * 1000} + time.sleep_ms(5) + return voidptr( &sync.IResult{ item * 1000 } ) } fn test_work_on_strings() { - rand.seed(0) mut pool_s := sync.new_pool_processor({ callback: worker_s maxjobs: 8 }) - pool_s.work_on_items(['a','b','c','d','e','f','g','h','i','j']) - for x in pool_s.get_results() { + + // TODO: uncomment this when generics work again + //pool_s.work_on_items(['a','b','c','d','e','f','g','h','i','j']) + //for x in pool_s.get_results() { + // println( x.s ) + // assert x.s.len > 1 + //} + + pool_s.work_on_items_s(['a','b','c','d','e','f','g','h','i','j']) + for x in pool_s.get_results_s() { println( x.s ) assert x.s.len > 1 } } fn test_work_on_ints() { - rand.seed(0) // NB: since maxjobs is left empty here, // the pool processor will use njobs = runtime.nr_jobs so that // it will work optimally without overloading the system mut pool_i := sync.new_pool_processor({ callback: worker_i }) - pool_i.work_on_items([1,2,3,4,5,6,7,8]) - for x in pool_i.get_results() { + + // TODO: uncomment this when generics work again + //pool_i.work_on_items([1,2,3,4,5,6,7,8]) + //for x in pool_i.get_results() { + // println( x.i ) + // assert x.i > 100 + //} + + pool_i.work_on_items_i([1,2,3,4,5,6,7,8]) + for x in pool_i.get_results_i() { println( x.i ) assert x.i > 100 }