calloc.c 2.2 KB

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