resource.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. """http://docs.python.org/library/resource"""
  2. from _resource_cffi import ffi, lib
  3. from errno import EINVAL, EPERM
  4. import _structseq, os
  5. try: from __pypy__ import builtinify
  6. except ImportError: builtinify = lambda f: f
  7. class error(Exception):
  8. pass
  9. class struct_rusage(metaclass=_structseq.structseqtype):
  10. """struct_rusage: Result from getrusage.
  11. This object may be accessed either as a tuple of
  12. (utime,stime,maxrss,ixrss,idrss,isrss,minflt,majflt,
  13. nswap,inblock,oublock,msgsnd,msgrcv,nsignals,nvcsw,nivcsw)
  14. or via the attributes ru_utime, ru_stime, ru_maxrss, and so on."""
  15. __metaclass__ = _structseq.structseqtype
  16. name = "resource.struct_rusage"
  17. ru_utime = _structseq.structseqfield(0, "user time used")
  18. ru_stime = _structseq.structseqfield(1, "system time used")
  19. ru_maxrss = _structseq.structseqfield(2, "max. resident set size")
  20. ru_ixrss = _structseq.structseqfield(3, "shared memory size")
  21. ru_idrss = _structseq.structseqfield(4, "unshared data size")
  22. ru_isrss = _structseq.structseqfield(5, "unshared stack size")
  23. ru_minflt = _structseq.structseqfield(6, "page faults not requiring I/O")
  24. ru_majflt = _structseq.structseqfield(7, "page faults requiring I/O")
  25. ru_nswap = _structseq.structseqfield(8, "number of swap outs")
  26. ru_inblock = _structseq.structseqfield(9, "block input operations")
  27. ru_oublock = _structseq.structseqfield(10, "block output operations")
  28. ru_msgsnd = _structseq.structseqfield(11, "IPC messages sent")
  29. ru_msgrcv = _structseq.structseqfield(12, "IPC messages received")
  30. ru_nsignals = _structseq.structseqfield(13,"signals received")
  31. ru_nvcsw = _structseq.structseqfield(14, "voluntary context switches")
  32. ru_nivcsw = _structseq.structseqfield(15, "involuntary context switches")
  33. def _make_struct_rusage(ru):
  34. return struct_rusage((
  35. lib.my_utime(ru),
  36. lib.my_stime(ru),
  37. ru.ru_maxrss,
  38. ru.ru_ixrss,
  39. ru.ru_idrss,
  40. ru.ru_isrss,
  41. ru.ru_minflt,
  42. ru.ru_majflt,
  43. ru.ru_nswap,
  44. ru.ru_inblock,
  45. ru.ru_oublock,
  46. ru.ru_msgsnd,
  47. ru.ru_msgrcv,
  48. ru.ru_nsignals,
  49. ru.ru_nvcsw,
  50. ru.ru_nivcsw,
  51. ))
  52. @builtinify
  53. def getrusage(who):
  54. ru = ffi.new("struct rusage *")
  55. if lib.getrusage(who, ru) == -1:
  56. if ffi.errno == EINVAL:
  57. raise ValueError("invalid who parameter")
  58. raise error(ffi.errno)
  59. return _make_struct_rusage(ru)
  60. @builtinify
  61. def getrlimit(resource):
  62. if not (0 <= resource < lib.RLIM_NLIMITS):
  63. return ValueError("invalid resource specified")
  64. result = ffi.new("long long[2]")
  65. if lib.my_getrlimit(resource, result) == -1:
  66. raise error(ffi.errno)
  67. return (result[0], result[1])
  68. @builtinify
  69. def setrlimit(resource, limits):
  70. if not (0 <= resource < lib.RLIM_NLIMITS):
  71. return ValueError("invalid resource specified")
  72. limits = tuple(limits)
  73. if len(limits) != 2:
  74. raise ValueError("expected a tuple of 2 integers")
  75. # accept and round down floats, like CPython does
  76. limit0 = int(limits[0])
  77. limit1 = int(limits[1])
  78. if lib.my_setrlimit(resource, limit0, limit1) == -1:
  79. if ffi.errno == EINVAL:
  80. raise ValueError("current limit exceeds maximum limit")
  81. elif ffi.errno == EPERM:
  82. raise ValueError("not allowed to raise maximum limit")
  83. else:
  84. raise error(ffi.errno)
  85. @builtinify
  86. def getpagesize():
  87. return os.sysconf("SC_PAGESIZE")
  88. def _setup():
  89. all_constants = []
  90. p = lib.my_rlimit_consts
  91. while p.name:
  92. name = ffi.string(p.name).decode()
  93. globals()[name] = int(p.value)
  94. all_constants.append(name)
  95. p += 1
  96. return all_constants
  97. __all__ = tuple(_setup()) + (
  98. 'error', 'getpagesize', 'struct_rusage',
  99. 'getrusage', 'getrlimit', 'setrlimit',
  100. )
  101. del _setup