1
0
mirror of https://git.FreeBSD.org/ports.git synced 2024-10-19 19:59:43 +00:00

Unbreak py-psyco: fix a problem with anonymous mmaps.

PR:		ports/69865
Submitted by:	myself
Approved by:	maintainer
Obtained from:	Armin Rigo (author)
This commit is contained in:
Thierry Thomas 2004-08-02 17:49:14 +00:00
parent 5b89556265
commit 441e117ec9
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=115285
2 changed files with 86 additions and 0 deletions

View File

@ -7,6 +7,7 @@
PORTNAME= psyco
PORTVERSION= 1.2
PORTREVISION= 1
CATEGORIES= devel python
MASTER_SITES= ${MASTER_SITE_SOURCEFORGE}
MASTER_SITE_SUBDIR= psyco

View File

@ -0,0 +1,85 @@
--- c/codemanager.c.orig Tue Dec 2 17:46:39 2003
+++ c/codemanager.c Sun Aug 1 08:41:16 2004
@@ -2,21 +2,12 @@
#include <ipyencoding.h>
/*** Allocators for Large Executable Blocks of Memory ***/
-/* Defaults, possibly overridden below */
-#define LEBM_WITH_MMAP 0 /* assume memory executable by default */
-#define LEBM_NUM_BIGBLOCKS 1 /* not too large blocks */
#ifndef MS_WINDOWS
/* Assume UNIX */
# include <sys/mman.h>
-# if defined(MAP_ANONYMOUS) || defined(MAP_ANON)
-# undef LEBM_WITH_MMAP
-# undef LEBM_NUM_BIGBLOCKS
-# define LEBM_WITH_MMAP 1 /* use mmap() with PROT_EXEC */
-# define LEBM_NUM_BIGBLOCKS 32 /* ask for 32MB at a time */
-# ifndef MAP_ANONYMOUS
-# define MAP_ANONYMOUS MAP_ANON
-# endif
+# if defined(MAP_ANON) && !defined(MAP_ANONYMOUS)
+# define MAP_ANONYMOUS MAP_ANON
# endif
#endif
@@ -42,22 +33,44 @@
static void allocate_more_buffers(codemanager_buf_t** bb)
{
- char* p;
- int i;
-
-#if LEBM_WITH_MMAP
- p = (char*) mmap(NULL, BIG_BUFFER_SIZE * LEBM_NUM_BIGBLOCKS,
- PROT_EXEC|PROT_READ|PROT_WRITE,
- MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
- if (p == MAP_FAILED)
- OUT_OF_MEMORY();
-#else
- p = (char*) PyMem_MALLOC(BIG_BUFFER_SIZE * LEBM_NUM_BIGBLOCKS);
- if (!p)
- OUT_OF_MEMORY();
+ char* p = NULL;
+ int num_bigblocks = 1;
+
+#if defined(MAP_ANONYMOUS) && defined(MAP_PRIVATE)
+ /* if we have anonymous mmap's, try using that -- this is known
+ to fail on some platforms */
+ static int mmap_works = -1;
+ if (mmap_works != 0)
+ {
+ num_bigblocks = 32; /* allocate 32MB at a time */
+ p = (char*) mmap(NULL, BIG_BUFFER_SIZE * num_bigblocks,
+ PROT_EXEC|PROT_READ|PROT_WRITE,
+ MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+ if (p == MAP_FAILED || p == NULL)
+ {
+ if (mmap_works == 1)
+ OUT_OF_MEMORY();
+ mmap_works = 0; /* doesn't work */
+ p = NULL;
+ num_bigblocks = 1;
+ /* note that some platforms *require* the allocation to be performed
+ by mmap, because PyMem_MALLOC() doesn't set the PROT_EXEC flag.
+ On these platforms we just hope that the first allocation is
+ successful, which sets mmap_works to 1; a failure in a subsequent
+ allocation correctly signals the OUT_OF_MEMORY. */
+ }
+ else
+ mmap_works = 1;
+ }
#endif
- for (i=0; i<LEBM_NUM_BIGBLOCKS; i++)
+ if (p == NULL)
+ {
+ p = (char*) PyMem_MALLOC(BIG_BUFFER_SIZE);
+ if (p == NULL)
+ OUT_OF_MEMORY();
+ }
+ while (--num_bigblocks >= 0)
{
/* the codemanager_buf_t structure is put at the end of the buffer,
with its signature to detect overflows (just in case) */