1#
2# getrusage for processor times
3#
4package provide Getrusage 0.1
5package require Ffidl
6package require Ffidlrt
7
8#
9# system types
10#
11::ffidl::find-type time_t
12::ffidl::find-type clock_t
13::ffidl::find-type timeval
14
15#
16# typedefs, avoid redefinition error
17#
18catch {
19    ::ffidl::typedef rusage timeval timeval long long long long long long long long long long long long long long
20}
21
22#
23# raw interfaces
24#
25::ffidl::callout _getrusage {int pointer-var} int [ffidl::symbol [ffidl::find-lib c] getrusage]
26::ffidl::callout _clock {} clock_t [ffidl::symbol [ffidl::find-lib c] clock]
27
28#
29# the cooked interfaces
30#
31proc getrusage {who} {
32    set rusage [binary format x[ffidl::info sizeof rusage]]
33    switch $who {
34	SELF { set rwho 0 }
35	CHILDREN { set rwho -1 }
36	BOTH { set rwho -2 }
37    }
38    if {[_getrusage $rwho rusage] != 0} {
39	return {}
40    }
41    binary scan $rusage [ffidl::info format rusage] \
42	v(ru_utime.tv_sec) v(ru_utime.tv_usec) \
43	v(ru_stime.tv_sec) v(ru_stime.tv_usec) \
44	v(ru_maxrss) v(ru_ixrss) v(ru_idrss) v(ru_isrss) \
45	v(ru_minflt) v(ru_majflt) v(ru_nswap) \
46	v(ru_inblock) v(ru_oublock) \
47	v(ru_msgsnd) v(ru_msgrcv) \
48	v(ru_nsignals) v(ru_nvcsw) v(ru_nivcsw)
49    array get v
50}
51proc utime {} {
52    array set v [getrusage SELF]
53    expr {$v(ru_utime.tv_sec)+$v(ru_utime.tv_usec)*1.0e-6}
54}
55proc stime {} {
56    array set v [getrusage SELF]
57    expr {$v(ru_stime.tv_sec)+$v(ru_stime.tv_usec)*1.0e-6}
58}
59