* Merge in cygwin-64bit-branch.
This commit is contained in:
@@ -27,6 +27,7 @@
|
||||
#include "ntdll.h"
|
||||
#include <unistd.h>
|
||||
#include <wchar.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
static mini_cygheap NO_COPY cygheap_dummy =
|
||||
{
|
||||
@@ -60,13 +61,11 @@ public:
|
||||
};
|
||||
|
||||
muto NO_COPY tls_sentry::lock;
|
||||
static NO_COPY size_t nthreads;
|
||||
static NO_COPY uint32_t nthreads;
|
||||
|
||||
#define THREADLIST_CHUNK 256
|
||||
|
||||
#define NBUCKETS (sizeof (cygheap->buckets) / sizeof (cygheap->buckets[0]))
|
||||
#define N0 ((_cmalloc_entry *) NULL)
|
||||
#define to_cmalloc(s) ((_cmalloc_entry *) (((char *) (s)) - (unsigned) (N0->data)))
|
||||
#define to_cmalloc(s) ((_cmalloc_entry *) (((char *) (s)) - offsetof (_cmalloc_entry, data)))
|
||||
|
||||
#define CFMAP_OPTIONS (SEC_RESERVE | PAGE_READWRITE)
|
||||
#define MVMAP_OPTIONS (FILE_MAP_WRITE)
|
||||
@@ -116,47 +115,6 @@ init_cygheap::close_ctty ()
|
||||
cygheap->ctty = NULL;
|
||||
}
|
||||
|
||||
#define nextpage(x) ((char *) (((DWORD) ((char *) x + granmask)) & ~granmask))
|
||||
#define allocsize(x) ((DWORD) nextpage (x))
|
||||
#ifdef DEBUGGING
|
||||
#define somekinda_printf debug_printf
|
||||
#else
|
||||
#define somekinda_printf malloc_printf
|
||||
#endif
|
||||
|
||||
static void *__stdcall
|
||||
_csbrk (int sbs)
|
||||
{
|
||||
void *prebrk = cygheap_max;
|
||||
size_t granmask = wincap.allocation_granularity () - 1;
|
||||
char *newbase = nextpage (prebrk);
|
||||
cygheap_max = (char *) cygheap_max + sbs;
|
||||
if (!sbs || (newbase >= cygheap_max) || (cygheap_max <= _cygheap_end))
|
||||
/* nothing to do */;
|
||||
else
|
||||
{
|
||||
if (prebrk <= _cygheap_end)
|
||||
newbase = _cygheap_end;
|
||||
|
||||
DWORD adjsbs = allocsize ((char *) cygheap_max - newbase);
|
||||
if (adjsbs && !VirtualAlloc (newbase, adjsbs, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE))
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION m;
|
||||
if (!VirtualQuery (newbase, &m, sizeof m))
|
||||
system_printf ("couldn't get memory info, %E");
|
||||
somekinda_printf ("Couldn't reserve/commit %d bytes of space for cygwin's heap, %E",
|
||||
adjsbs);
|
||||
somekinda_printf ("AllocationBase %p, BaseAddress %p, RegionSize %p, State %p\n",
|
||||
m.AllocationBase, m.BaseAddress, m.RegionSize, m.State);
|
||||
__seterrno ();
|
||||
cygheap_max = (char *) cygheap_max - sbs;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return prebrk;
|
||||
}
|
||||
|
||||
/* Use absolute path of cygwin1.dll to derive the Win32 dir which
|
||||
is our installation_root. Note that we can't handle Cygwin installation
|
||||
root dirs of more than 4K path length. I assume that's ok...
|
||||
@@ -261,6 +219,21 @@ cygheap_init ()
|
||||
sizeof (*cygheap));
|
||||
cygheap_max = cygheap;
|
||||
_csbrk (sizeof (*cygheap));
|
||||
/* Initialize bucket_val. The value is the max size of a block
|
||||
fitting into the bucket. The values are powers of two and their
|
||||
medians: 12, 16, 24, 32, 48, 64, ... On 64 bit, start with 24 to
|
||||
accommodate bigger size of struct cygheap_entry.
|
||||
With NBUCKETS == 40, the maximum block size is 6291456/12582912.
|
||||
The idea is to have better matching bucket sizes (not wasting
|
||||
space) without trading in performance compared to the old powers
|
||||
of 2 method. */
|
||||
#ifdef __x86_64__
|
||||
unsigned sz[2] = { 16, 24 }; /* sizeof cygheap_entry == 16 */
|
||||
#else
|
||||
unsigned sz[2] = { 8, 12 }; /* sizeof cygheap_entry == 8 */
|
||||
#endif
|
||||
for (unsigned b = 1; b < NBUCKETS; b++, sz[b & 1] <<= 1)
|
||||
cygheap->bucket_val[b] = sz[b & 1];
|
||||
/* Default locale settings. */
|
||||
cygheap->locale.mbtowc = __utf8_mbtowc;
|
||||
cygheap->locale.wctomb = __utf8_wctomb;
|
||||
@@ -276,6 +249,47 @@ cygheap_init ()
|
||||
cygheap->init_tls_list ();
|
||||
}
|
||||
|
||||
#define nextpage(x) ((char *) roundup2 ((uintptr_t) (x), \
|
||||
wincap.allocation_granularity ()))
|
||||
#define allocsize(x) ((SIZE_T) nextpage (x))
|
||||
#ifdef DEBUGGING
|
||||
#define somekinda_printf debug_printf
|
||||
#else
|
||||
#define somekinda_printf malloc_printf
|
||||
#endif
|
||||
|
||||
static void *__stdcall
|
||||
_csbrk (int sbs)
|
||||
{
|
||||
void *prebrk = cygheap_max;
|
||||
char *newbase = nextpage (prebrk);
|
||||
cygheap_max = (char *) cygheap_max + sbs;
|
||||
if (!sbs || (newbase >= cygheap_max) || (cygheap_max <= _cygheap_end))
|
||||
/* nothing to do */;
|
||||
else
|
||||
{
|
||||
if (prebrk <= _cygheap_end)
|
||||
newbase = _cygheap_end;
|
||||
|
||||
SIZE_T adjsbs = allocsize ((char *) cygheap_max - newbase);
|
||||
if (adjsbs && !VirtualAlloc (newbase, adjsbs, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE))
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION m;
|
||||
if (!VirtualQuery (newbase, &m, sizeof m))
|
||||
system_printf ("couldn't get memory info, %E");
|
||||
somekinda_printf ("Couldn't reserve/commit %ld bytes of space for cygwin's heap, %E",
|
||||
adjsbs);
|
||||
somekinda_printf ("AllocationBase %p, BaseAddress %p, RegionSize %lx, State %x\n",
|
||||
m.AllocationBase, m.BaseAddress, m.RegionSize, m.State);
|
||||
__seterrno ();
|
||||
cygheap_max = (char *) cygheap_max - sbs;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return prebrk;
|
||||
}
|
||||
|
||||
/* Copyright (C) 1997, 2000 DJ Delorie */
|
||||
|
||||
static void *__reg1 _cmalloc (unsigned size);
|
||||
@@ -285,11 +299,13 @@ static void *__reg1
|
||||
_cmalloc (unsigned size)
|
||||
{
|
||||
_cmalloc_entry *rvc;
|
||||
unsigned b, sz;
|
||||
unsigned b;
|
||||
|
||||
/* Calculate "bit bucket" and size as a power of two. */
|
||||
for (b = 3, sz = 8; sz && sz < size; b++, sz <<= 1)
|
||||
/* Calculate "bit bucket". */
|
||||
for (b = 1; b < NBUCKETS && cygheap->bucket_val[b] < size; b++)
|
||||
continue;
|
||||
if (b >= NBUCKETS)
|
||||
return NULL;
|
||||
|
||||
cygheap_protect.acquire ();
|
||||
if (cygheap->buckets[b])
|
||||
@@ -300,7 +316,8 @@ _cmalloc (unsigned size)
|
||||
}
|
||||
else
|
||||
{
|
||||
rvc = (_cmalloc_entry *) _csbrk (sz + sizeof (_cmalloc_entry));
|
||||
rvc = (_cmalloc_entry *) _csbrk (cygheap->bucket_val[b]
|
||||
+ sizeof (_cmalloc_entry));
|
||||
if (!rvc)
|
||||
{
|
||||
cygheap_protect.release ();
|
||||
@@ -320,7 +337,7 @@ _cfree (void *ptr)
|
||||
{
|
||||
cygheap_protect.acquire ();
|
||||
_cmalloc_entry *rvc = to_cmalloc (ptr);
|
||||
DWORD b = rvc->b;
|
||||
unsigned b = rvc->b;
|
||||
rvc->ptr = cygheap->buckets[b];
|
||||
cygheap->buckets[b] = (char *) rvc;
|
||||
cygheap_protect.release ();
|
||||
@@ -334,7 +351,7 @@ _crealloc (void *ptr, unsigned size)
|
||||
newptr = _cmalloc (size);
|
||||
else
|
||||
{
|
||||
unsigned oldsize = 1 << to_cmalloc (ptr)->b;
|
||||
unsigned oldsize = cygheap->bucket_val[to_cmalloc (ptr)->b];
|
||||
if (size <= oldsize)
|
||||
return ptr;
|
||||
newptr = _cmalloc (size);
|
||||
@@ -351,8 +368,7 @@ _crealloc (void *ptr, unsigned size)
|
||||
|
||||
#define sizeof_cygheap(n) ((n) + sizeof (cygheap_entry))
|
||||
|
||||
#define N ((cygheap_entry *) NULL)
|
||||
#define tocygheap(s) ((cygheap_entry *) (((char *) (s)) - (int) (N->data)))
|
||||
#define tocygheap(s) ((cygheap_entry *) (((char *) (s)) - offsetof (cygheap_entry, data)))
|
||||
|
||||
inline static void *
|
||||
creturn (cygheap_types x, cygheap_entry * c, unsigned len, const char *fn = NULL)
|
||||
@@ -600,12 +616,12 @@ init_cygheap::remove_tls (_cygtls *t, DWORD wait)
|
||||
tls_sentry here (wait);
|
||||
if (here.acquired ())
|
||||
{
|
||||
for (size_t i = 0; i < nthreads; i++)
|
||||
for (uint32_t i = 0; i < nthreads; i++)
|
||||
if (t == threadlist[i])
|
||||
{
|
||||
if (i < --nthreads)
|
||||
threadlist[i] = threadlist[nthreads];
|
||||
debug_only_printf ("removed %p element %d", this, i);
|
||||
debug_only_printf ("removed %p element %u", this, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user