1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
from cffi import FFI
import sys
ffi = FFI()
# Note: we don't directly expose 'struct timeval' or 'struct rlimit'
rlimit_consts = '''
RLIMIT_CPU
RLIMIT_FSIZE
RLIMIT_DATA
RLIMIT_STACK
RLIMIT_CORE
RLIMIT_NOFILE
RLIMIT_OFILE
RLIMIT_VMEM
RLIMIT_AS
RLIMIT_RSS
RLIMIT_NPROC
RLIMIT_MEMLOCK
RLIMIT_SBSIZE
RLIM_INFINITY
RUSAGE_SELF
RUSAGE_CHILDREN
RUSAGE_BOTH
'''.split()
rlimit_consts = ['#ifdef %s\n\t{"%s", %s},\n#endif\n' % (s, s, s)
for s in rlimit_consts]
ffi.set_source("_resource_cffi", """
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/wait.h>
static const struct my_rlimit_def {
const char *name;
long long value;
} my_rlimit_consts[] = {
$RLIMIT_CONSTS
{ NULL, 0 }
};
#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
static double my_utime(struct rusage *input)
{
return doubletime(input->ru_utime);
}
static double my_stime(struct rusage *input)
{
return doubletime(input->ru_stime);
}
static int my_getrlimit(int resource, long long result[2])
{
struct rlimit rl;
if (getrlimit(resource, &rl) == -1)
return -1;
result[0] = rl.rlim_cur;
result[1] = rl.rlim_max;
return 0;
}
static int my_setrlimit(int resource, long long cur, long long max)
{
struct rlimit rl;
rl.rlim_cur = cur & RLIM_INFINITY;
rl.rlim_max = max & RLIM_INFINITY;
return setrlimit(resource, &rl);
}
#ifdef __linux__
static int _prlimit(int pid, int resource, int set, long long cur, long long max, long long result[2])
{
struct rlimit new_rl, old_rl;
new_rl.rlim_cur = cur & RLIM_INFINITY;
new_rl.rlim_max = max & RLIM_INFINITY;
if(prlimit(pid, resource, (set ? &new_rl : NULL), &old_rl) == -1)
return -1;
result[0] = old_rl.rlim_cur;
result[1] = old_rl.rlim_max;
return 0;
}
#endif
""".replace('$RLIMIT_CONSTS', ''.join(rlimit_consts)))
ffi.cdef("""
#define RLIM_NLIMITS ...
const struct my_rlimit_def {
const char *name;
long long value;
} my_rlimit_consts[];
struct rusage {
long ru_maxrss;
long ru_ixrss;
long ru_idrss;
long ru_isrss;
long ru_minflt;
long ru_majflt;
long ru_nswap;
long ru_inblock;
long ru_oublock;
long ru_msgsnd;
long ru_msgrcv;
long ru_nsignals;
long ru_nvcsw;
long ru_nivcsw;
...;
};
static double my_utime(struct rusage *);
static double my_stime(struct rusage *);
void getrusage(int who, struct rusage *result);
int my_getrlimit(int resource, long long result[2]);
int my_setrlimit(int resource, long long cur, long long max);
int wait3(int *status, int options, struct rusage *rusage);
int wait4(int pid, int *status, int options, struct rusage *rusage);
""")
if sys.platform.startswith("linux"):
ffi.cdef("""
int _prlimit(int pid, int resource, int set, long long cur, long long max, long long result[2]);
""")
if __name__ == "__main__":
ffi.compile()
|