* Merge in cygwin-64bit-branch.

This commit is contained in:
Corinna Vinschen
2013-04-23 09:44:36 +00:00
parent 1875ee55d3
commit 61522196c7
253 changed files with 10632 additions and 5055 deletions

View File

@@ -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;
}
}