Skip to content

Commit b1b22cf

Browse files
committed
feat(Lib): resource
1 parent 4ea577a commit b1b22cf

File tree

6 files changed

+207
-0
lines changed

6 files changed

+207
-0
lines changed

src/pylib/Lib/resource.nim

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
import ./resource_impl/[
3+
funcs, consts, types
4+
]
5+
6+
export funcs, consts, types
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
2+
from ./csyms import SIZEOF_RLIMIT_T
3+
4+
const RLIM_INFINITY* =
5+
when SIZEOF_RLIMIT_T == 8:
6+
0xffffffffffffffffu
7+
else:
8+
0xffffffffu
9+
10+
template wrap(name){.dirty.} =
11+
let `c name`{.importc: astToStr(name), header: "<sys/resource.h>".}: cint
12+
let name* = int `c name`
13+
template wrap(name, os){.dirty.} =
14+
when defined(os):
15+
wrap(name)
16+
17+
wrap(RLIMIT_CORE)
18+
wrap(RLIMIT_CPU)
19+
wrap(RLIMIT_FSIZE)
20+
wrap(RLIMIT_DATA)
21+
wrap(RLIMIT_STACK)
22+
wrap(RLIMIT_RSS)
23+
wrap(RLIMIT_NPROC)
24+
wrap(RLIMIT_NOFILE)
25+
wrap(RLIMIT_OFILE)
26+
wrap(RLIMIT_MEMLOCK)
27+
wrap(RLIMIT_VMEM, freebsd)
28+
wrap(RLIMIT_AS)
29+
when defined(linux):
30+
wrap(RLIMIT_MSGQUEUE)
31+
wrap(RLIMIT_NICE)
32+
wrap(RLIMIT_RTPRIO)
33+
wrap(RLIMIT_RTTIME)
34+
wrap(RLIMIT_SIGPENDING)
35+
when defined(freebsd):
36+
wrap(RLIMIT_SBSIZE)
37+
wrap(RLIMIT_SWAP)
38+
wrap(RLIMIT_NPTS)
39+
wrap(RLIMIT_KQUEUES)
40+
41+
wrap(RUSAGE_SELF)
42+
wrap(RUSAGE_CHILDREN)
43+
wrap(RUSAGE_BOTH)
44+
wrap(RUSAGE_THREAD)

src/pylib/Lib/resource_impl/csyms.nim

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
2+
import ../../pyconfig/resource
3+
export resource

src/pylib/Lib/resource_impl/funcs.nim

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
2+
import ./types
3+
import std/posix except EINVAL, EPERM
4+
import ../n_errno
5+
import ../../pyerrors/oserr
6+
from ./csyms import HAVE_PRLIMIT, HAVE_GETPAGESIZE, HAVE_SYSCONF_PAGE_SIZE
7+
8+
proc getrusage*(who: int): struct_rusage =
9+
var ru: posix.RUsage
10+
if getrusage(who.cint, addr ru) == -1:
11+
if isErr(EINVAL):
12+
raise newException(ValueError, "Invalid who value")
13+
raiseErrno()
14+
ru.toPyObject()
15+
16+
type
17+
py_rlimit* = tuple
18+
rlim_cur: int
19+
rlim_max: int
20+
21+
# XXX: NIM-BUG: rlim_cur and rlim_max are int over unsigned in std/posix
22+
23+
proc py2rlimit(limits: py_rlimit, rl_out: var RLimit) =
24+
rl_out.rlim_cur = limits.rlim_cur
25+
rl_out.rlim_max = limits.rlim_max
26+
27+
proc rlimit2py(rl_in: RLimit): py_rlimit = (rl_in.rlim_cur, rl_in.rlim_max)
28+
29+
let RLIM_NLIMITS{.importc, header: "<sys/resource.h>".}: cint
30+
31+
proc checked_resource*(resource: int): cint =
32+
if resource < 0 or resource >= RLIM_NLIMITS:
33+
raise newException(ValueError, "Invalid resource specified")
34+
cast[cint](resource)
35+
36+
proc getrlimit*(resource: int): py_rlimit =
37+
var rl: RLimit
38+
if getrlimit(checked_resource(resource), rl) == -1:
39+
raiseErrno()
40+
rlimit2py(rl)
41+
42+
proc raise_inval =
43+
raise newException(ValueError, "current limit exceeds maximum limit")
44+
proc setrlimit*(resource: int, limits: py_rlimit) =
45+
var rl: RLimit
46+
py2rlimit(limits, rl)
47+
if setrlimit(checked_resource(resource), rl) == -1:
48+
if isErr(EINVAL): raise_inval()
49+
elif isErr(EPERM):
50+
raise newException(ValueError, "not allowed to raise maximum limit")
51+
raiseErrno()
52+
53+
when HAVE_PRLIMIT:
54+
proc prlimit(pid: Pid, resource: cint, new_limit: ptr RLimit, old_limit: var RLimit): cint {.
55+
importc, header: "<sys/resource.h>".}
56+
57+
proc prlimit*(pid: int, resource: int): py_rlimit{.discardable.} =
58+
let
59+
pid = Pid pid
60+
resource = checked_resource(resource)
61+
var old_limit: RLimit
62+
if prlimit(pid, resource, nil, old_limit) == -1:
63+
if isErr(EINVAL): raise_inval()
64+
raiseErrno()
65+
rlimit2py(old_limit)
66+
67+
proc prlimit*(pid: int, resource: int, limits: py_rlimit): py_rlimit{.discardable.} =
68+
let
69+
pid = Pid pid
70+
resource = checked_resource(resource)
71+
var old_limit, new_limit: RLimit
72+
73+
py2rlimit(limits, new_limit)
74+
if prlimit(pid, resource, addr new_limit, old_limit) == -1:
75+
if isErr(EINVAL): raise_inval()
76+
raiseErrno()
77+
78+
rlimit2py(old_limit)
79+
80+
when HAVE_GETPAGESIZE:
81+
proc c_getpagesize(): cint{.importc, header: "<unistd.h>".}
82+
proc getpagesize*(): int = int c_getpagesize()
83+
elif HAVE_SYSCONF_PAGE_SIZE:
84+
let SC_PAGE_SIZE{.importc, header: "<unistd.h>".}: cint
85+
proc c_sysconf(name: cint): cint{.importc, header: "<unistd.h>".}
86+
proc getpagesize*(): int = int c_sysconf(SC_PAGE_SIZE)
87+

