diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2013-04-04 15:28:24 +0400 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2013-04-04 15:28:24 +0400 |
commit | 5a9640162ae63c5ac5b993fea8880a12980c1a32 (patch) | |
tree | 0699f4aa8a8982be924834520c32ebac2dd8d420 | |
parent | e09fc3f884867953a2125ffaa47c719d770038ef (diff) |
* 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.
-rw-r--r-- | winsup/cygwin/ChangeLog.64bit | 15 | ||||
-rw-r--r-- | winsup/cygwin/cygheap.cc | 31 | ||||
-rw-r--r-- | 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 <corinna@vinschen.de> + + * 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 Алексей Павлов <alexpux@gmail.com> * 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]; |