X-Git-Url: http://git.ozlabs.org/?a=blobdiff_plain;f=ccan%2Flbalance%2Ftest%2Frun.c;fp=ccan%2Flbalance%2Ftest%2Frun.c;h=542501c0a641a775b8d796a1a52316cefd86e9ee;hb=f69389e6806e2f0b63084576ffa4c84bba699147;hp=0000000000000000000000000000000000000000;hpb=18631151c81a92341d26cee6f3b125191f3d5c41;p=ccan diff --git a/ccan/lbalance/test/run.c b/ccan/lbalance/test/run.c new file mode 100644 index 00000000..542501c0 --- /dev/null +++ b/ccan/lbalance/test/run.c @@ -0,0 +1,97 @@ +#include "config.h" +#include +#include +#include +#include + +static int fake_gettimeofday(struct timeval *tv, struct timezone *tz); +static int fake_getrusage(int who, struct rusage *usage); +#define gettimeofday fake_gettimeofday +#define getrusage fake_getrusage + +#include +#include + +static unsigned faketime_ms = 0; +static struct rusage total_usage; + +static int fake_gettimeofday(struct timeval *tv, struct timezone *tz) +{ + assert(tz == NULL); + tv->tv_usec = (faketime_ms % 1000) * 1000; + tv->tv_sec = faketime_ms / 1000; + return 0; +} + +static int fake_getrusage(int who, struct rusage *usage) +{ + assert(who == RUSAGE_CHILDREN); + *usage = total_usage; + return 0; +} + +static void test_optimum(struct lbalance *lb, unsigned int optimum) +{ + unsigned int j, i, num_tasks = 0, usec, num_counted = 0; + float average; + struct lbalance_task *tasks[1000]; + + for (j = 0; j < 1000; j++) { + diag("lbalance_target is %u\n", lbalance_target(lb)); + /* We measure average once we try optimum once. */ + if (lbalance_target(lb) == optimum && num_counted == 0) { + average = lbalance_target(lb); + num_counted = 1; + } else if (num_counted) { + average += lbalance_target(lb); + num_counted++; + } + + /* Create tasks until we reach target. */ + for (i = 0; i < lbalance_target(lb); i++) { + tasks[i] = lbalance_task_new(lb); + } + num_tasks = i; + + faketime_ms += 100; + /* If we're under optimum, set utilization to 100% */ + if (num_tasks <= optimum) { + usec = 100000; + } else { + usec = 100000 * optimum / num_tasks; + } + + for (i = 0; i < num_tasks; i++) { + total_usage.ru_utime.tv_usec += usec / 2; + if (total_usage.ru_utime.tv_usec > 1000000) { + total_usage.ru_utime.tv_usec -= 1000000; + total_usage.ru_utime.tv_sec++; + } + total_usage.ru_stime.tv_usec += usec / 2; + if (total_usage.ru_stime.tv_usec > 1000000) { + total_usage.ru_stime.tv_usec -= 1000000; + total_usage.ru_stime.tv_sec++; + } + lbalance_task_free(tasks[i], NULL); + } + } + + /* We should have stayed close to optimum. */ + ok1(num_counted && (int)(average / num_counted + 0.5) == optimum); +} + +int main(void) +{ + struct lbalance *lb; + + plan_tests(4); + lb = lbalance_new(); + + test_optimum(lb, 1); + test_optimum(lb, 2); + test_optimum(lb, 4); + test_optimum(lb, 64); + lbalance_free(lb); + + return exit_status(); +}