lbalance.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #include <ccan/lbalance/lbalance.h>
  2. #include <ccan/lbalance/lbalance.c>
  3. #include <ccan/time/time.h>
  4. #include <ccan/jmap/jmap_type.h>
  5. #include <stdio.h>
  6. #include <err.h>
  7. /* Defines struct jmap_task. */
  8. JMAP_DEFINE_UINTIDX_TYPE(struct lbalance_task, task);
  9. /* Figure out how many loops we need to run for about 1 second. */
  10. static unsigned long burn_count;
  11. static void calibrate_burn_cpu(void)
  12. {
  13. struct timeval start = time_now();
  14. while (time_less(time_now(), time_add(start, time_from_msec(1000))))
  15. burn_count++;
  16. printf("Burn count = %lu\n", burn_count);
  17. }
  18. static void burn_cpu(void)
  19. {
  20. unsigned int i, after = 0;
  21. struct timeval start = time_now();
  22. /* We do a loop similar to the calibrate_burn_cpu loop. */
  23. for (i = 0; i < burn_count; i++) {
  24. after += time_less(time_now(),
  25. time_add(start, time_from_msec(1000)));
  26. }
  27. /* We use the result so the compiler can't discard it. */
  28. exit(after);
  29. }
  30. static pid_t spawn(char *args[])
  31. {
  32. pid_t pid = fork();
  33. if (pid == -1)
  34. err(1, "forking");
  35. if (pid == 0) {
  36. if (!args[0])
  37. burn_cpu();
  38. execvp(args[0], args);
  39. err(1, "exec failed");
  40. }
  41. return pid;
  42. }
  43. int main(int argc, char *argv[])
  44. {
  45. unsigned int i, num, fixed_target = 0, num_done = 0, num_running = 0;
  46. struct lbalance *lb;
  47. struct jmap_task *tasks = jmap_task_new();
  48. if (argc < 2) {
  49. fprintf(stderr,
  50. "Usage: lbalance --fixed=<num> <num> [<command>...]\n"
  51. "OR: lbalance <num> [<command>...]\n");
  52. exit(1);
  53. }
  54. if (strncmp(argv[1], "--fixed=", strlen("--fixed=")) == 0) {
  55. fixed_target = atoi(argv[1] + strlen("--fixed="));
  56. if (!fixed_target)
  57. errx(1, "Need positive number after --fixed");
  58. argv++;
  59. argc--;
  60. lb = NULL;
  61. } else {
  62. lb = lbalance_new();
  63. }
  64. num = atoi(argv[1]);
  65. argv++;
  66. argc--;
  67. if (!argv[1])
  68. calibrate_burn_cpu();
  69. while (num_done < num) {
  70. unsigned int j, target = fixed_target;
  71. struct lbalance_task *task;
  72. struct rusage ru;
  73. pid_t pid;
  74. if (lb) {
  75. target = lbalance_target(lb);
  76. printf("(%u)", target);
  77. }
  78. while (num_running < target && num_done + num_running < num) {
  79. pid = spawn(argv+1);
  80. if (lb)
  81. task = lbalance_task_new(lb);
  82. else
  83. task = (void *)1;
  84. jmap_task_add(tasks, pid, task);
  85. num_running++;
  86. printf("+"); fflush(stdout);
  87. }
  88. /* Now wait for something to die! */
  89. pid = wait3(NULL, 0, &ru);
  90. task = jmap_task_get(tasks, pid);
  91. if (lb)
  92. lbalance_task_free(task, &ru);
  93. num_done++;
  94. num_running--;
  95. printf("-"); fflush(stdout);
  96. }
  97. printf("\n");
  98. if (lb)
  99. lbalance_free(lb);
  100. return 0;
  101. }