aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2024-09-17 09:37:14 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2024-09-18 23:08:03 -0400
commitdb1a3056296ea3ed13c5a425cf1f11602b43a6c7 (patch)
tree3e3ad60bb4dbdee1a37e10cb10cb3dc2f10b334c
parent0f95b43e2d3853995106c5c6aa55bf92f63fb331 (diff)
downloadstasis-db1a3056296ea3ed13c5a425cf1f11602b43a6c7.tar.gz
Add pool summary and elapsed time output
* Add get_task_duration() * Add get_pool_show_summary() * Add signaled_by member to MultiProcessingTask * Add time_data member to MultiProcessingTask for duration tracking
-rw-r--r--include/multiprocessing.h12
-rw-r--r--src/multiprocessing.c48
2 files changed, 60 insertions, 0 deletions
diff --git a/include/multiprocessing.h b/include/multiprocessing.h
index 4e89722..2356403 100644
--- a/include/multiprocessing.h
+++ b/include/multiprocessing.h
@@ -15,9 +15,14 @@ struct MultiProcessingTask {
pid_t pid; ///< Program PID
pid_t parent_pid; ///< Program PID (parent process)
int status; ///< Child process exit status
+ int signaled_by; ///< Last signal received, if any
char ident[255]; ///< Identity of the pool task
char log_file[255]; ///< Path to stdout/stderr log file
char parent_script[PATH_MAX]; ///< Path to temporary script executing the task
+ struct {
+ struct timespec t_start;
+ struct timespec t_stop;
+ } time_data; ///< Wall-time counters
};
struct MultiProcessingPool {
@@ -104,6 +109,13 @@ struct MultiProcessingTask *mp_task(struct MultiProcessingPool *pool, const char
int mp_pool_join(struct MultiProcessingPool *pool, size_t jobs, size_t flags);
/**
+ * Show summary of pool tasks
+ *
+ * @pararm pool a pointer to MultiProcessingPool
+ */
+void mp_pool_show_summary(struct MultiProcessingPool *pool);
+
+/**
* Release resources allocated by mp_pool_init()
*
* @param a pointer to MultiProcessingPool
diff --git a/src/multiprocessing.c b/src/multiprocessing.c
index fe15ab6..5e605a6 100644
--- a/src/multiprocessing.c
+++ b/src/multiprocessing.c
@@ -161,6 +161,41 @@ struct MultiProcessingTask *mp_task(struct MultiProcessingPool *pool, const char
return slot;
}
+static void get_task_duration(struct MultiProcessingTask *task, struct timespec *result) {
+ struct timespec *start = &task->time_data.t_start;
+ struct timespec *stop = &task->time_data.t_stop;
+ result->tv_sec = (stop->tv_sec - start->tv_sec);
+ result->tv_nsec = (stop->tv_nsec - start->tv_nsec);
+ if (result->tv_nsec < 0) {
+ --result->tv_sec;
+ result->tv_nsec += 1000000000L;
+ }
+}
+
+void mp_pool_show_summary(struct MultiProcessingPool *pool) {
+ print_banner("=", 79);
+ printf("Pool execution summary for \"%s\"\n", pool->ident);
+ print_banner("=", 79);
+ printf("STATUS PID DURATION IDENT\n");
+ for (size_t i = 0; i < pool->num_used; i++) {
+ struct MultiProcessingTask *task = &pool->task[i];
+ char status_str[10] = {0};
+ if (!task->status && !task->signaled_by) {
+ strcpy(status_str, "DONE");
+ } else if (task->signaled_by) {
+ strcpy(status_str, "TERM");
+ } else {
+ strcpy(status_str, "FAIL");
+ }
+
+ struct timespec duration;
+ get_task_duration(task, &duration);
+ long diff = duration.tv_sec + duration.tv_nsec / 1000000000L;
+ printf("%-4s %-10d %7lds %-10s\n", status_str, task->parent_pid, diff, task->ident) ;
+ }
+ puts("");
+}
+
static int show_log_contents(FILE *stream, struct MultiProcessingTask *task) {
FILE *fp = fopen(task->log_file, "r");
if (!fp) {
@@ -189,9 +224,15 @@ int mp_pool_kill(struct MultiProcessingPool *pool, int signum) {
status = kill(slot->pid, signum);
if (status && errno != ESRCH) {
fprintf(stderr, "Task '%s' (pid: %d) did not respond: %s\n", slot->ident, slot->pid, strerror(errno));
+ } else {
// Wait for process to handle the signal, then set the status accordingly
if (waitpid(slot->pid, &status, 0) >= 0) {
slot->signaled_by = WTERMSIG(status);
+ // Record the task stop time
+ if (clock_gettime(CLOCK_REALTIME, &slot->time_data.t_stop) < 0) {
+ perror("clock_gettime");
+ exit(1);
+ }
}
}
}
@@ -273,6 +314,13 @@ int mp_pool_join(struct MultiProcessingPool *pool, size_t jobs, size_t flags) {
if (show_log_contents(stdout, slot)) {
perror(slot->log_file);
}
+
+ // Record the task stop time
+ if (clock_gettime(CLOCK_REALTIME, &slot->time_data.t_stop) < 0) {
+ perror("clock_gettime");
+ exit(1);
+ }
+
if (status >> 8 != 0 || (status & 0xff) != 0) {
fprintf(stderr, "%s Task failed\n", progress);
if (flags & MP_POOL_FAIL_FAST && pool->num_used > 1) {