int main(void) { int nthreads = sysconf(_SC_NPROCESSORS_ONLN); wqueue *queue = wqueue_create(50, nthreads); struct sha1_job jobs[400]; for (unsigned i = 0; i < countof(jobs); i++) { sprintf(jobs[i].message, "hello%06d", i); wqueue_add(queue, sha1_worker, &jobs[i]); } fprintf(stderr, "\x1b[91;1mWaiting ...\n\x1b[0m"); wqueue_wait(queue); wqueue_free(queue); return 0; }
struct _graph * elf32_graph_functions (struct _elf32 * elf32, struct _map * memory, struct _map * functions) { struct _graph * graph; struct _wqueue * wqueue; // disassemble from entry point graph = x86_graph(elf32_entry(elf32), memory); struct _map_it * it; wqueue = wqueue_create(); for (it = map_iterator(functions); it != NULL; it = map_it_next(it)) { struct _function * function = map_it_data(it); struct _x86_wqueue * x86w; x86w = x86_wqueue_create(function->address, memory); wqueue_push(wqueue, WQUEUE_CALLBACK(x86_graph_wqueue), x86w); object_delete(x86w); } wqueue_wait(wqueue); while (wqueue_peek(wqueue) != NULL) { graph_merge(graph, wqueue_peek(wqueue)); wqueue_pop(wqueue); } object_delete(wqueue); remove_function_predecessors(graph, functions); graph_reduce(graph); return graph; }
struct _map * elf32_functions_wqueue (struct _elf32 * elf32, struct _map * memory, struct _list * entries) { struct _map * functions = map_create(); struct _wqueue * wqueue = wqueue_create(); struct _list_it * it; for (it = list_iterator(entries); it != NULL; it = it->next) { struct _function * function = it->data; if (map_fetch(functions, function->address) == NULL) map_insert(functions, function->address, function); struct _x86_wqueue * x86w; x86w = x86_wqueue_create(function->address, memory); wqueue_push(wqueue, WQUEUE_CALLBACK(x86_functions_wqueue), x86w); object_delete(x86w); } wqueue_wait(wqueue); struct _map * fmap; while ((fmap = wqueue_peek(wqueue)) != NULL) { struct _map_it * mit; for (mit = map_iterator(fmap); mit != NULL; mit = map_it_next(mit)) { struct _function * function = map_it_data(mit); if (map_fetch(functions, function->address) == NULL) map_insert(functions, function->address, function); } wqueue_pop(wqueue); } object_delete(wqueue); return functions; }