From 5a9640162ae63c5ac5b993fea8880a12980c1a32 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Thu, 4 Apr 2013 11:28:24 +0000 Subject: * cygheap.h (struct _cmalloc_entry): Define b as unsigned rather than DWORD. (NBUCKETS): Define here as constant value. (struct init_cygheap): Add bucket_val member. Define size of bucket_val and buckets using NBUCKETS. * cygheap.cc (NBUCKETS): Drop definition here. (cygheap_init): Initialize cygheap->bucket_val. Add comment to explain what we do and why. (_cmalloc): Simplify bit bucket search using cygheap->bucket_val. Drop local variable sz. Fetch size of block from cygheap->bucket_val. (_cfree): Define b as unsigned. (_crealloc): Fetch size of block from cygheap->bucket_val. --- winsup/cygwin/ChangeLog.64bit | 15 +++++++++++++++ winsup/cygwin/cygheap.cc | 31 ++++++++++++++++++++++++------- winsup/cygwin/cygheap.h | 7 +++++-- 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/winsup/cygwin/ChangeLog.64bit b/winsup/cygwin/ChangeLog.64bit index b8ee5fc9d..5dd2adac6 100644 --- a/winsup/cygwin/ChangeLog.64bit +++ b/winsup/cygwin/ChangeLog.64bit @@ -1,3 +1,18 @@ +2013-04-04 Corinna Vinschen + + * cygheap.h (struct _cmalloc_entry): Define b as unsigned rather than + DWORD. + (NBUCKETS): Define here as constant value. + (struct init_cygheap): Add bucket_val member. Define size of bucket_val + and buckets using NBUCKETS. + * cygheap.cc (NBUCKETS): Drop definition here. + (cygheap_init): Initialize cygheap->bucket_val. Add comment to explain + what we do and why. + (_cmalloc): Simplify bit bucket search using cygheap->bucket_val. Drop + local variable sz. Fetch size of block from cygheap->bucket_val. + (_cfree): Define b as unsigned. + (_crealloc): Fetch size of block from cygheap->bucket_val. + 2013-04-02 Алексей Павлов * fhandler_disk_file.cc (fhandler_disk_file::ftruncate): Add missed diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc index 6b068008f..5d41e18c6 100644 --- a/winsup/cygwin/cygheap.cc +++ b/winsup/cygwin/cygheap.cc @@ -65,7 +65,6 @@ static NO_COPY uint32_t nthreads; #define THREADLIST_CHUNK 256 -#define NBUCKETS (sizeof (cygheap->buckets) / sizeof (cygheap->buckets[0])) #define to_cmalloc(s) ((_cmalloc_entry *) (((char *) (s)) - offsetof (_cmalloc_entry, data))) #define CFMAP_OPTIONS (SEC_RESERVE | PAGE_READWRITE) @@ -261,6 +260,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; @@ -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); diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h index bdc3a1144..bb2d20a3e 100644 --- a/winsup/cygwin/cygheap.h +++ b/winsup/cygwin/cygheap.h @@ -18,7 +18,7 @@ struct _cmalloc_entry { union { - DWORD b; + unsigned b; char *ptr; }; struct _cmalloc_entry *prev; @@ -365,10 +365,13 @@ struct mini_cygheap cygheap_locale locale; }; +#define NBUCKETS 40 + struct init_cygheap: public mini_cygheap { _cmalloc_entry *chain; - char *buckets[32]; + unsigned bucket_val[NBUCKETS]; + char *buckets[NBUCKETS]; WCHAR installation_root[PATH_MAX]; UNICODE_STRING installation_key; WCHAR installation_key_buf[18]; -- cgit v1.2.3