From c10ed33172acfd5126a82cd11b1476d5c9a8aa9f Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sun, 5 Jun 2011 10:12:41 +0930 Subject: [PATCH] lbalance: add examples. --- ccan/lbalance/_info | 66 +++++++++++++++++++++++++++++++++++++++ ccan/lbalance/lbalance.h | 67 +++++++++++++++++++++++++++++++++++----- 2 files changed, 126 insertions(+), 7 deletions(-) diff --git a/ccan/lbalance/_info b/ccan/lbalance/_info index c0d0ab0e..e3e9c78e 100644 --- a/ccan/lbalance/_info +++ b/ccan/lbalance/_info @@ -9,6 +9,72 @@ * * License: GPL * Author: Rusty Russell + * + * Example: + * // Run 1000 of the given commandline at best-known parallel rate. + * // See tools/lbalance.c for a sligtly more serious example. + * #include + * #include + * #include + * #include + * #include + * #include + * + * #define MAX 1000 + * + * static pid_t spawn(char *args[]) + * { + * pid_t pid = fork(); + * + * if (pid == -1) + * err(1, "forking"); + * if (pid == 0) { + * execvp(args[0], args); + * err(1, "exec failed"); + * } + * return pid; + * } + * + * int main(int argc, char *argv[]) + * { + * unsigned int num = 0, num_running = 0; + * pid_t pids[MAX]; + * struct lbalance_task *tasks[MAX]; + * struct lbalance *lb; + * + * if (argc == 1) + * errx(1, "Usage: %s cmdline...", argv[0]); + * + * lb = lbalance_new(); + * + * while (num - num_running < MAX) { + * struct rusage ru; + * pid_t pid; + * unsigned int i; + * + * // Make sure we're running as many as lbalance says to. + * while (num_running < lbalance_target(lb) && num < MAX) { + * pids[num] = spawn(argv+1); + * tasks[num] = lbalance_task_new(lb); + * num++; + * num_running++; + * } + * + * // Now wait for something to die. + * pid = wait3(NULL, 0, &ru); + * // Find it, tell lbalance it's finished. + * for (i = 0; i < num; i++) { + * if (pids[i] == pid) { + * lbalance_task_free(tasks[i], &ru); + * pids[i] = 0; + * break; + * } + * } + * num_running--; + * } + * lbalance_free(lb); + * return 0; + * } */ int main(int argc, char *argv[]) { diff --git a/ccan/lbalance/lbalance.h b/ccan/lbalance/lbalance.h index d318a6fe..b5de8aa6 100644 --- a/ccan/lbalance/lbalance.h +++ b/ccan/lbalance/lbalance.h @@ -9,12 +9,41 @@ struct rusage; /** * lbalance_new - initialize a load balancing structure. + * + * Example: + * struct lbalance *lb = lbalance_new(); + * + * // ... + * + * lbalance_free(lb); + * return 0; */ struct lbalance *lbalance_new(void); +/** + * lbalance_free - free a load balancing structure. + * @lbalance: the load balancer from lbalance_new. + * + * Also frees any tasks still attached. + */ +void lbalance_free(struct lbalance *lbalance); + /** * lbalance_task_new - mark the starting of a new task. * @lbalance: the load balancer from lbalance_new. + * + * Example: + * static pid_t run_child(struct lbalance *lb, struct lbalance_task **task) + * { + * pid_t pid = fork(); + * if (pid != 0) { + * // We are the parent, return. + * *task = lbalance_task_new(lb); + * return pid; + * } + * // otherwise do some work... + * exit(0); + * } */ struct lbalance_task *lbalance_task_new(struct lbalance *lbalance); @@ -29,6 +58,21 @@ struct lbalance_task *lbalance_task_new(struct lbalance *lbalance); * * Otherwise, lbalance_task_free() is a noop, which is useful for failure * paths. + * + * Example: + * #include + * #include + * #include + * #include + * + * static void wait_for_child(struct lbalance_task *task) + * { + * struct rusage ru; + * // Wait for child to finish, get usage. + * wait4(-1, NULL, 0, &ru); + * // Tell lbalancer about usage, free struct lbalance_task. + * lbalance_task_free(task, &ru); + * } */ void lbalance_task_free(struct lbalance_task *task, const struct rusage *usage); @@ -39,14 +83,23 @@ void lbalance_task_free(struct lbalance_task *task, * * Normally you keep creating tasks until this limit is reached. It's * updated by stats from lbalance_task_free. + * + * Example: + * int main(void) + * { + * unsigned int num_running = 0; + * struct lbalance *lb = lbalance_new(); + * + * for (;;) { + * // Run more until we reach target. + * while (num_running < lbalance_target(lb)) { + * // Run another one. + * } + * + * // Wait for something to finish. + * } + * } */ unsigned lbalance_target(struct lbalance *lbalance); -/** - * lbalance_free - free a load balancing structure. - * @lbalance: the load balancer from lbalance_new. - * - * Also frees any tasks still attached. - */ -void lbalance_free(struct lbalance *lbalance); #endif /* CCAN_LBALANCE_H */ -- 2.39.2