Staging
v0.5.1
https://github.com/python/cpython
Revision e977fae6b8c7423cb5dd7caaeff7e84dff72f4a3 authored by R. David Murray on 21 November 2010, 16:59:54 UTC, committed by R. David Murray on 21 November 2010, 16:59:54 UTC
........
  r86642 | r.david.murray | 2010-11-21 11:53:48 -0500 (Sun, 21 Nov 2010) | 10 lines

  Fix TestBytesGeneratorIdempotent tests and a couple bugs they revealed.

  The tests that were failing on (some) windows machines, where the
  msg_XX.txt files used native \r\n lineseps are now also run on machines
  that use \n natively, and conversely the \n tests are run on Windows.
  The failing tests revealed one place where linesep needed to be added
  to a flatten call in generator.  There was also another that the tests
  didn't catch, so I added a test for that case as well.
........
1 parent 19f2aeb
Raw File
Tip revision: e977fae6b8c7423cb5dd7caaeff7e84dff72f4a3 authored by R. David Murray on 21 November 2010, 16:59:54 UTC
Blocked revisions 86642 via svnmerge
Tip revision: e977fae
malloc_closure.c
#include <Python.h>
#include <ffi.h>
#ifdef MS_WIN32
#include <windows.h>
#else
#include <sys/mman.h>
#include <unistd.h>
# if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
#  define MAP_ANONYMOUS MAP_ANON
# endif
#endif
#include "ctypes.h"

/* BLOCKSIZE can be adjusted.  Larger blocksize will take a larger memory
   overhead, but allocate less blocks from the system.  It may be that some
   systems have a limit of how many mmap'd blocks can be open.
*/

#define BLOCKSIZE _pagesize

/* #define MALLOC_CLOSURE_DEBUG */ /* enable for some debugging output */

/******************************************************************/

typedef union _tagITEM {
    ffi_closure closure;
    union _tagITEM *next;
} ITEM;

static ITEM *free_list;
static int _pagesize;

static void more_core(void)
{
    ITEM *item;
    int count, i;

/* determine the pagesize */
#ifdef MS_WIN32
    if (!_pagesize) {
        SYSTEM_INFO systeminfo;
        GetSystemInfo(&systeminfo);
        _pagesize = systeminfo.dwPageSize;
    }
#else
    if (!_pagesize) {
#ifdef _SC_PAGESIZE
        _pagesize = sysconf(_SC_PAGESIZE);
#else
        _pagesize = getpagesize();
#endif
    }
#endif

    /* calculate the number of nodes to allocate */
    count = BLOCKSIZE / sizeof(ITEM);

    /* allocate a memory block */
#ifdef MS_WIN32
    item = (ITEM *)VirtualAlloc(NULL,
                                           count * sizeof(ITEM),
                                           MEM_COMMIT,
                                           PAGE_EXECUTE_READWRITE);
    if (item == NULL)
        return;
#else
    item = (ITEM *)mmap(NULL,
                        count * sizeof(ITEM),
                        PROT_READ | PROT_WRITE | PROT_EXEC,
                        MAP_PRIVATE | MAP_ANONYMOUS,
                        -1,
                        0);
    if (item == (void *)MAP_FAILED)
        return;
#endif

#ifdef MALLOC_CLOSURE_DEBUG
    printf("block at %p allocated (%d bytes), %d ITEMs\n",
           item, count * sizeof(ITEM), count);
#endif
    /* put them into the free list */
    for (i = 0; i < count; ++i) {
        item->next = free_list;
        free_list = item;
        ++item;
    }
}

/******************************************************************/

/* put the item back into the free list */
void _ctypes_free_closure(void *p)
{
    ITEM *item = (ITEM *)p;
    item->next = free_list;
    free_list = item;
}

/* return one item from the free list, allocating more if needed */
void *_ctypes_alloc_closure(void)
{
    ITEM *item;
    if (!free_list)
        more_core();
    if (!free_list)
        return NULL;
    item = free_list;
    free_list = item->next;
    return item;
}
back to top