@@ -708,11 +708,54 @@ mmap__sizeof__method(mmap_object *self, void *unused)
708708}
709709#endif
710710
711+ #ifdef HAVE_MADVISE
712+ static PyObject *
713+ mmap_madvise_method (mmap_object * self , PyObject * args )
714+ {
715+ int option ;
716+ Py_ssize_t start = 0 , length ;
717+
718+ CHECK_VALID (NULL );
719+ length = self -> size ;
720+
721+ if (!PyArg_ParseTuple (args , "i|nn:madvise" , & option , & start , & length )) {
722+ return NULL ;
723+ }
724+
725+ if (start < 0 || start >= self -> size ) {
726+ PyErr_SetString (PyExc_ValueError , "madvise start out of bounds" );
727+ return NULL ;
728+ }
729+ if (length < 0 ) {
730+ PyErr_SetString (PyExc_ValueError , "madvise length invalid" );
731+ return NULL ;
732+ }
733+ if (PY_SSIZE_T_MAX - start < length ) {
734+ PyErr_SetString (PyExc_OverflowError , "madvise length too large" );
735+ return NULL ;
736+ }
737+
738+ if (start + length > self -> size ) {
739+ length = self -> size - start ;
740+ }
741+
742+ if (madvise (self -> data + start , length , option ) != 0 ) {
743+ PyErr_SetFromErrno (PyExc_OSError );
744+ return NULL ;
745+ }
746+
747+ Py_RETURN_NONE ;
748+ }
749+ #endif // HAVE_MADVISE
750+
711751static struct PyMethodDef mmap_object_methods [] = {
712752 {"close" , (PyCFunction ) mmap_close_method , METH_NOARGS },
713753 {"find" , (PyCFunction ) mmap_find_method , METH_VARARGS },
714754 {"rfind" , (PyCFunction ) mmap_rfind_method , METH_VARARGS },
715755 {"flush" , (PyCFunction ) mmap_flush_method , METH_VARARGS },
756+ #ifdef HAVE_MADVISE
757+ {"madvise" , (PyCFunction ) mmap_madvise_method , METH_VARARGS },
758+ #endif
716759 {"move" , (PyCFunction ) mmap_move_method , METH_VARARGS },
717760 {"read" , (PyCFunction ) mmap_read_method , METH_VARARGS },
718761 {"read_byte" , (PyCFunction ) mmap_read_byte_method , METH_NOARGS },
@@ -1494,5 +1537,80 @@ PyInit_mmap(void)
14941537 setint (dict , "ACCESS_READ" , ACCESS_READ );
14951538 setint (dict , "ACCESS_WRITE" , ACCESS_WRITE );
14961539 setint (dict , "ACCESS_COPY" , ACCESS_COPY );
1540+
1541+ #ifdef HAVE_MADVISE
1542+ // Conventional advice values
1543+ #ifdef MADV_NORMAL
1544+ setint (dict , "MADV_NORMAL" , MADV_NORMAL );
1545+ #endif
1546+ #ifdef MADV_RANDOM
1547+ setint (dict , "MADV_RANDOM" , MADV_RANDOM );
1548+ #endif
1549+ #ifdef MADV_SEQUENTIAL
1550+ setint (dict , "MADV_SEQUENTIAL" , MADV_SEQUENTIAL );
1551+ #endif
1552+ #ifdef MADV_WILLNEED
1553+ setint (dict , "MADV_WILLNEED" , MADV_WILLNEED );
1554+ #endif
1555+ #ifdef MADV_DONTNEED
1556+ setint (dict , "MADV_DONTNEED" , MADV_DONTNEED );
1557+ #endif
1558+
1559+ // Linux-specific advice values
1560+ #ifdef MADV_REMOVE
1561+ setint (dict , "MADV_REMOVE" , MADV_REMOVE );
1562+ #endif
1563+ #ifdef MADV_DONTFORK
1564+ setint (dict , "MADV_DONTFORK" , MADV_DONTFORK );
1565+ #endif
1566+ #ifdef MADV_DOFORK
1567+ setint (dict , "MADV_DOFORK" , MADV_DOFORK );
1568+ #endif
1569+ #ifdef MADV_HWPOISON
1570+ setint (dict , "MADV_HWPOISON" , MADV_HWPOISON );
1571+ #endif
1572+ #ifdef MADV_MERGEABLE
1573+ setint (dict , "MADV_MERGEABLE" , MADV_MERGEABLE );
1574+ #endif
1575+ #ifdef MADV_UNMERGEABLE
1576+ setint (dict , "MADV_UNMERGEABLE" , MADV_UNMERGEABLE );
1577+ #endif
1578+ #ifdef MADV_SOFT_OFFLINE
1579+ setint (dict , "MADV_SOFT_OFFLINE" , MADV_SOFT_OFFLINE );
1580+ #endif
1581+ #ifdef MADV_HUGEPAGE
1582+ setint (dict , "MADV_HUGEPAGE" , MADV_HUGEPAGE );
1583+ #endif
1584+ #ifdef MADV_NOHUGEPAGE
1585+ setint (dict , "MADV_NOHUGEPAGE" , MADV_NOHUGEPAGE );
1586+ #endif
1587+ #ifdef MADV_DONTDUMP
1588+ setint (dict , "MADV_DONTDUMP" , MADV_DONTDUMP );
1589+ #endif
1590+ #ifdef MADV_DODUMP
1591+ setint (dict , "MADV_DODUMP" , MADV_DODUMP );
1592+ #endif
1593+ #ifdef MADV_FREE // (Also present on FreeBSD and macOS.)
1594+ setint (dict , "MADV_FREE" , MADV_FREE );
1595+ #endif
1596+
1597+ // FreeBSD-specific
1598+ #ifdef MADV_NOSYNC
1599+ setint (dict , "MADV_NOSYNC" , MADV_NOSYNC );
1600+ #endif
1601+ #ifdef MADV_AUTOSYNC
1602+ setint (dict , "MADV_AUTOSYNC" , MADV_AUTOSYNC );
1603+ #endif
1604+ #ifdef MADV_NOCORE
1605+ setint (dict , "MADV_NOCORE" , MADV_NOCORE );
1606+ #endif
1607+ #ifdef MADV_CORE
1608+ setint (dict , "MADV_CORE" , MADV_CORE );
1609+ #endif
1610+ #ifdef MADV_PROTECT
1611+ setint (dict , "MADV_PROTECT" , MADV_PROTECT );
1612+ #endif
1613+ #endif // HAVE_MADVISE
1614+
14971615 return module ;
14981616}
0 commit comments