github.com/afumu/libc@v0.0.6/musl/src/malloc/calloc.c (about) 1 #include <stdlib.h> 2 #include <stdint.h> 3 #include <string.h> 4 #include <errno.h> 5 #include "dynlink.h" 6 7 static size_t mal0_clear(char *p, size_t n) 8 { 9 const size_t pagesz = 4096; /* arbitrary */ 10 if (n < pagesz) return n; 11 #ifdef __GNUC__ 12 typedef uint64_t __attribute__((__may_alias__)) T; 13 #else 14 typedef unsigned char T; 15 #endif 16 char *pp = p + n; 17 size_t i = (uintptr_t)pp & (pagesz - 1); 18 for (;;) { 19 pp = memset(pp - i, 0, i); 20 if (pp - p < pagesz) return pp - p; 21 for (i = pagesz; i; i -= 2*sizeof(T), pp -= 2*sizeof(T)) 22 if (((T *)pp)[-1] | ((T *)pp)[-2]) 23 break; 24 } 25 } 26 27 static int allzerop(void *p) 28 { 29 return 0; 30 } 31 weak_alias(allzerop, __malloc_allzerop); 32 33 void *calloc(size_t m, size_t n) 34 { 35 if (n && m > (size_t)-1/n) { 36 errno = ENOMEM; 37 return 0; 38 } 39 n *= m; 40 void *p = malloc(n); 41 if (!p || (!__malloc_replaced && __malloc_allzerop(p))) 42 return p; 43 n = mal0_clear(p, n); 44 return memset(p, 0, n); 45 }