aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorPaul Eggert2011-09-03 16:03:38 -0700
committerPaul Eggert2011-09-03 16:03:38 -0700
commitb49e353d9d01adbe60bc5d0b1658b4ef978b0b06 (patch)
tree9f2ffa6f7a6562abf661a4951012b488ad8b1ae7 /src/alloc.c
parent74b880cbc18bd0194c7b1fc44c4a983ee05adae2 (diff)
parentbc3200871917d5c54c8c4299a06bf8f8ba2ea02d (diff)
downloademacs-b49e353d9d01adbe60bc5d0b1658b4ef978b0b06.tar.gz
emacs-b49e353d9d01adbe60bc5d0b1658b4ef978b0b06.zip
Merge from trunk.
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c106
1 files changed, 98 insertions, 8 deletions
diff --git a/src/alloc.c b/src/alloc.c
index b96fc1f0642..2d256800466 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -24,7 +24,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
24 24
25#include <signal.h> 25#include <signal.h>
26 26
27#ifdef HAVE_GTK_AND_PTHREAD 27#ifdef HAVE_PTHREAD
28#include <pthread.h> 28#include <pthread.h>
29#endif 29#endif
30 30
@@ -46,6 +46,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
46#include "syssignal.h" 46#include "syssignal.h"
47#include "termhooks.h" /* For struct terminal. */ 47#include "termhooks.h" /* For struct terminal. */
48#include <setjmp.h> 48#include <setjmp.h>
49#include <verify.h>
49 50
50/* GC_MALLOC_CHECK defined means perform validity checks of malloc'd 51/* GC_MALLOC_CHECK defined means perform validity checks of malloc'd
51 memory. Can do this only if using gmalloc.c. */ 52 memory. Can do this only if using gmalloc.c. */
@@ -84,13 +85,15 @@ extern size_t __malloc_extra_blocks;
84#endif /* not DOUG_LEA_MALLOC */ 85#endif /* not DOUG_LEA_MALLOC */
85 86
86#if ! defined SYSTEM_MALLOC && ! defined SYNC_INPUT 87#if ! defined SYSTEM_MALLOC && ! defined SYNC_INPUT
87#ifdef HAVE_GTK_AND_PTHREAD 88#ifdef HAVE_PTHREAD
88 89
89/* When GTK uses the file chooser dialog, different backends can be loaded 90/* When GTK uses the file chooser dialog, different backends can be loaded
90 dynamically. One such a backend is the Gnome VFS backend that gets loaded 91 dynamically. One such a backend is the Gnome VFS backend that gets loaded
91 if you run Gnome. That backend creates several threads and also allocates 92 if you run Gnome. That backend creates several threads and also allocates
92 memory with malloc. 93 memory with malloc.
93 94
95 Also, gconf and gsettings may create several threads.
96
94 If Emacs sets malloc hooks (! SYSTEM_MALLOC) and the emacs_blocked_* 97 If Emacs sets malloc hooks (! SYSTEM_MALLOC) and the emacs_blocked_*
95 functions below are called from malloc, there is a chance that one 98 functions below are called from malloc, there is a chance that one
96 of these threads preempts the Emacs main thread and the hook variables 99 of these threads preempts the Emacs main thread and the hook variables
@@ -122,12 +125,12 @@ static pthread_mutex_t alloc_mutex;
122 } \ 125 } \
123 while (0) 126 while (0)
124 127
125#else /* ! defined HAVE_GTK_AND_PTHREAD */ 128#else /* ! defined HAVE_PTHREAD */
126 129
127#define BLOCK_INPUT_ALLOC BLOCK_INPUT 130#define BLOCK_INPUT_ALLOC BLOCK_INPUT
128#define UNBLOCK_INPUT_ALLOC UNBLOCK_INPUT 131#define UNBLOCK_INPUT_ALLOC UNBLOCK_INPUT
129 132
130#endif /* ! defined HAVE_GTK_AND_PTHREAD */ 133#endif /* ! defined HAVE_PTHREAD */
131#endif /* ! defined SYSTEM_MALLOC && ! defined SYNC_INPUT */ 134#endif /* ! defined SYSTEM_MALLOC && ! defined SYNC_INPUT */
132 135
133/* Mark, unmark, query mark bit of a Lisp string. S must be a pointer 136/* Mark, unmark, query mark bit of a Lisp string. S must be a pointer
@@ -731,6 +734,93 @@ xfree (POINTER_TYPE *block)
731} 734}
732 735
733 736
737/* Other parts of Emacs pass large int values to allocator functions
738 expecting ptrdiff_t. This is portable in practice, but check it to
739 be safe. */
740verify (INT_MAX <= PTRDIFF_MAX);
741
742
743/* Allocate an array of NITEMS items, each of size ITEM_SIZE.
744 Signal an error on memory exhaustion, and block interrupt input. */
745
746void *
747xnmalloc (ptrdiff_t nitems, ptrdiff_t item_size)
748{
749 xassert (0 <= nitems && 0 < item_size);
750 if (min (PTRDIFF_MAX, SIZE_MAX) / item_size < nitems)
751 memory_full (SIZE_MAX);
752 return xmalloc (nitems * item_size);
753}
754
755
756/* Reallocate an array PA to make it of NITEMS items, each of size ITEM_SIZE.
757 Signal an error on memory exhaustion, and block interrupt input. */
758
759void *
760xnrealloc (void *pa, ptrdiff_t nitems, ptrdiff_t item_size)
761{
762 xassert (0 <= nitems && 0 < item_size);
763 if (min (PTRDIFF_MAX, SIZE_MAX) / item_size < nitems)
764 memory_full (SIZE_MAX);
765 return xrealloc (pa, nitems * item_size);
766}
767
768
769/* Grow PA, which points to an array of *NITEMS items, and return the
770 location of the reallocated array, updating *NITEMS to reflect its
771 new size. The new array will contain at least NITEMS_INCR_MIN more
772 items, but will not contain more than NITEMS_MAX items total.
773 ITEM_SIZE is the size of each item, in bytes.
774
775 ITEM_SIZE and NITEMS_INCR_MIN must be positive. *NITEMS must be
776 nonnegative. If NITEMS_MAX is -1, it is treated as if it were
777 infinity.
778
779 If PA is null, then allocate a new array instead of reallocating
780 the old one. Thus, to grow an array A without saving its old
781 contents, invoke xfree (A) immediately followed by xgrowalloc (0,
782 &NITEMS, ...).
783
784 Block interrupt input as needed. If memory exhaustion occurs, set
785 *NITEMS to zero if PA is null, and signal an error (i.e., do not
786 return). */
787
788void *
789xpalloc (void *pa, ptrdiff_t *nitems, ptrdiff_t nitems_incr_min,
790 ptrdiff_t nitems_max, ptrdiff_t item_size)
791{
792 /* The approximate size to use for initial small allocation
793 requests. This is the largest "small" request for the GNU C
794 library malloc. */
795 enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 };
796
797 /* If the array is tiny, grow it to about (but no greater than)
798 DEFAULT_MXFAST bytes. Otherwise, grow it by about 50%. */
799 ptrdiff_t n = *nitems;
800 ptrdiff_t tiny_max = DEFAULT_MXFAST / item_size - n;
801 ptrdiff_t half_again = n >> 1;
802 ptrdiff_t incr_estimate = max (tiny_max, half_again);
803
804 /* Adjust the increment according to three constraints: NITEMS_INCR_MIN,
805 NITEMS_MAX, and what the C language can represent safely. */
806 ptrdiff_t C_language_max = min (PTRDIFF_MAX, SIZE_MAX) / item_size;
807 ptrdiff_t n_max = (0 <= nitems_max && nitems_max < C_language_max
808 ? nitems_max : C_language_max);
809 ptrdiff_t nitems_incr_max = n_max - n;
810 ptrdiff_t incr = max (nitems_incr_min, min (incr_estimate, nitems_incr_max));
811
812 xassert (0 < item_size && 0 < nitems_incr_min && 0 <= n && -1 <= nitems_max);
813 if (! pa)
814 *nitems = 0;
815 if (nitems_incr_max < incr)
816 memory_full (SIZE_MAX);
817 n += incr;
818 pa = xrealloc (pa, n * item_size);
819 *nitems = n;
820 return pa;
821}
822
823
734/* Like strdup, but uses xmalloc. */ 824/* Like strdup, but uses xmalloc. */
735 825
736char * 826char *
@@ -1265,7 +1355,7 @@ emacs_blocked_realloc (void *ptr, size_t size, const void *ptr2)
1265} 1355}
1266 1356
1267 1357
1268#ifdef HAVE_GTK_AND_PTHREAD 1358#ifdef HAVE_PTHREAD
1269/* Called from Fdump_emacs so that when the dumped Emacs starts, it has a 1359/* Called from Fdump_emacs so that when the dumped Emacs starts, it has a
1270 normal malloc. Some thread implementations need this as they call 1360 normal malloc. Some thread implementations need this as they call
1271 malloc before main. The pthread_self call in BLOCK_INPUT_ALLOC then 1361 malloc before main. The pthread_self call in BLOCK_INPUT_ALLOC then
@@ -1278,7 +1368,7 @@ reset_malloc_hooks (void)
1278 __malloc_hook = old_malloc_hook; 1368 __malloc_hook = old_malloc_hook;
1279 __realloc_hook = old_realloc_hook; 1369 __realloc_hook = old_realloc_hook;
1280} 1370}
1281#endif /* HAVE_GTK_AND_PTHREAD */ 1371#endif /* HAVE_PTHREAD */
1282 1372
1283 1373
1284/* Called from main to set up malloc to use our hooks. */ 1374/* Called from main to set up malloc to use our hooks. */
@@ -1286,7 +1376,7 @@ reset_malloc_hooks (void)
1286void 1376void
1287uninterrupt_malloc (void) 1377uninterrupt_malloc (void)
1288{ 1378{
1289#ifdef HAVE_GTK_AND_PTHREAD 1379#ifdef HAVE_PTHREAD
1290#ifdef DOUG_LEA_MALLOC 1380#ifdef DOUG_LEA_MALLOC
1291 pthread_mutexattr_t attr; 1381 pthread_mutexattr_t attr;
1292 1382
@@ -1300,7 +1390,7 @@ uninterrupt_malloc (void)
1300 and the bundled gmalloc.c doesn't require it. */ 1390 and the bundled gmalloc.c doesn't require it. */
1301 pthread_mutex_init (&alloc_mutex, NULL); 1391 pthread_mutex_init (&alloc_mutex, NULL);
1302#endif /* !DOUG_LEA_MALLOC */ 1392#endif /* !DOUG_LEA_MALLOC */
1303#endif /* HAVE_GTK_AND_PTHREAD */ 1393#endif /* HAVE_PTHREAD */
1304 1394
1305 if (__free_hook != emacs_blocked_free) 1395 if (__free_hook != emacs_blocked_free)
1306 old_free_hook = __free_hook; 1396 old_free_hook = __free_hook;