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