xalloc.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include "u.h"
  10. #include "../port/lib.h"
  11. #include "mem.h"
  12. #include "dat.h"
  13. #include "fns.h"
  14. THIS FILE IS NOT USED FOR NIX.
  15. I'm leaving it here, and making sure it does not compile. -nemo
  16. enum
  17. {
  18. Nhole = 128,
  19. Magichole = 0x484F4C45, /* HOLE */
  20. };
  21. typedef struct Hole Hole;
  22. typedef struct Xalloc Xalloc;
  23. typedef struct Xhdr Xhdr;
  24. struct Hole
  25. {
  26. uintptr addr;
  27. ulong size;
  28. uintptr top;
  29. Hole* link;
  30. };
  31. struct Xhdr
  32. {
  33. ulong size;
  34. ulong magix;
  35. char data[];
  36. };
  37. struct Xalloc
  38. {
  39. Lock;
  40. Hole hole[Nhole];
  41. Hole* flist;
  42. Hole* table;
  43. };
  44. static Xalloc xlists;
  45. extern void* xalloc(ulong);
  46. extern int xmerge(void*, void*);
  47. extern void xhole(uintptr, ulong);
  48. extern void xsummary(void);
  49. void
  50. xinit(void)
  51. {
  52. int i, n, upages, kpages;
  53. ulong maxkpa;
  54. Confmem *m;
  55. Pallocmem *pm;
  56. Hole *h, *eh;
  57. eh = &xlists.hole[Nhole-1];
  58. for(h = xlists.hole; h < eh; h++)
  59. h->link = h+1;
  60. xlists.flist = xlists.hole;
  61. upages = conf.upages;
  62. kpages = conf.npage - upages;
  63. pm = palloc.mem;
  64. maxkpa = -KZERO;
  65. for(i=0; i<nelem(conf.mem); i++){
  66. m = &conf.mem[i];
  67. n = m->npage;
  68. if(n > kpages)
  69. n = kpages;
  70. if(m->base >= maxkpa)
  71. n = 0;
  72. else if(n > 0 && m->base+n*PGSZ >= maxkpa)
  73. n = (maxkpa - m->base)/PGSZ;
  74. /* first give to kernel */
  75. if(n > 0){
  76. m->kbase = PTR2UINT(KADDR(m->base));
  77. m->klimit = PTR2UINT(KADDR(m->base+n*PGSZ));
  78. xhole(m->base, n*PGSZ);
  79. kpages -= n;
  80. }
  81. /* if anything left over, give to user */
  82. if(n < m->npage){
  83. if(pm >= palloc.mem+nelem(palloc.mem)){
  84. print("xinit: losing %lud pages\n", m->npage-n);
  85. continue;
  86. }
  87. pm->base = m->base+n*PGSZ;
  88. pm->npage = m->npage - n;
  89. pm++;
  90. }
  91. }
  92. xsummary();
  93. }
  94. void*
  95. xspanalloc(ulong size, int align, ulong span)
  96. {
  97. uintptr a, v, t;
  98. a = PTR2UINT(xalloc(size+align+span));
  99. if(a == 0)
  100. panic("xspanalloc: %lud %d %lux\n", size, align, span);
  101. if(span > 2) {
  102. v = (a + span) & ~(span-1);
  103. t = v - a;
  104. if(t > 0)
  105. xhole(PADDR(UINT2PTR(a)), t);
  106. t = a + span - v;
  107. if(t > 0)
  108. xhole(PADDR(UINT2PTR(v+size+align)), t);
  109. }
  110. else
  111. v = a;
  112. if(align > 1)
  113. v = (v + align) & ~(align-1);
  114. return (void*)v;
  115. }
  116. void*
  117. xallocz(ulong size, int zero)
  118. {
  119. Xhdr *p;
  120. Hole *h, **l;
  121. size += BY2V + offsetof(Xhdr, data[0]);
  122. size &= ~(BY2V-1);
  123. ilock(&xlists);
  124. l = &xlists.table;
  125. for(h = *l; h; h = h->link) {
  126. if(h->size >= size) {
  127. p = (Xhdr*)KADDR(h->addr);
  128. h->addr += size;
  129. h->size -= size;
  130. if(h->size == 0) {
  131. *l = h->link;
  132. h->link = xlists.flist;
  133. xlists.flist = h;
  134. }
  135. iunlock(&xlists);
  136. if(zero)
  137. memset(p->data, 0, size);
  138. p->magix = Magichole;
  139. p->size = size;
  140. return p->data;
  141. }
  142. l = &h->link;
  143. }
  144. iunlock(&xlists);
  145. return nil;
  146. }
  147. void*
  148. xalloc(ulong size)
  149. {
  150. return xallocz(size, 1);
  151. }
  152. void
  153. xfree(void *p)
  154. {
  155. Xhdr *x;
  156. x = UINT2PTR((PTR2UINT(p) - offsetof(Xhdr, data[0])));
  157. if(x->magix != Magichole) {
  158. xsummary();
  159. panic("xfree(%#p) %#ux != %#lux", p, Magichole, x->magix);
  160. }
  161. xhole(PADDR(x), x->size);
  162. }
  163. int
  164. xmerge(void *vp, void *vq)
  165. {
  166. Xhdr *p, *q;
  167. p = UINT2PTR((PTR2UINT(vp) - offsetof(Xhdr, data[0])));
  168. q = UINT2PTR((PTR2UINT(vq) - offsetof(Xhdr, data[0])));
  169. if(p->magix != Magichole || q->magix != Magichole) {
  170. xsummary();
  171. panic("xmerge(%#p, %#p) bad magic %#lux, %#lux\n",
  172. vp, vq, p->magix, q->magix);
  173. }
  174. if((uchar*)p+p->size == (uchar*)q) {
  175. p->size += q->size;
  176. return 1;
  177. }
  178. return 0;
  179. }
  180. void
  181. xhole(uintptr addr, ulong size)
  182. {
  183. uintptr top;
  184. Hole *h, *c, **l;
  185. if(size == 0)
  186. return;
  187. top = addr + size;
  188. ilock(&xlists);
  189. l = &xlists.table;
  190. for(h = *l; h; h = h->link) {
  191. if(h->top == addr) {
  192. h->size += size;
  193. h->top = h->addr+h->size;
  194. c = h->link;
  195. if(c && h->top == c->addr) {
  196. h->top += c->size;
  197. h->size += c->size;
  198. h->link = c->link;
  199. c->link = xlists.flist;
  200. xlists.flist = c;
  201. }
  202. iunlock(&xlists);
  203. return;
  204. }
  205. if(h->addr > addr)
  206. break;
  207. l = &h->link;
  208. }
  209. if(h && top == h->addr) {
  210. h->addr -= size;
  211. h->size += size;
  212. iunlock(&xlists);
  213. return;
  214. }
  215. if(xlists.flist == nil) {
  216. iunlock(&xlists);
  217. print("xfree: no free holes, leaked %lud bytes\n", size);
  218. return;
  219. }
  220. h = xlists.flist;
  221. xlists.flist = h->link;
  222. h->addr = addr;
  223. h->top = top;
  224. h->size = size;
  225. h->link = *l;
  226. *l = h;
  227. iunlock(&xlists);
  228. }
  229. void
  230. xsummary(void)
  231. {
  232. int i;
  233. Hole *h;
  234. i = 0;
  235. for(h = xlists.flist; h; h = h->link)
  236. i++;
  237. print("%d holes free\n", i);
  238. i = 0;
  239. for(h = xlists.table; h; h = h->link) {
  240. print("%.8p %.8p %lud\n", h->addr, h->top, h->size);
  241. i += h->size;
  242. }
  243. print("%d bytes free\n", i);
  244. }