ucalloc.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*
  2. * allocate uncached memory
  3. */
  4. #include "u.h"
  5. #include "../port/lib.h"
  6. #include "mem.h"
  7. #include "dat.h"
  8. #include "fns.h"
  9. #include <pool.h>
  10. typedef struct Private Private;
  11. struct Private {
  12. Lock;
  13. char msg[256];
  14. char* cur;
  15. };
  16. static Private ucprivate;
  17. static void
  18. ucpoolpanic(Pool* p, char* fmt, ...)
  19. {
  20. va_list v;
  21. Private *pv;
  22. char msg[sizeof pv->msg];
  23. pv = p->private;
  24. va_start(v, fmt);
  25. vseprint(pv->cur, &pv->msg[sizeof pv->msg], fmt, v);
  26. va_end(v);
  27. memmove(msg, pv->msg, sizeof msg);
  28. iunlock(pv);
  29. panic("%s", msg);
  30. }
  31. static void
  32. ucpoolprint(Pool* p, char* fmt, ...)
  33. {
  34. va_list v;
  35. Private *pv;
  36. pv = p->private;
  37. va_start(v, fmt);
  38. pv->cur = vseprint(pv->cur, &pv->msg[sizeof pv->msg], fmt, v);
  39. va_end(v);
  40. }
  41. static void
  42. ucpoolunlock(Pool* p)
  43. {
  44. Private *pv;
  45. char msg[sizeof pv->msg];
  46. pv = p->private;
  47. if(pv->cur == pv->msg){
  48. iunlock(pv);
  49. return;
  50. }
  51. memmove(msg, pv->msg, sizeof msg);
  52. pv->cur = pv->msg;
  53. iunlock(pv);
  54. iprint("%.*s", sizeof pv->msg, msg);
  55. }
  56. static void
  57. ucpoollock(Pool* p)
  58. {
  59. Private *pv;
  60. pv = p->private;
  61. ilock(pv);
  62. pv->pc = getcallerpc(&p);
  63. pv->cur = pv->msg;
  64. }
  65. static void*
  66. ucarena(usize size)
  67. {
  68. void *uv, *v;
  69. assert(size == 1*MiB);
  70. mainmem->maxsize += 1*MiB;
  71. if((v = mallocalign(1*MiB, 1*MiB, 0, 0)) == nil ||
  72. (uv = mmuuncache(v, 1*MiB)) == nil){
  73. free(v);
  74. mainmem->maxsize -= 1*MiB;
  75. return nil;
  76. }
  77. return uv;
  78. }
  79. static Pool ucpool = {
  80. .name = "Uncached",
  81. .maxsize = 4*MiB,
  82. .minarena = 1*MiB-32,
  83. .quantum = 32,
  84. .alloc = ucarena,
  85. .merge = nil,
  86. .flags = /*POOL_TOLERANCE|POOL_ANTAGONISM|POOL_PARANOIA|*/0,
  87. .lock = ucpoollock,
  88. .unlock = ucpoolunlock,
  89. .print = ucpoolprint,
  90. .panic = ucpoolpanic,
  91. .private = &ucprivate,
  92. };
  93. void
  94. ucfree(void* v)
  95. {
  96. if(v == nil)
  97. return;
  98. poolfree(&ucpool, v);
  99. }
  100. void*
  101. ucalloc(usize size)
  102. {
  103. assert(size < ucpool.minarena-128);
  104. return poolallocalign(&ucpool, size, 32, 0, 0);
  105. }
  106. void*
  107. ucallocalign(usize size, int align, int span)
  108. {
  109. assert(size < ucpool.minarena-128);
  110. return poolallocalign(&ucpool, size, align, 0, span);
  111. }