6 ex_parallel_for_8c example
gullradriel edited this page 2026-10-09 00:55:18 +02:00

ex_parallel_for.c

n_parallel_for(): a loop over a range on several cores Fills an array in parallel and checks every item was written exactly once, whatever the slicing; that a small range runs on the caller alone; that an empty range does nothing; and that two parallel loops started at once from two threads, as workers of a pool do, both finish right while sharing one budget of cores. ```c

#include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <string.h>

#include "nilorea/n_common.h" #include "nilorea/n_log.h" #include "nilorea/n_thread_pool.h"

static int failures = 0;

static void expect_true(const char* what, int ok) { if (!ok) { n_log(LOG_ERR, "FAIL: %s", what); failures++; } }

static void bump(size_t begin, size_t end, void* user) { int* items = (int*)user; size_t i = 0;

for (i = begin; i < end; i++) items[i]++;

}

static void* nested(void* arg) { n_parallel_for(0, 1000000, 1000, bump, arg); return NULL; }

static int all_ones(const int* items, size_t count) { size_t i = 0;

for (i = 0; i < count; i++)
    if (items[i] != 1) return 0;
return 1;

}

int main(void) { int* a = NULL; int* b = NULL; pthread_t other; int slices = 0;

set_log_level(LOG_NOTICE);
a = calloc(1000000, sizeof(int));
b = calloc(1000000, sizeof(int));
if (!a || !b) return 1;

slices = n_parallel_for(0, 1000000, 1000, bump, a);
n_log(LOG_NOTICE, "ex_parallel_for: a million items in %d slice(s) on %ld core(s)", slices, get_nb_cpu_cores());
expect_true("every item written exactly once", all_ones(a, 1000000));
expect_true("more than one slice on a machine with more than one core",
            get_nb_cpu_cores() < 2 || slices > 1);

memset(a, 0, 1000000 * sizeof(int));
expect_true("a range under two grains runs as one slice", n_parallel_for(0, 1500, 1000, bump, a) == 1);
expect_true("and does all of it", all_ones(a, 1500));
expect_true("an empty range does nothing", n_parallel_for(10, 10, 1, bump, a) == 0);
expect_true("a NULL function does nothing", n_parallel_for(0, 10, 1, NULL, a) == 0);

/* Two at once, sharing the budget. */
memset(a, 0, 1000000 * sizeof(int));
if (pthread_create(&other, NULL, nested, b) != 0) return 1;
n_parallel_for(0, 1000000, 1000, bump, a);
pthread_join(other, NULL);
expect_true("two loops at once both finish right", all_ones(a, 1000000) && all_ones(b, 1000000));

free(a);
free(b);
n_log(LOG_NOTICE, "ex_parallel_for: %s", failures ? "FAILED" : "ok");
return failures ? 1 : 0;

}


_Filename: ex_parallel_for.c_