-
Notifications
You must be signed in to change notification settings - Fork 412
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4517 from rgrinberg/accurate-process-time
Use wait3 to accurately time spawned processes
- Loading branch information
Showing
10 changed files
with
300 additions
and
105 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,4 +10,4 @@ | |
dune_filesystem_stubs) | ||
(foreign_stubs | ||
(language c) | ||
(names fcntl_stubs))) | ||
(names fcntl_stubs wait3_stubs))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,30 @@ | ||
val restore_cwd_and_execve : string -> string list -> env:Env.t -> _ | ||
|
||
module Resource_usage : sig | ||
type t = | ||
{ user_cpu_time : float | ||
(** Same as the "user" time reported by the "time" command *) | ||
; system_cpu_time : float | ||
(** Same as the "sys" time reported by the "time" command *) | ||
} | ||
end | ||
|
||
module Times : sig | ||
type t = | ||
{ elapsed_time : float | ||
(** Same as the "real" time reported by the "time" command *) | ||
; resource_usage : Resource_usage.t option | ||
} | ||
end | ||
|
||
module Process_info : sig | ||
type t = | ||
{ pid : Pid.t | ||
; status : Unix.process_status | ||
; end_time : float (** Time at which the process finished. *) | ||
; resource_usage : Resource_usage.t option | ||
} | ||
end | ||
|
||
(** This function is not implemented on Windows *) | ||
val wait : Unix.wait_flag list -> Process_info.t |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
#include <caml/mlvalues.h> | ||
|
||
#ifdef _WIN32 | ||
#include <caml/fail.h> | ||
|
||
void dune_wait3(value flags) { | ||
caml_failwith("wait3: not supported on windows"); | ||
} | ||
|
||
#else | ||
|
||
#include <caml/alloc.h> | ||
#include <caml/memory.h> | ||
#include <caml/signals.h> | ||
#include <caml/unixsupport.h> | ||
|
||
#include <sys/resource.h> | ||
#include <sys/time.h> | ||
#include <sys/types.h> | ||
#include <sys/wait.h> | ||
|
||
#define TAG_WEXITED 0 | ||
#define TAG_WSIGNALED 1 | ||
#define TAG_WSTOPPED 2 | ||
|
||
CAMLextern int caml_convert_signal_number(int); | ||
CAMLextern int caml_rev_convert_signal_number(int); | ||
|
||
static value alloc_process_status(int status) { | ||
value st; | ||
|
||
if (WIFEXITED(status)) { | ||
st = caml_alloc_small(1, TAG_WEXITED); | ||
Field(st, 0) = Val_int(WEXITSTATUS(status)); | ||
} else if (WIFSTOPPED(status)) { | ||
st = caml_alloc_small(1, TAG_WSTOPPED); | ||
Field(st, 0) = Val_int(caml_rev_convert_signal_number(WSTOPSIG(status))); | ||
} else { | ||
st = caml_alloc_small(1, TAG_WSIGNALED); | ||
Field(st, 0) = Val_int(caml_rev_convert_signal_number(WTERMSIG(status))); | ||
} | ||
return st; | ||
} | ||
|
||
static int wait_flag_table[] = {WNOHANG, WUNTRACED}; | ||
|
||
value dune_wait3(value flags) { | ||
CAMLparam1(flags); | ||
CAMLlocal2(times, res); | ||
|
||
int pid, status, cv_flags; | ||
struct timeval tp; | ||
cv_flags = caml_convert_flag_list(flags, wait_flag_table); | ||
|
||
struct rusage ru; | ||
|
||
caml_enter_blocking_section(); | ||
pid = wait3(&status, cv_flags, &ru); | ||
gettimeofday(&tp, NULL); | ||
caml_leave_blocking_section(); | ||
if (pid == -1) | ||
uerror("wait3", Nothing); | ||
|
||
times = caml_alloc_small(2 * Double_wosize, Double_array_tag); | ||
Store_double_field(times, 0, ru.ru_utime.tv_sec + ru.ru_utime.tv_usec / 1e6); | ||
Store_double_field(times, 1, ru.ru_stime.tv_sec + ru.ru_stime.tv_usec / 1e6); | ||
|
||
res = caml_alloc_tuple(4); | ||
Store_field(res, 0, Val_int(pid)); | ||
Store_field(res, 1, alloc_process_status(status)); | ||
Store_field(res, 2, caml_copy_double(((double) tp.tv_sec + (double) tp.tv_usec / 1e6))); | ||
Store_field(res, 3, times); | ||
CAMLreturn(res); | ||
} | ||
|
||
#endif |
Oops, something went wrong.