1 /*
2   This is a version (aka dlmalloc) of malloc/free/realloc written by
3   Doug Lea and released to the public domain.  Use, modify, and
4   redistribute this code without permission or acknowledgement in any
5   way you wish.  Send questions, comments, complaints, performance
6   data, etc to dl@cs.oswego.edu
7 
8   VERSION 2.7.2 Sat Aug 17 09:07:30 2002  Doug Lea  (dl at gee)
9 
10   Note: There may be an updated version of this malloc obtainable at
11            ftp://gee.cs.oswego.edu/pub/misc/malloc.c
12   Check before installing!
13 
14   Hacked up for uClibc by Erik Andersen <andersen@codepoet.org>
15 */
16 
17 #include "malloc.h"
18 
19 
20 /* ------------------------------ calloc ------------------------------ */
calloc(size_t n_elements,size_t elem_size)21 void* calloc(size_t n_elements, size_t elem_size)
22 {
23     mchunkptr p;
24     unsigned long  clearsize;
25     unsigned long  nclears;
26     size_t size, *d;
27     void* mem;
28 
29 
30     /* guard vs integer overflow, but allow nmemb
31      * to fall through and call malloc(0) */
32     size = n_elements * elem_size;
33     if (n_elements && elem_size != (size / n_elements)) {
34 	__set_errno(ENOMEM);
35 	return NULL;
36     }
37 
38     __MALLOC_LOCK;
39     mem = malloc(size);
40     if (mem != 0) {
41 	p = mem2chunk(mem);
42 
43 	if (!chunk_is_mmapped(p))
44 	{
45 	    /*
46 	       Unroll clear of <= 36 bytes (72 if 8byte sizes)
47 	       We know that contents have an odd number of
48 	       size_t-sized words; minimally 3.
49 	       */
50 
51 	    d = (size_t*)mem;
52 	    clearsize = chunksize(p) - (sizeof(size_t));
53 	    nclears = clearsize / sizeof(size_t);
54 	    assert(nclears >= 3);
55 
56 	    if (nclears > 9)
57 		memset(d, 0, clearsize);
58 
59 	    else {
60 		*(d+0) = 0;
61 		*(d+1) = 0;
62 		*(d+2) = 0;
63 		if (nclears > 4) {
64 		    *(d+3) = 0;
65 		    *(d+4) = 0;
66 		    if (nclears > 6) {
67 			*(d+5) = 0;
68 			*(d+6) = 0;
69 			if (nclears > 8) {
70 			    *(d+7) = 0;
71 			    *(d+8) = 0;
72 			}
73 		    }
74 		}
75 	    }
76 	}
77 #if 0
78 	else
79 	{
80 	/* Standard unix mmap using /dev/zero clears memory so calloc
81 	 * doesn't need to actually zero anything....
82 	 */
83 	    d = (size_t*)mem;
84 	    /* Note the additional (sizeof(size_t)) */
85 	    clearsize = chunksize(p) - 2*(sizeof(size_t));
86 	    memset(d, 0, clearsize);
87 	}
88 #endif
89     }
90     __MALLOC_UNLOCK;
91     return mem;
92 }
93 
94 /* glibc compatibilty  */
95 weak_alias(calloc, __libc_calloc)
96