22
33#include <stddef.h>
44
5+ #if defined(__APPLE__ )
6+ # include <TargetConditionals.h>
7+ // Older macOS SDKs do not define TARGET_OS_OSX
8+ # if !defined(TARGET_OS_OSX )
9+ # define TARGET_OS_OSX 1
10+ # endif
11+ # if TARGET_OS_OSX
12+ # include <errno.h> // errno, ESRCH
13+ # include <libproc.h> // proc_pidinfo(), PROC_PIDTASKINFO
14+ # include <sys/proc_info.h> // struct proc_taskinfo
15+ # endif
16+ #endif
17+
518#ifdef __FreeBSD__
619# include <fcntl.h> // O_RDONLY
720# include <kvm.h> // kvm_openfiles()
@@ -693,7 +706,7 @@ tracemalloc_track_race(PyObject *self, PyObject *args)
693706}
694707
695708
696- #ifdef __FreeBSD__
709+ #if TARGET_OS_OSX || defined( __FreeBSD__ )
697710// Return RSS only. Per-process swap usage isn't readily available
698711static PyObject *
699712get_process_memory_usage (PyObject * self , PyObject * args )
@@ -703,6 +716,22 @@ get_process_memory_usage(PyObject *self, PyObject *args)
703716 return NULL ;
704717 }
705718
719+ #if TARGET_OS_OSX
720+ // macOS: proc_pidinfo(PROC_PIDTASKINFO).pti_resident_size
721+ struct proc_taskinfo pti ;
722+ int ret = proc_pidinfo (pid , PROC_PIDTASKINFO , 0 , & pti , sizeof (pti ));
723+ if (ret <= 0 ) {
724+ if (errno == 0 ) {
725+ // proc_pidinfo() can return 0 without setting errno when the
726+ // process does not exist.
727+ errno = ESRCH ;
728+ }
729+ return PyErr_SetFromErrno (PyExc_OSError );
730+ }
731+
732+ return PyLong_FromUnsignedLongLong (pti .pti_resident_size );
733+ #else
734+ // FreeBSD: kvm_getprocs(KERN_PROC_PID) and ki_rssize * page_size
706735 long page_size = sysconf (_SC_PAGESIZE );
707736 if (page_size <= 0 ) {
708737 return PyErr_SetFromErrno (PyExc_OSError );
@@ -740,6 +769,7 @@ get_process_memory_usage(PyObject *self, PyObject *args)
740769error :
741770 kvm_close (kd );
742771 return NULL ;
772+ #endif
743773}
744774#endif
745775
@@ -758,7 +788,7 @@ static PyMethodDef test_methods[] = {
758788 {"test_pymem_setrawallocators" , test_pymem_setrawallocators , METH_NOARGS },
759789 {"test_pyobject_new" , test_pyobject_new , METH_NOARGS },
760790 {"test_pyobject_setallocators" , test_pyobject_setallocators , METH_NOARGS },
761- #ifdef __FreeBSD__
791+ #if TARGET_OS_OSX || defined ( __FreeBSD__ )
762792 {"get_process_memory_usage" , get_process_memory_usage , METH_VARARGS },
763793#endif
764794
0 commit comments