1
0

kmalloc.g 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. # This file is part of asmc, a bootstrapping OS with minimal seed
  2. # Copyright (C) 2018 Giovanni Mascellani <gio@debian.org>
  3. # https://gitlab.com/giomasce/asmc
  4. # This program is free software: you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License as published by
  6. # the Free Software Foundation, either version 3 of the License, or
  7. # (at your option) any later version.
  8. # This program is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. # GNU General Public License for more details.
  12. # You should have received a copy of the GNU General Public License
  13. # along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. # This memory allocator is based on the same ideas as kmalloc.c (see
  15. # for example [1]), but the implementation is completely new and some
  16. # bits were simplified (for example, page size is ignored, because
  17. # there is not virtual memory around). It is rewritten from scratch
  18. # anyway.
  19. #
  20. # [1] https://github.com/emeryberger/Malloc-Implementations/blob/master/allocators/kmalloc/kmalloc.c
  21. const KMALLOC_NBUCKETS 28
  22. $kmalloc_buckets
  23. $kmalloc_num
  24. $kmalloc_num_tot
  25. $kmalloc_size_tot
  26. $kmalloc_req_num
  27. $kmalloc_req_size
  28. fun _bucket_actual_size 2 {
  29. $buf
  30. $bucket
  31. @buf 1 param = ;
  32. @bucket 0 param = ;
  33. 0 bucket <= bucket KMALLOC_NBUCKETS < && "_bucket_actual_size: invalid bucket number" buf bucket assert_msg_int_int ;
  34. $actual
  35. @actual 1 bucket 3 + << = ;
  36. actual ret ;
  37. }
  38. fun malloc 1 {
  39. $size
  40. @size 0 param = ;
  41. if size 0 == {
  42. 0 ret ;
  43. }
  44. size 0 > "malloc: invalid negative size" assert_msg ;
  45. @kmalloc_num kmalloc_num 1 + = ;
  46. @kmalloc_num_tot kmalloc_num_tot 1 + = ;
  47. @kmalloc_size_tot kmalloc_size_tot size + = ;
  48. # Initialize buckets on first call
  49. if kmalloc_buckets 0 == {
  50. @kmalloc_buckets KMALLOC_NBUCKETS 4 * platform_allocate = ;
  51. $i
  52. @i 0 = ;
  53. while i KMALLOC_NBUCKETS < {
  54. kmalloc_buckets 4 i * + 0 = ;
  55. @i i 1 + = ;
  56. }
  57. }
  58. # Find the appropriate bucket size
  59. $actual
  60. $bucket
  61. @bucket 0 = ;
  62. $cont
  63. @cont 1 = ;
  64. while cont {
  65. @actual 0 bucket _bucket_actual_size = ;
  66. if size 4 + actual <= {
  67. @cont 0 = ;
  68. } else {
  69. @bucket bucket 1 + = ;
  70. }
  71. }
  72. # Take a region from the appropriate bucket, or request a new one
  73. $ptr
  74. @ptr kmalloc_buckets 4 bucket * + ** = ;
  75. if ptr 0 == {
  76. @ptr actual platform_allocate = ;
  77. @kmalloc_req_num kmalloc_req_num 1 + = ;
  78. @kmalloc_req_size kmalloc_req_size actual + = ;
  79. } else {
  80. kmalloc_buckets 4 bucket * + ptr ** = ;
  81. }
  82. ptr bucket = ;
  83. ptr 4 + ret ;
  84. }
  85. fun free 1 {
  86. $buf
  87. @buf 0 param = ;
  88. if buf 0 == {
  89. ret ;
  90. }
  91. kmalloc_num 0 > "free: mismatched free" assert_msg ;
  92. @kmalloc_num kmalloc_num 1 - = ;
  93. $ptr
  94. @ptr buf 4 - = ;
  95. $bucket
  96. @bucket ptr ** = ;
  97. # Just for checking that the bucket number is valid
  98. buf bucket _bucket_actual_size ;
  99. ptr kmalloc_buckets 4 bucket * + ** = ;
  100. kmalloc_buckets 4 bucket * + ptr = ;
  101. }
  102. fun _malloc_get_size 1 {
  103. $buf
  104. @buf 0 param = ;
  105. $ptr
  106. @ptr buf 4 - = ;
  107. $bucket
  108. @bucket ptr ** = ;
  109. $actual
  110. @actual buf bucket _bucket_actual_size = ;
  111. $size
  112. @size actual 4 - = ;
  113. size ret ;
  114. }
  115. fun malloc_stats 0 {
  116. kmalloc_num_tot itoa log ;
  117. " regions were malloc-ed\n" log ;
  118. kmalloc_size_tot itoa log ;
  119. " bytes were malloc-ed\n" log ;
  120. kmalloc_num itoa log ;
  121. " malloc-ed regions were never free-d\n" log ;
  122. kmalloc_req_num itoa log ;
  123. " regions were requested from platform\n" log ;
  124. kmalloc_req_size itoa log ;
  125. " bytes were requested from platform\n" log ;
  126. }