diff options
Diffstat (limited to 'src/lib/libc')
| -rw-r--r-- | src/lib/libc/stdlib/malloc.c | 194 |
1 files changed, 136 insertions, 58 deletions
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c index e3405df39a..5a328b0eb0 100644 --- a/src/lib/libc/stdlib/malloc.c +++ b/src/lib/libc/stdlib/malloc.c | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | */ | 8 | */ |
| 9 | 9 | ||
| 10 | #if defined(LIBC_SCCS) && !defined(lint) | 10 | #if defined(LIBC_SCCS) && !defined(lint) |
| 11 | static char rcsid[] = "$OpenBSD: malloc.c,v 1.74 2005/06/07 04:42:42 tedu Exp $"; | 11 | static char rcsid[] = "$OpenBSD: malloc.c,v 1.75 2005/07/07 05:28:53 tdeval Exp $"; |
| 12 | #endif /* LIBC_SCCS and not lint */ | 12 | #endif /* LIBC_SCCS and not lint */ |
| 13 | 13 | ||
| 14 | /* | 14 | /* |
| @@ -142,8 +142,9 @@ struct pgfree { | |||
| 142 | /* A mask for the offset inside a page. */ | 142 | /* A mask for the offset inside a page. */ |
| 143 | #define malloc_pagemask ((malloc_pagesize)-1) | 143 | #define malloc_pagemask ((malloc_pagesize)-1) |
| 144 | 144 | ||
| 145 | #define pageround(foo) (((foo) + (malloc_pagemask)) & ~malloc_pagemask) | 145 | #define pageround(foo) (((foo) + (malloc_pagemask)) & ~malloc_pagemask) |
| 146 | #define ptr2index(foo) (((u_long)(foo) >> malloc_pageshift)+malloc_pageshift) | 146 | #define ptr2index(foo) (((u_long)(foo) >> malloc_pageshift)+malloc_pageshift) |
| 147 | #define index2ptr(idx) ((void*)(((idx)-malloc_pageshift)<<malloc_pageshift)) | ||
| 147 | 148 | ||
| 148 | /* fd of /dev/zero */ | 149 | /* fd of /dev/zero */ |
| 149 | #ifdef USE_DEV_ZERO | 150 | #ifdef USE_DEV_ZERO |
| @@ -211,6 +212,7 @@ static int malloc_freeprot; | |||
| 211 | 212 | ||
| 212 | /* use guard pages after allocations? */ | 213 | /* use guard pages after allocations? */ |
| 213 | static int malloc_guard = 0; | 214 | static int malloc_guard = 0; |
| 215 | static int malloc_guarded; | ||
| 214 | /* align pointers to end of page? */ | 216 | /* align pointers to end of page? */ |
| 215 | static int malloc_ptrguard; | 217 | static int malloc_ptrguard; |
| 216 | 218 | ||
| @@ -396,6 +398,7 @@ malloc_dump(FILE *fd) | |||
| 396 | fprintf(fd, "Pagesize\t%lu\n", (u_long)malloc_pagesize); | 398 | fprintf(fd, "Pagesize\t%lu\n", (u_long)malloc_pagesize); |
| 397 | fprintf(fd, "Pageshift\t%d\n", malloc_pageshift); | 399 | fprintf(fd, "Pageshift\t%d\n", malloc_pageshift); |
| 398 | fprintf(fd, "In use\t%lu\n", (u_long)malloc_used); | 400 | fprintf(fd, "In use\t%lu\n", (u_long)malloc_used); |
| 401 | fprintf(fd, "Guarded\t%lu\n", (u_long)malloc_guarded); | ||
| 399 | } | 402 | } |
| 400 | #endif /* MALLOC_STATS */ | 403 | #endif /* MALLOC_STATS */ |
| 401 | 404 | ||
| @@ -472,9 +475,9 @@ map_pages(size_t pages) | |||
| 472 | { | 475 | { |
| 473 | struct pdinfo *pi, *spi; | 476 | struct pdinfo *pi, *spi; |
| 474 | struct pginfo **pd; | 477 | struct pginfo **pd; |
| 475 | u_long pidx,lidx; | 478 | u_long idx, pidx, lidx; |
| 476 | void *result, *tail; | 479 | void *result, *tail; |
| 477 | u_long index; | 480 | u_long index, lindex; |
| 478 | 481 | ||
| 479 | pages <<= malloc_pageshift; | 482 | pages <<= malloc_pageshift; |
| 480 | result = MMAP(pages + malloc_guard); | 483 | result = MMAP(pages + malloc_guard); |
| @@ -485,23 +488,25 @@ map_pages(size_t pages) | |||
| 485 | #endif /* MALLOC_EXTRA_SANITY */ | 488 | #endif /* MALLOC_EXTRA_SANITY */ |
| 486 | return (NULL); | 489 | return (NULL); |
| 487 | } | 490 | } |
| 491 | index = ptr2index(result); | ||
| 488 | tail = result + pages + malloc_guard; | 492 | tail = result + pages + malloc_guard; |
| 493 | lindex = ptr2index(tail) - 1; | ||
| 489 | if (malloc_guard) | 494 | if (malloc_guard) |
| 490 | mprotect(result + pages, malloc_guard, PROT_NONE); | 495 | mprotect(result + pages, malloc_guard, PROT_NONE); |
| 491 | 496 | ||
| 492 | if (tail > malloc_brk) | 497 | pidx = PI_IDX(index); |
| 498 | lidx = PI_IDX(lindex); | ||
| 499 | |||
| 500 | if (tail > malloc_brk) { | ||
| 493 | malloc_brk = tail; | 501 | malloc_brk = tail; |
| 494 | if ((index = ptr2index(tail) - 1) > last_index) | 502 | last_index = lindex; |
| 495 | last_index = index; | 503 | } |
| 496 | 504 | ||
| 497 | /* Insert directory pages, if needed. */ | 505 | /* Insert directory pages, if needed. */ |
| 498 | pidx = PI_IDX(ptr2index(result)); | 506 | pdir_lookup(index, &pi); |
| 499 | lidx = PI_IDX(index); | ||
| 500 | |||
| 501 | pdir_lookup(ptr2index(result), &pi); | ||
| 502 | 507 | ||
| 503 | for (index=pidx,spi=pi;index<=lidx;index++) { | 508 | for (idx=pidx,spi=pi;idx<=lidx;idx++) { |
| 504 | if (pi == NULL || PD_IDX(pi->dirnum) != index) { | 509 | if (pi == NULL || PD_IDX(pi->dirnum) != idx) { |
| 505 | if ((pd = MMAP(malloc_pagesize)) == MAP_FAILED) { | 510 | if ((pd = MMAP(malloc_pagesize)) == MAP_FAILED) { |
| 506 | errno = ENOMEM; | 511 | errno = ENOMEM; |
| 507 | munmap(result, tail - result); | 512 | munmap(result, tail - result); |
| @@ -515,31 +520,31 @@ map_pages(size_t pages) | |||
| 515 | pi->base = pd; | 520 | pi->base = pd; |
| 516 | pi->prev = spi; | 521 | pi->prev = spi; |
| 517 | pi->next = spi->next; | 522 | pi->next = spi->next; |
| 518 | pi->dirnum = index * (malloc_pagesize/sizeof(struct pginfo *)); | 523 | pi->dirnum = idx * (malloc_pagesize/sizeof(struct pginfo *)); |
| 519 | 524 | ||
| 520 | if (spi->next != NULL) | 525 | if (spi->next != NULL) |
| 521 | spi->next->prev = pi; | 526 | spi->next->prev = pi; |
| 522 | spi->next = pi; | 527 | spi->next = pi; |
| 523 | } | 528 | } |
| 524 | if (index > pidx && index < lidx) { | 529 | if (idx > pidx && idx < lidx) { |
| 525 | pi->dirnum += pdi_mod; | 530 | pi->dirnum += pdi_mod; |
| 526 | } else if (index == pidx) { | 531 | } else if (idx == pidx) { |
| 527 | if (pidx == lidx) { | 532 | if (pidx == lidx) { |
| 528 | pi->dirnum += (tail - result) >> malloc_pageshift; | 533 | pi->dirnum += (tail - result) >> malloc_pageshift; |
| 529 | } else { | 534 | } else { |
| 530 | pi->dirnum += pdi_mod - PI_OFF(ptr2index(result)); | 535 | pi->dirnum += pdi_mod - PI_OFF(index); |
| 531 | } | 536 | } |
| 532 | } else { | 537 | } else { |
| 533 | pi->dirnum += PI_OFF(ptr2index(tail - 1)) + 1; | 538 | pi->dirnum += PI_OFF(ptr2index(tail - 1)) + 1; |
| 534 | } | 539 | } |
| 535 | #ifdef MALLOC_EXTRA_SANITY | 540 | #ifdef MALLOC_EXTRA_SANITY |
| 536 | if (PD_OFF(pi->dirnum) > pdi_mod || PD_IDX(pi->dirnum) > index) { | 541 | if (PD_OFF(pi->dirnum) > pdi_mod || PD_IDX(pi->dirnum) > idx) { |
| 537 | wrterror("(ES): pages directory overflow\n"); | 542 | wrterror("(ES): pages directory overflow\n"); |
| 538 | errno = EFAULT; | 543 | errno = EFAULT; |
| 539 | return (NULL); | 544 | return (NULL); |
| 540 | } | 545 | } |
| 541 | #endif /* MALLOC_EXTRA_SANITY */ | 546 | #endif /* MALLOC_EXTRA_SANITY */ |
| 542 | if (index == pidx && pi != last_dir) { | 547 | if (idx == pidx && pi != last_dir) { |
| 543 | prev_dir = last_dir; | 548 | prev_dir = last_dir; |
| 544 | last_dir = pi; | 549 | last_dir = pi; |
| 545 | } | 550 | } |
| @@ -852,6 +857,7 @@ malloc_pages(size_t size) | |||
| 852 | } | 857 | } |
| 853 | 858 | ||
| 854 | malloc_used += size << malloc_pageshift; | 859 | malloc_used += size << malloc_pageshift; |
| 860 | malloc_guarded += malloc_guard; | ||
| 855 | 861 | ||
| 856 | if (malloc_junk) | 862 | if (malloc_junk) |
| 857 | memset(p, SOME_JUNK, size << malloc_pageshift); | 863 | memset(p, SOME_JUNK, size << malloc_pageshift); |
| @@ -1065,11 +1071,11 @@ malloc_bytes(size_t size) | |||
| 1065 | } | 1071 | } |
| 1066 | 1072 | ||
| 1067 | /* | 1073 | /* |
| 1068 | * magic so that malloc(sizeof(ptr)) is near the end of the page. | 1074 | * Magic so that malloc(sizeof(ptr)) is near the end of the page. |
| 1069 | */ | 1075 | */ |
| 1070 | #define PTR_GAP (malloc_pagesize - sizeof(void *)) | 1076 | #define PTR_GAP (malloc_pagesize - sizeof(void *)) |
| 1071 | #define PTR_SIZE (sizeof(void *)) | 1077 | #define PTR_SIZE (sizeof(void *)) |
| 1072 | #define PTR_ALIGNED(p) (((unsigned long)p & malloc_pagemask) == PTR_GAP) | 1078 | #define PTR_ALIGNED(p) (((unsigned long)p & malloc_pagemask) == PTR_GAP) |
| 1073 | 1079 | ||
| 1074 | /* | 1080 | /* |
| 1075 | * Allocate a piece of memory | 1081 | * Allocate a piece of memory |
| @@ -1087,8 +1093,8 @@ imalloc(size_t size) | |||
| 1087 | abort(); | 1093 | abort(); |
| 1088 | 1094 | ||
| 1089 | if (malloc_ptrguard && size == PTR_SIZE) { | 1095 | if (malloc_ptrguard && size == PTR_SIZE) { |
| 1090 | ptralloc = 1; | 1096 | ptralloc = 1; |
| 1091 | size = malloc_pagesize; | 1097 | size = malloc_pagesize; |
| 1092 | } | 1098 | } |
| 1093 | 1099 | ||
| 1094 | if ((size + malloc_pagesize) < size) { /* Check for overflow */ | 1100 | if ((size + malloc_pagesize) < size) { /* Check for overflow */ |
| @@ -1107,7 +1113,7 @@ imalloc(size_t size) | |||
| 1107 | memset(result, 0, size); | 1113 | memset(result, 0, size); |
| 1108 | 1114 | ||
| 1109 | if (result && ptralloc) | 1115 | if (result && ptralloc) |
| 1110 | return ((char *)result + PTR_GAP); | 1116 | return ((char *)result + PTR_GAP); |
| 1111 | return (result); | 1117 | return (result); |
| 1112 | } | 1118 | } |
| 1113 | 1119 | ||
| @@ -1133,18 +1139,17 @@ irealloc(void *ptr, size_t size) | |||
| 1133 | } | 1139 | } |
| 1134 | 1140 | ||
| 1135 | if (malloc_ptrguard && PTR_ALIGNED(ptr)) { | 1141 | if (malloc_ptrguard && PTR_ALIGNED(ptr)) { |
| 1136 | if (size <= PTR_SIZE) | 1142 | if (size <= PTR_SIZE) { |
| 1137 | return (ptr); | 1143 | return (ptr); |
| 1138 | else { | 1144 | } else { |
| 1139 | p = imalloc(size); | 1145 | p = imalloc(size); |
| 1140 | if (p) | 1146 | if (p) |
| 1141 | memcpy(p, ptr, PTR_SIZE); | 1147 | memcpy(p, ptr, PTR_SIZE); |
| 1142 | ifree(ptr); | 1148 | ifree(ptr); |
| 1143 | return (p); | 1149 | return (p); |
| 1144 | } | 1150 | } |
| 1145 | } | 1151 | } |
| 1146 | 1152 | ||
| 1147 | |||
| 1148 | index = ptr2index(ptr); | 1153 | index = ptr2index(ptr); |
| 1149 | 1154 | ||
| 1150 | if (index < malloc_pageshift) { | 1155 | if (index < malloc_pageshift) { |
| @@ -1240,7 +1245,7 @@ irealloc(void *ptr, size_t size) | |||
| 1240 | } | 1245 | } |
| 1241 | 1246 | ||
| 1242 | } else { | 1247 | } else { |
| 1243 | wrtwarning("pointer to wrong page\n"); | 1248 | wrtwarning("irealloc: pointer to wrong page\n"); |
| 1244 | return (NULL); | 1249 | return (NULL); |
| 1245 | } | 1250 | } |
| 1246 | 1251 | ||
| @@ -1268,7 +1273,7 @@ irealloc(void *ptr, size_t size) | |||
| 1268 | static __inline__ void | 1273 | static __inline__ void |
| 1269 | free_pages(void *ptr, u_long index, struct pginfo *info) | 1274 | free_pages(void *ptr, u_long index, struct pginfo *info) |
| 1270 | { | 1275 | { |
| 1271 | u_long i, l; | 1276 | u_long i, l, cachesize = 0; |
| 1272 | struct pginfo **pd; | 1277 | struct pginfo **pd; |
| 1273 | struct pdinfo *pi, *spi; | 1278 | struct pdinfo *pi, *spi; |
| 1274 | u_long pidx, lidx; | 1279 | u_long pidx, lidx; |
| @@ -1281,7 +1286,7 @@ free_pages(void *ptr, u_long index, struct pginfo *info) | |||
| 1281 | } | 1286 | } |
| 1282 | 1287 | ||
| 1283 | if (info != MALLOC_FIRST) { | 1288 | if (info != MALLOC_FIRST) { |
| 1284 | wrtwarning("pointer to wrong page\n"); | 1289 | wrtwarning("free_pages: pointer to wrong page\n"); |
| 1285 | return; | 1290 | return; |
| 1286 | } | 1291 | } |
| 1287 | 1292 | ||
| @@ -1330,6 +1335,7 @@ free_pages(void *ptr, u_long index, struct pginfo *info) | |||
| 1330 | memset(ptr, SOME_JUNK, l); | 1335 | memset(ptr, SOME_JUNK, l); |
| 1331 | 1336 | ||
| 1332 | malloc_used -= l; | 1337 | malloc_used -= l; |
| 1338 | malloc_guarded -= malloc_guard; | ||
| 1333 | if (malloc_guard) { | 1339 | if (malloc_guard) { |
| 1334 | #ifdef MALLOC_EXTRA_SANITY | 1340 | #ifdef MALLOC_EXTRA_SANITY |
| 1335 | if (pi == NULL || PD_IDX(pi->dirnum) != PI_IDX(index+i)) { | 1341 | if (pi == NULL || PD_IDX(pi->dirnum) != PI_IDX(index+i)) { |
| @@ -1371,9 +1377,18 @@ free_pages(void *ptr, u_long index, struct pginfo *info) | |||
| 1371 | 1377 | ||
| 1372 | /* Find the right spot, leave pf pointing to the modified entry. */ | 1378 | /* Find the right spot, leave pf pointing to the modified entry. */ |
| 1373 | 1379 | ||
| 1374 | for(pf = free_list.next; (pf->page+pf->size) < ptr && pf->next != NULL; | 1380 | /* Race ahead here, while calculating cache size. */ |
| 1375 | pf = pf->next) | 1381 | for (pf = free_list.next; |
| 1376 | ; /* Race ahead here. */ | 1382 | (pf->page + pf->size) < ptr && pf->next != NULL; |
| 1383 | pf = pf->next) | ||
| 1384 | cachesize += pf->size; | ||
| 1385 | |||
| 1386 | /* Finish cache size calculation. */ | ||
| 1387 | pt = pf; | ||
| 1388 | while (pt) { | ||
| 1389 | cachesize += pt->size; | ||
| 1390 | pt = pt->next; | ||
| 1391 | } | ||
| 1377 | 1392 | ||
| 1378 | if (pf->page > tail) { | 1393 | if (pf->page > tail) { |
| 1379 | /* Insert before entry */ | 1394 | /* Insert before entry */ |
| @@ -1385,6 +1400,7 @@ free_pages(void *ptr, u_long index, struct pginfo *info) | |||
| 1385 | px = NULL; | 1400 | px = NULL; |
| 1386 | } else if ((pf->page + pf->size) == ptr ) { | 1401 | } else if ((pf->page + pf->size) == ptr ) { |
| 1387 | /* Append to the previous entry. */ | 1402 | /* Append to the previous entry. */ |
| 1403 | cachesize -= pf->size; | ||
| 1388 | pf->size += l; | 1404 | pf->size += l; |
| 1389 | if (pf->next != NULL && (pf->page + pf->size) == pf->next->page ) { | 1405 | if (pf->next != NULL && (pf->page + pf->size) == pf->next->page ) { |
| 1390 | /* And collapse the next too. */ | 1406 | /* And collapse the next too. */ |
| @@ -1396,6 +1412,7 @@ free_pages(void *ptr, u_long index, struct pginfo *info) | |||
| 1396 | } | 1412 | } |
| 1397 | } else if (pf->page == tail) { | 1413 | } else if (pf->page == tail) { |
| 1398 | /* Prepend to entry. */ | 1414 | /* Prepend to entry. */ |
| 1415 | cachesize -= pf->size; | ||
| 1399 | pf->size += l; | 1416 | pf->size += l; |
| 1400 | pf->page = ptr; | 1417 | pf->page = ptr; |
| 1401 | pf->pdir = spi; | 1418 | pf->pdir = spi; |
| @@ -1419,34 +1436,32 @@ free_pages(void *ptr, u_long index, struct pginfo *info) | |||
| 1419 | } | 1436 | } |
| 1420 | 1437 | ||
| 1421 | /* Return something to OS ? */ | 1438 | /* Return something to OS ? */ |
| 1422 | if (pf->next == NULL && /* If we're the last one, */ | 1439 | if (pf->size > (malloc_cache - cachesize)) { |
| 1423 | pf->size > malloc_cache && /* ..and the cache is full, */ | ||
| 1424 | (pf->page + pf->size) == malloc_brk) { /* ..and none behind us, */ | ||
| 1425 | 1440 | ||
| 1426 | /* | 1441 | /* |
| 1427 | * Keep the cache intact. Notice that the '>' above guarantees that | 1442 | * Keep the cache intact. Notice that the '>' above guarantees that |
| 1428 | * the pf will always have at least one page afterwards. | 1443 | * the pf will always have at least one page afterwards. |
| 1429 | */ | 1444 | */ |
| 1430 | if (munmap((char *)pf->page + malloc_cache, pf->size - malloc_cache)!=0) | 1445 | if (munmap((char *)pf->page + (malloc_cache - cachesize), |
| 1446 | pf->size - (malloc_cache - cachesize)) != 0) | ||
| 1431 | goto not_return; | 1447 | goto not_return; |
| 1432 | tail = pf->page + pf->size; | 1448 | tail = pf->page + pf->size; |
| 1433 | lidx = ptr2index(tail) - 1; | 1449 | lidx = ptr2index(tail) - 1; |
| 1434 | pf->size = malloc_cache; | 1450 | pf->size = malloc_cache - cachesize; |
| 1435 | 1451 | ||
| 1436 | malloc_brk = pf->page + malloc_cache; | 1452 | index = ptr2index(pf->page + pf->size); |
| 1437 | |||
| 1438 | index = ptr2index(malloc_brk); | ||
| 1439 | 1453 | ||
| 1440 | pidx = PI_IDX(index); | 1454 | pidx = PI_IDX(index); |
| 1441 | if (prev_dir != NULL && PD_IDX(prev_dir->dirnum) >= pidx) | 1455 | if (prev_dir != NULL && PD_IDX(prev_dir->dirnum) >= pidx) |
| 1442 | prev_dir = NULL; /* Will be wiped out below ! */ | 1456 | prev_dir = NULL; /* Will be wiped out below ! */ |
| 1443 | 1457 | ||
| 1444 | for (pi=pf->pdir; pi!=NULL && PD_IDX(pi->dirnum)<pidx; pi=pi->next); | 1458 | for (pi=pf->pdir; pi!=NULL && PD_IDX(pi->dirnum)<pidx; pi=pi->next); |
| 1445 | 1459 | ||
| 1460 | spi = pi; | ||
| 1446 | if (pi != NULL && PD_IDX(pi->dirnum) == pidx) { | 1461 | if (pi != NULL && PD_IDX(pi->dirnum) == pidx) { |
| 1447 | pd = pi->base; | 1462 | pd = pi->base; |
| 1448 | 1463 | ||
| 1449 | for(i=index;i <= last_index;) { | 1464 | for(i=index;i <= lidx;) { |
| 1450 | if (pd[PI_OFF(i)] != MALLOC_NOT_MINE) { | 1465 | if (pd[PI_OFF(i)] != MALLOC_NOT_MINE) { |
| 1451 | pd[PI_OFF(i)] = MALLOC_NOT_MINE; | 1466 | pd[PI_OFF(i)] = MALLOC_NOT_MINE; |
| 1452 | #ifdef MALLOC_EXTRA_SANITY | 1467 | #ifdef MALLOC_EXTRA_SANITY |
| @@ -1458,12 +1473,19 @@ free_pages(void *ptr, u_long index, struct pginfo *info) | |||
| 1458 | #endif /* MALLOC_EXTRA_SANITY */ | 1473 | #endif /* MALLOC_EXTRA_SANITY */ |
| 1459 | pi->dirnum--; | 1474 | pi->dirnum--; |
| 1460 | } | 1475 | } |
| 1476 | #ifdef MALLOC_EXTRA_SANITY | ||
| 1477 | else | ||
| 1478 | wrtwarning("(ES): page already unmapped\n"); | ||
| 1479 | #endif /* MALLOC_EXTRA_SANITY */ | ||
| 1461 | i++; | 1480 | i++; |
| 1462 | if (!PI_OFF(i)) { | 1481 | if (!PI_OFF(i)) { |
| 1463 | /* If no page in that dir, free directory page. */ | 1482 | /* If no page in that dir, free directory page. */ |
| 1464 | if (!PD_OFF(pi->dirnum)) { | 1483 | if (!PD_OFF(pi->dirnum)) { |
| 1465 | /* Remove from list. */ | 1484 | /* Remove from list. */ |
| 1466 | pi->prev->next = pi->next; | 1485 | if (spi == pi) /* Update spi only if first. */ |
| 1486 | spi = pi->prev; | ||
| 1487 | if (pi->prev != NULL) | ||
| 1488 | pi->prev->next = pi->next; | ||
| 1467 | if (pi->next != NULL) | 1489 | if (pi->next != NULL) |
| 1468 | pi->next->prev = pi->prev; | 1490 | pi->next->prev = pi->prev; |
| 1469 | pi = pi->next; | 1491 | pi = pi->next; |
| @@ -1475,11 +1497,65 @@ free_pages(void *ptr, u_long index, struct pginfo *info) | |||
| 1475 | pd = pi->base; | 1497 | pd = pi->base; |
| 1476 | } | 1498 | } |
| 1477 | } | 1499 | } |
| 1500 | if (pi && !PD_OFF(pi->dirnum)) { | ||
| 1501 | /* Resulting page dir is now empty. */ | ||
| 1502 | /* Remove from list. */ | ||
| 1503 | if (spi == pi) /* Update spi only if first. */ | ||
| 1504 | spi = pi->prev; | ||
| 1505 | if (pi->prev != NULL) | ||
| 1506 | pi->prev->next = pi->next; | ||
| 1507 | if (pi->next != NULL) | ||
| 1508 | pi->next->prev = pi->prev; | ||
| 1509 | pi = pi->next; | ||
| 1510 | munmap(pd, malloc_pagesize); | ||
| 1511 | } | ||
| 1478 | } | 1512 | } |
| 1479 | 1513 | ||
| 1480 | last_index = index - 1; | 1514 | if (pi == NULL && malloc_brk == tail) { |
| 1515 | /* Resize down the malloc upper boundary. */ | ||
| 1516 | last_index = index - 1; | ||
| 1517 | malloc_brk = index2ptr(index); | ||
| 1518 | } | ||
| 1481 | 1519 | ||
| 1482 | /* XXX: We could realloc/shrink the pagedir here I guess. */ | 1520 | /* XXX: We could realloc/shrink the pagedir here I guess. */ |
| 1521 | if (pf->size == 0) { /* Remove from free-list as well. */ | ||
| 1522 | if (px) | ||
| 1523 | ifree(px); | ||
| 1524 | if ((px = pf->prev) != &free_list) { | ||
| 1525 | if (pi == NULL && last_index == (index - 1)) { | ||
| 1526 | if (spi == NULL) { | ||
| 1527 | malloc_brk = NULL; | ||
| 1528 | i = 11; | ||
| 1529 | } else { | ||
| 1530 | pd = spi->base; | ||
| 1531 | if (PD_IDX(spi->dirnum) < pidx) | ||
| 1532 | index = ((PD_IDX(spi->dirnum) + 1) * pdi_mod) - 1; | ||
| 1533 | for (pi=spi,i=index;pd[PI_OFF(i)]==MALLOC_NOT_MINE;i--) | ||
| 1534 | #ifdef MALLOC_EXTRA_SANITY | ||
| 1535 | if (!PI_OFF(i)) { /* Should never enter here. */ | ||
| 1536 | pi = pi->prev; | ||
| 1537 | if (pi == NULL || i == 0) | ||
| 1538 | break; | ||
| 1539 | pd = pi->base; | ||
| 1540 | i = (PD_IDX(pi->dirnum) + 1) * pdi_mod; | ||
| 1541 | } | ||
| 1542 | #else /* !MALLOC_EXTRA_SANITY */ | ||
| 1543 | { } | ||
| 1544 | #endif /* MALLOC_EXTRA_SANITY */ | ||
| 1545 | malloc_brk = index2ptr(i + 1); | ||
| 1546 | } | ||
| 1547 | last_index = i; | ||
| 1548 | } | ||
| 1549 | if ((px->next = pf->next) != NULL) | ||
| 1550 | px->next->prev = px; | ||
| 1551 | } else { | ||
| 1552 | if ((free_list.next = pf->next) != NULL) | ||
| 1553 | free_list.next->prev = &free_list; | ||
| 1554 | } | ||
| 1555 | px = pf; | ||
| 1556 | last_dir = prev_dir; | ||
| 1557 | prev_dir = NULL; | ||
| 1558 | } | ||
| 1483 | } | 1559 | } |
| 1484 | not_return: | 1560 | not_return: |
| 1485 | if (pt != NULL) | 1561 | if (pt != NULL) |
| @@ -1607,17 +1683,19 @@ ifree(void *ptr) | |||
| 1607 | return; | 1683 | return; |
| 1608 | 1684 | ||
| 1609 | if (malloc_ptrguard && PTR_ALIGNED(ptr)) | 1685 | if (malloc_ptrguard && PTR_ALIGNED(ptr)) |
| 1610 | ptr = (char *)ptr - PTR_GAP; | 1686 | ptr = (char *)ptr - PTR_GAP; |
| 1611 | 1687 | ||
| 1612 | index = ptr2index(ptr); | 1688 | index = ptr2index(ptr); |
| 1613 | 1689 | ||
| 1614 | if (index < malloc_pageshift) { | 1690 | if (index < malloc_pageshift) { |
| 1615 | wrtwarning("junk pointer, too low to make sense\n"); | 1691 | warnx("(%p)", ptr); |
| 1692 | wrtwarning("ifree: junk pointer, too low to make sense\n"); | ||
| 1616 | return; | 1693 | return; |
| 1617 | } | 1694 | } |
| 1618 | 1695 | ||
| 1619 | if (index > last_index) { | 1696 | if (index > last_index) { |
| 1620 | wrtwarning("junk pointer, too high to make sense\n"); | 1697 | warnx("(%p)", ptr); |
| 1698 | wrtwarning("ifree: junk pointer, too high to make sense\n"); | ||
| 1621 | return; | 1699 | return; |
| 1622 | } | 1700 | } |
| 1623 | 1701 | ||
