comparison src/alloc.c @ 51907:4073a8ee4fc0

(BLOCK_PADDING): Rename from ABLOCKS_PADDING. Update users. (lisp_align_malloc): Use posix_memalign is available. (ABLOCKS_BASE): Use HAVE_POSIX_MEMALIGN as an optimization. (STRING_BLOCK_SIZE): Rename from STRINGS_IN_STRING_BLOCK for consistency. Update users.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Mon, 14 Jul 2003 02:51:08 +0000
parents 65772ad7d4e1
children cb3976b5e59f
comparison
equal deleted inserted replaced
51906:b4346da6617f 51907:4073a8ee4fc0
642 /* BLOCK_BYTES and guarantees they are aligned on a BLOCK_ALIGN boundary. */ 642 /* BLOCK_BYTES and guarantees they are aligned on a BLOCK_ALIGN boundary. */
643 643
644 644
645 /* BLOCK_ALIGN has to be a power of 2. */ 645 /* BLOCK_ALIGN has to be a power of 2. */
646 #define BLOCK_ALIGN (1 << 10) 646 #define BLOCK_ALIGN (1 << 10)
647 #define BLOCK_BYTES \
648 (BLOCK_ALIGN - sizeof (struct alinged_block *) - ABLOCKS_PADDING)
649
650 /* Internal data structures and constants. */
651 647
652 /* Padding to leave at the end of a malloc'd block. This is to give 648 /* Padding to leave at the end of a malloc'd block. This is to give
653 malloc a chance to minimize the amount of memory wasted to alignment. 649 malloc a chance to minimize the amount of memory wasted to alignment.
654 It should be tuned to the particular malloc library used. 650 It should be tuned to the particular malloc library used.
655 The current setting is based on glibc-2.3.2. */ 651 On glibc-2.3.2, malloc never tries to align, so a padding of 0 is best.
656 #define ABLOCKS_PADDING 0 652 posix_memalign on the other hand would ideally prefer a value of 4
653 because otherwise, there's 1020 bytes wasted between each ablocks.
654 But testing shows that those 1020 will most of the time be efficiently
655 used by malloc to place other objects, so a value of 0 is still preferable
656 unless you have a lot of cons&floats and virtually nothing else. */
657 #define BLOCK_PADDING 0
658 #define BLOCK_BYTES \
659 (BLOCK_ALIGN - sizeof (struct aligned_block *) - BLOCK_PADDING)
660
661 /* Internal data structures and constants. */
662
657 #define ABLOCKS_SIZE 16 663 #define ABLOCKS_SIZE 16
658 664
659 /* An aligned block of memory. */ 665 /* An aligned block of memory. */
660 struct ablock 666 struct ablock
661 { 667 {
674 (if not, the word before the first ablock holds a pointer to the 680 (if not, the word before the first ablock holds a pointer to the
675 real base). */ 681 real base). */
676 struct ablocks *abase; 682 struct ablocks *abase;
677 /* The padding of all but the last ablock is unused. The padding of 683 /* The padding of all but the last ablock is unused. The padding of
678 the last ablock in an ablocks is not allocated. */ 684 the last ablock in an ablocks is not allocated. */
679 #if ABLOCKS_PADDING 685 #if BLOCK_PADDING
680 char padding[ABLOCKS_PADDING]; 686 char padding[BLOCK_PADDING];
681 #endif 687 #endif
682 }; 688 };
683 689
684 /* A bunch of consecutive aligned blocks. */ 690 /* A bunch of consecutive aligned blocks. */
685 struct ablocks 691 struct ablocks
686 { 692 {
687 struct ablock blocks[ABLOCKS_SIZE]; 693 struct ablock blocks[ABLOCKS_SIZE];
688 }; 694 };
689 695
690 /* Size of the block requested from malloc or memalign. */ 696 /* Size of the block requested from malloc or memalign. */
691 #define ABLOCKS_BYTES (sizeof (struct ablocks) - ABLOCKS_PADDING) 697 #define ABLOCKS_BYTES (sizeof (struct ablocks) - BLOCK_PADDING)
692 698
693 #define ABLOCK_ABASE(block) \ 699 #define ABLOCK_ABASE(block) \
694 (((unsigned long) (block)->abase) <= (1 + 2 * ABLOCKS_SIZE) \ 700 (((unsigned long) (block)->abase) <= (1 + 2 * ABLOCKS_SIZE) \
695 ? (struct ablocks *)(block) \ 701 ? (struct ablocks *)(block) \
696 : (block)->abase) 702 : (block)->abase)
697 703
698 /* Virtual `busy' field. */ 704 /* Virtual `busy' field. */
699 #define ABLOCKS_BUSY(abase) ((abase)->blocks[0].abase) 705 #define ABLOCKS_BUSY(abase) ((abase)->blocks[0].abase)
700 706
701 /* Pointer to the (not necessarily aligned) malloc block. */ 707 /* Pointer to the (not necessarily aligned) malloc block. */
708 #ifdef HAVE_POSIX_MEMALIGN
709 #define ABLOCKS_BASE(abase) (abase)
710 #else
702 #define ABLOCKS_BASE(abase) \ 711 #define ABLOCKS_BASE(abase) \
703 (1 & (int) ABLOCKS_BUSY (abase) ? abase : ((void**)abase)[-1]) 712 (1 & (int) ABLOCKS_BUSY (abase) ? abase : ((void**)abase)[-1])
713 #endif
704 714
705 /* The list of free ablock. */ 715 /* The list of free ablock. */
706 static struct ablock *free_ablock; 716 static struct ablock *free_ablock;
707 717
708 /* Allocate an aligned block of nbytes. 718 /* Allocate an aligned block of nbytes.
733 because mapped region contents are not preserved in 743 because mapped region contents are not preserved in
734 a dumped Emacs. */ 744 a dumped Emacs. */
735 mallopt (M_MMAP_MAX, 0); 745 mallopt (M_MMAP_MAX, 0);
736 #endif 746 #endif
737 747
748 #ifdef HAVE_POSIX_MEMALIGN
749 {
750 int err = posix_memalign (&base, BLOCK_ALIGN, ABLOCKS_BYTES);
751 abase = err ? (base = NULL) : base;
752 }
753 #else
738 base = malloc (ABLOCKS_BYTES); 754 base = malloc (ABLOCKS_BYTES);
739 abase = ALIGN (base, BLOCK_ALIGN); 755 abase = ALIGN (base, BLOCK_ALIGN);
756 #endif
740 757
741 aligned = (base == abase); 758 aligned = (base == abase);
742 if (!aligned) 759 if (!aligned)
743 ((void**)abase)[-1] = base; 760 ((void**)abase)[-1] = base;
744 761
755 abase->blocks[i].x.next_free = free_ablock; 772 abase->blocks[i].x.next_free = free_ablock;
756 free_ablock = &abase->blocks[i]; 773 free_ablock = &abase->blocks[i];
757 } 774 }
758 ABLOCKS_BUSY (abase) = (struct ablocks *) aligned; 775 ABLOCKS_BUSY (abase) = (struct ablocks *) aligned;
759 776
777 eassert (0 == ((EMACS_UINT)abase) % BLOCK_ALIGN);
760 eassert (ABLOCK_ABASE (&abase->blocks[3]) == abase); /* 3 is arbitrary */ 778 eassert (ABLOCK_ABASE (&abase->blocks[3]) == abase); /* 3 is arbitrary */
761 eassert (ABLOCK_ABASE (&abase->blocks[0]) == abase); 779 eassert (ABLOCK_ABASE (&abase->blocks[0]) == abase);
762 eassert (ABLOCKS_BASE (abase) == base); 780 eassert (ABLOCKS_BASE (abase) == base);
763 eassert (aligned == (int)ABLOCKS_BUSY (abase)); 781 eassert (aligned == (int)ABLOCKS_BUSY (abase));
764 } 782 }
1309 }; 1327 };
1310 1328
1311 /* Number of Lisp strings in a string_block structure. The 1020 is 1329 /* Number of Lisp strings in a string_block structure. The 1020 is
1312 1024 minus malloc overhead. */ 1330 1024 minus malloc overhead. */
1313 1331
1314 #define STRINGS_IN_STRING_BLOCK \ 1332 #define STRING_BLOCK_SIZE \
1315 ((1020 - sizeof (struct string_block *)) / sizeof (struct Lisp_String)) 1333 ((1020 - sizeof (struct string_block *)) / sizeof (struct Lisp_String))
1316 1334
1317 /* Structure describing a block from which Lisp_String structures 1335 /* Structure describing a block from which Lisp_String structures
1318 are allocated. */ 1336 are allocated. */
1319 1337
1320 struct string_block 1338 struct string_block
1321 { 1339 {
1322 struct string_block *next; 1340 struct string_block *next;
1323 struct Lisp_String strings[STRINGS_IN_STRING_BLOCK]; 1341 struct Lisp_String strings[STRING_BLOCK_SIZE];
1324 }; 1342 };
1325 1343
1326 /* Head and tail of the list of sblock structures holding Lisp string 1344 /* Head and tail of the list of sblock structures holding Lisp string
1327 data. We always allocate from current_sblock. The NEXT pointers 1345 data. We always allocate from current_sblock. The NEXT pointers
1328 in the sblock structures go from oldest_sblock to current_sblock. */ 1346 in the sblock structures go from oldest_sblock to current_sblock. */
1513 bzero (b, sizeof *b); 1531 bzero (b, sizeof *b);
1514 b->next = string_blocks; 1532 b->next = string_blocks;
1515 string_blocks = b; 1533 string_blocks = b;
1516 ++n_string_blocks; 1534 ++n_string_blocks;
1517 1535
1518 for (i = STRINGS_IN_STRING_BLOCK - 1; i >= 0; --i) 1536 for (i = STRING_BLOCK_SIZE - 1; i >= 0; --i)
1519 { 1537 {
1520 s = b->strings + i; 1538 s = b->strings + i;
1521 NEXT_FREE_LISP_STRING (s) = string_free_list; 1539 NEXT_FREE_LISP_STRING (s) = string_free_list;
1522 string_free_list = s; 1540 string_free_list = s;
1523 } 1541 }
1524 1542
1525 total_free_strings += STRINGS_IN_STRING_BLOCK; 1543 total_free_strings += STRING_BLOCK_SIZE;
1526 } 1544 }
1527 1545
1528 /* Pop a Lisp_String off the free-list. */ 1546 /* Pop a Lisp_String off the free-list. */
1529 s = string_free_list; 1547 s = string_free_list;
1530 string_free_list = NEXT_FREE_LISP_STRING (s); 1548 string_free_list = NEXT_FREE_LISP_STRING (s);
1671 int i, nfree = 0; 1689 int i, nfree = 0;
1672 struct Lisp_String *free_list_before = string_free_list; 1690 struct Lisp_String *free_list_before = string_free_list;
1673 1691
1674 next = b->next; 1692 next = b->next;
1675 1693
1676 for (i = 0; i < STRINGS_IN_STRING_BLOCK; ++i) 1694 for (i = 0; i < STRING_BLOCK_SIZE; ++i)
1677 { 1695 {
1678 struct Lisp_String *s = b->strings + i; 1696 struct Lisp_String *s = b->strings + i;
1679 1697
1680 if (s->data) 1698 if (s->data)
1681 { 1699 {
1726 } 1744 }
1727 } 1745 }
1728 1746
1729 /* Free blocks that contain free Lisp_Strings only, except 1747 /* Free blocks that contain free Lisp_Strings only, except
1730 the first two of them. */ 1748 the first two of them. */
1731 if (nfree == STRINGS_IN_STRING_BLOCK 1749 if (nfree == STRING_BLOCK_SIZE
1732 && total_free_strings > STRINGS_IN_STRING_BLOCK) 1750 && total_free_strings > STRING_BLOCK_SIZE)
1733 { 1751 {
1734 lisp_free (b); 1752 lisp_free (b);
1735 --n_string_blocks; 1753 --n_string_blocks;
1736 string_free_list = free_list_before; 1754 string_free_list = free_list_before;
1737 } 1755 }