src/pylib/Lib/resource_impl/types.nim

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
2+
import std/posix
3+
4+
type
5+
struct_rusage* = ref object
6+
ru_utime*: float
7+
ru_stime*: float
8+
ru_maxrss*: int
9+
ru_ixrss*: int
10+
ru_idrss*: int
11+
ru_isrss*: int
12+
ru_minflt*: int
13+
ru_majflt*: int
14+
ru_nswap*: int
15+
ru_inblock*: int
16+
ru_oublock*: int
17+
ru_msgsnd*: int
18+
ru_msgrcv*: int
19+
ru_nsignals*: int
20+
ru_nvcsw*: int
21+
ru_nivcsw*: int
22+
23+
template doubletime(tv: TimeVal): float =
24+
float(tv.tv_sec) + float(tv.tv_usec) / 1000000.0
25+
26+
proc toPyObject*(rusage: RUsage): struct_rusage =
27+
struct_rusage(
28+
ru_utime: doubletime(rusage.ru_utime),
29+
ru_stime: doubletime(rusage.ru_stime),
30+
ru_maxrss: rusage.ru_maxrss,
31+
ru_ixrss: rusage.ru_ixrss,
32+
ru_idrss: rusage.ru_idrss,
33+
ru_isrss: rusage.ru_isrss,
34+
ru_minflt: rusage.ru_minflt,
35+
ru_majflt: rusage.ru_majflt,
36+
ru_nswap: rusage.ru_nswap,
37+
ru_inblock: rusage.ru_inblock,
38+
ru_oublock: rusage.ru_oublock,
39+
ru_msgsnd: rusage.ru_msgsnd,
40+
ru_msgrcv: rusage.ru_msgrcv,
41+
ru_nsignals: rusage.ru_nsignals,
42+
ru_nvcsw: rusage.ru_nvcsw,
43+
ru_nivcsw: rusage.ru_nivcsw
44+
)

src/pylib/pyconfig/resource.nim

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
2+
import ./util
3+
4+
const SIZEOF_RLIMIT_T* = from_c_int(SIZEOF_RLIMIT_T, 8):
5+
{.emit: """/*INCLUDESECTION*/
6+
#include <sys/resource.h>
7+
#define SIZEOF_RLIMIT_T sizeof(rlim_t)
8+
""".}
9+
10+
AC_LINK_IFELSE HAVE_PRLIMIT, false:
11+
import std/posix
12+
proc prlimit(pid: Pid, resource: cint, new_limit, old_limit: ptr RLimit): cint {.
13+
importc, header: "<sys/resource.h>".}
14+
discard prlimit(0, 0, nil, nil)
15+
16+
AC_LINK_IFELSE HAVE_GETPAGESIZE, false:
17+
proc getpagesize(): cint {.importc, header: "<unistd.h>".}
18+
discard getpagesize()
19+
20+
AC_LINK_IFELSE HAVE_SYSCONF_PAGE_SIZE, false:
21+
let SC_PAGE_SIZE{.importc, header: "<unistd.h>".}: cint
22+
proc sysconf(name: cint): cint {.importc, header: "<unistd.h>".}
23+
discard sysconf(SC_PAGE_SIZE)

0 commit comments

Comments
 (0)