mercurial/cext/osutil.c
changeset 51738 b619ba39d10a
parent 49275 c6a3243567b6
equal deleted inserted replaced
51737:d748fd2647f8 51738:b619ba39d10a
    33 #ifdef HAVE_BSD_STATFS
    33 #ifdef HAVE_BSD_STATFS
    34 #include <sys/mount.h>
    34 #include <sys/mount.h>
    35 #include <sys/param.h>
    35 #include <sys/param.h>
    36 #endif
    36 #endif
    37 #endif
    37 #endif
       
    38 
       
    39 #ifndef _WIN32
       
    40 #include <sys/mman.h>
       
    41 #include <pthread.h>
       
    42 #endif
       
    43 
    38 
    44 
    39 #ifdef __APPLE__
    45 #ifdef __APPLE__
    40 #include <sys/attr.h>
    46 #include <sys/attr.h>
    41 #include <sys/vnode.h>
    47 #include <sys/vnode.h>
    42 #endif
    48 #endif
  1201 		Py_RETURN_FALSE;
  1207 		Py_RETURN_FALSE;
  1202 	}
  1208 	}
  1203 }
  1209 }
  1204 #endif
  1210 #endif
  1205 
  1211 
       
  1212 #ifdef MADV_POPULATE_READ
       
  1213 
       
  1214 typedef struct {
       
  1215     void * mmap_address;
       
  1216     size_t length;
       
  1217 } mmap_info;
       
  1218 
       
  1219 static void _mmap_populate(mmap_info *info) {
       
  1220     /* We explicitly does not check the return value as we don't care about it.
       
  1221      * the madvise is here to help performance and we don't care if it fails
       
  1222      * (for example because the mapping is no longer valid) */
       
  1223     void * mmap_address = info->mmap_address;
       
  1224     size_t length = info->length;
       
  1225     free(info);
       
  1226     madvise(mmap_address, length, MADV_POPULATE_READ);
       
  1227 }
       
  1228 
       
  1229 static PyObject *background_mmap_populate(PyObject *self, PyObject *mmap) {
       
  1230     Py_buffer b;
       
  1231     pthread_t thread_id;
       
  1232     mmap_info *info;
       
  1233     if (PyObject_GetBuffer(mmap, &b, PyBUF_CONTIG_RO | PyBUF_C_CONTIGUOUS) == -1) {
       
  1234         return NULL;
       
  1235     }
       
  1236     info = (mmap_info *)malloc(sizeof(mmap_info));
       
  1237     info->mmap_address=b.buf;
       
  1238     info->length=b.len;
       
  1239     /* note: for very large map, we could spin multiple thread populating
       
  1240      * different area */
       
  1241     pthread_create(&thread_id, NULL, (void *) &_mmap_populate, info);
       
  1242     /* We don't keep track of this thread as it is fine for it to die when we
       
  1243      * exit. */
       
  1244     pthread_detach(thread_id);
       
  1245     /* We release the PyBuffer in the main thread to let the object be garbage
       
  1246      * collected as soon as possible. This might result in the memory map being
       
  1247      * closed while the background thread is working. That will result in a
       
  1248      * error in the background thread we can ignore. */
       
  1249     PyBuffer_Release(&b);
       
  1250 	Py_RETURN_NONE;
       
  1251 }
       
  1252 
       
  1253 #endif
       
  1254 
  1206 static char osutil_doc[] = "Native operating system services.";
  1255 static char osutil_doc[] = "Native operating system services.";
  1207 
  1256 
  1208 static PyMethodDef methods[] = {
  1257 static PyMethodDef methods[] = {
  1209 	{"listdir", (PyCFunction)listdir, METH_VARARGS | METH_KEYWORDS,
  1258 	{"listdir", (PyCFunction)listdir, METH_VARARGS | METH_KEYWORDS,
  1210 	 "list a directory\n"},
  1259 	 "list a directory\n"},
  1235 	{
  1284 	{
  1236 		"isgui", (PyCFunction)isgui, METH_NOARGS,
  1285 		"isgui", (PyCFunction)isgui, METH_NOARGS,
  1237 		"Is a CoreGraphics session available?"
  1286 		"Is a CoreGraphics session available?"
  1238 	},
  1287 	},
  1239 #endif
  1288 #endif
       
  1289 #ifdef MADV_POPULATE_READ
       
  1290 	{"background_mmap_populate", (PyCFunction)background_mmap_populate, METH_O,
       
  1291 	 "populate a mmap in the background\n"},
       
  1292 #endif
  1240 	{NULL, NULL}
  1293 	{NULL, NULL}
  1241 };
  1294 };
  1242 
  1295 
  1243 static const int version = 4;
  1296 static const int version = 4;
  1244 
  1297