mem_musl.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. // Copyright 2023 The Libc Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. //go:build !libc.membrk && !libc.memgrind && linux && (amd64 || arm64 || loong64 || ppc64le || s390x || riscv64 || 386 || arm)
  5. package libc // import "modernc.org/libc"
  6. import (
  7. "math"
  8. mbits "math/bits"
  9. "modernc.org/memory"
  10. )
  11. const (
  12. isMemBrk = false
  13. )
  14. func Xmalloc(tls *TLS, n Tsize_t) (r uintptr) {
  15. if __ccgo_strace {
  16. trc("tls=%v n=%v, (%v:)", tls, n, origin(2))
  17. defer func() { trc("-> %v", r) }()
  18. }
  19. if n > math.MaxInt {
  20. tls.setErrno(ENOMEM)
  21. return 0
  22. }
  23. allocatorMu.Lock()
  24. defer allocatorMu.Unlock()
  25. if n == 0 {
  26. // malloc(0) should return unique pointers
  27. // (often expected and gnulib replaces malloc if malloc(0) returns 0)
  28. n = 1
  29. }
  30. var err error
  31. if r, err = allocator.UintptrMalloc(int(n)); err != nil {
  32. r = 0
  33. tls.setErrno(ENOMEM)
  34. }
  35. return r
  36. }
  37. func Xcalloc(tls *TLS, m Tsize_t, n Tsize_t) (r uintptr) {
  38. if __ccgo_strace {
  39. trc("tls=%v m=%v n=%v, (%v:)", tls, m, n, origin(2))
  40. defer func() { trc("-> %v", r) }()
  41. }
  42. hi, rq := mbits.Mul(uint(m), uint(n))
  43. if hi != 0 || rq > math.MaxInt {
  44. tls.setErrno(ENOMEM)
  45. return 0
  46. }
  47. allocatorMu.Lock()
  48. defer allocatorMu.Unlock()
  49. if rq == 0 {
  50. rq = 1
  51. }
  52. var err error
  53. if r, err = allocator.UintptrCalloc(int(rq)); err != nil {
  54. r = 0
  55. tls.setErrno(ENOMEM)
  56. }
  57. return r
  58. }
  59. func Xrealloc(tls *TLS, p uintptr, n Tsize_t) (r uintptr) {
  60. if __ccgo_strace {
  61. trc("tls=%v p=%v n=%v, (%v:)", tls, p, n, origin(2))
  62. defer func() { trc("-> %v", r) }()
  63. }
  64. allocatorMu.Lock()
  65. defer allocatorMu.Unlock()
  66. var err error
  67. if r, err = allocator.UintptrRealloc(p, int(n)); err != nil {
  68. r = 0
  69. tls.setErrno(ENOMEM)
  70. }
  71. return r
  72. }
  73. func Xfree(tls *TLS, p uintptr) {
  74. if __ccgo_strace {
  75. trc("tls=%v p=%v, (%v:)", tls, p, origin(2))
  76. }
  77. allocatorMu.Lock()
  78. defer allocatorMu.Unlock()
  79. allocator.UintptrFree(p)
  80. }
  81. func Xmalloc_usable_size(tls *TLS, p uintptr) (r Tsize_t) {
  82. if __ccgo_strace {
  83. trc("tls=%v p=%v, (%v:)", tls, p, origin(2))
  84. defer func() { trc("-> %v", r) }()
  85. }
  86. if p == 0 {
  87. return 0
  88. }
  89. allocatorMu.Lock()
  90. defer allocatorMu.Unlock()
  91. return Tsize_t(memory.UintptrUsableSize(p))
  92. }
  93. func MemAudit() (r []*MemAuditError) {
  94. return nil
  95. }
  96. func UsableSize(p uintptr) Tsize_t {
  97. allocatorMu.Lock()
  98. defer allocatorMu.Unlock()
  99. return Tsize_t(memory.UintptrUsableSize(p))
  100. }
  101. type MemAllocatorStat struct {
  102. Allocs int
  103. Bytes int
  104. Mmaps int
  105. }
  106. // MemStat returns the global memory allocator statistics.
  107. // should be compiled with the memory.counters build tag for the data to be available.
  108. func MemStat() MemAllocatorStat {
  109. allocatorMu.Lock()
  110. defer allocatorMu.Unlock()
  111. return MemAllocatorStat{
  112. Allocs: allocator.Allocs,
  113. Bytes: allocator.Bytes,
  114. Mmaps: allocator.Mmaps,
  115. }
  116. }
  117. // MemAuditStart locks the memory allocator, initializes and enables memory
  118. // auditing. Finaly it unlocks the memory allocator.
  119. //
  120. // Some memory handling errors, like double free or freeing of unallocated
  121. // memory, will panic when memory auditing is enabled.
  122. //
  123. // This memory auditing functionality has to be enabled using the libc.memgrind
  124. // build tag.
  125. //
  126. // It is intended only for debug/test builds. It slows down memory allocation
  127. // routines and it has additional memory costs.
  128. func MemAuditStart() {}
  129. // MemAuditReport locks the memory allocator, reports memory leaks, if any.
  130. // Finally it disables memory auditing and unlocks the memory allocator.
  131. //
  132. // This memory auditing functionality has to be enabled using the libc.memgrind
  133. // build tag.
  134. //
  135. // It is intended only for debug/test builds. It slows down memory allocation
  136. // routines and it has additional memory costs.
  137. func MemAuditReport() error { return nil }