0000: 23 69 6e 63 6c 75 64 65 20 22 73 6c 61 62 2e 68 #include "slab.h
0010: 22 0a 0a 23 69 66 20 49 4e 54 45 52 46 41 43 45 "..#if INTERFACE
0020: 0a 23 69 6e 63 6c 75 64 65 20 3c 73 79 73 2f 74 .#include <sys/t
0030: 79 70 65 73 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 ypes.h>.#include
0040: 20 3c 73 74 64 64 65 66 2e 68 3e 0a 23 69 6e 63 <stddef.h>.#inc
0050: 6c 75 64 65 20 3c 73 74 64 69 6e 74 2e 68 3e 0a lude <stdint.h>.
0060: 0a 73 74 72 75 63 74 20 73 6c 61 62 5f 74 79 70 .struct slab_typ
0070: 65 5f 74 20 7b 0a 09 75 69 6e 74 33 32 5f 74 20 e_t {..uint32_t
0080: 6d 61 67 69 63 3b 0a 09 73 69 7a 65 5f 74 20 65 magic;..size_t e
0090: 73 69 7a 65 3b 0a 09 73 69 7a 65 5f 74 20 73 6c size;..size_t sl
00a0: 6f 74 73 69 7a 65 3b 0a 09 69 6e 74 20 63 6f 75 otsize;..int cou
00b0: 6e 74 3b 0a 09 73 74 72 75 63 74 20 73 6c 61 62 nt;..struct slab
00c0: 20 2a 20 66 69 72 73 74 3b 0a 09 73 6c 61 62 5f * first;..slab_
00d0: 74 79 70 65 5f 74 20 2a 20 6e 65 78 74 2c 20 2a type_t * next, *
00e0: 20 70 72 65 76 3b 0a 09 76 6f 69 64 20 28 2a 6d prev;..void (*m
00f0: 61 72 6b 29 28 76 6f 69 64 20 2a 29 3b 0a 09 76 ark)(void *);..v
0100: 6f 69 64 20 28 2a 66 69 6e 61 6c 69 7a 65 29 28 oid (*finalize)(
0110: 76 6f 69 64 20 2a 29 3b 0a 09 6d 75 74 65 78 5f void *);..mutex_
0120: 74 20 6c 6f 63 6b 5b 31 5d 3b 0a 7d 3b 0a 0a 73 t lock[1];.};..s
0130: 74 72 75 63 74 20 73 6c 61 62 5f 77 65 61 6b 72 truct slab_weakr
0140: 65 66 5f 74 20 7b 0a 09 76 6f 69 64 20 2a 20 70 ef_t {..void * p
0150: 3b 0a 09 69 6e 74 20 63 68 61 6e 63 65 73 3b 0a ;..int chances;.
0160: 09 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 73 65 .unsigned int se
0170: 71 3b 0a 7d 3b 0a 0a 73 74 72 75 63 74 20 67 63 q;.};..struct gc
0180: 5f 73 74 61 74 73 5f 74 0a 7b 0a 09 73 69 7a 65 _stats_t.{..size
0190: 5f 74 20 69 6e 75 73 65 3b 0a 09 73 69 7a 65 5f _t inuse;..size_
01a0: 74 20 70 65 61 6b 3b 0a 09 73 69 7a 65 5f 74 20 t peak;..size_t
01b0: 74 6f 74 61 6c 3b 0a 7d 3b 0a 0a 23 64 65 66 69 total;.};..#defi
01c0: 6e 65 20 53 4c 41 42 5f 54 59 50 45 28 73 2c 20 ne SLAB_TYPE(s,
01d0: 6d 2c 20 66 29 20 7b 2e 6d 61 67 69 63 3d 30 2c m, f) {.magic=0,
01e0: 20 2e 65 73 69 7a 65 3d 73 2c 20 2e 6d 61 72 6b .esize=s, .mark
01f0: 3d 6d 2c 20 2e 66 69 6e 61 6c 69 7a 65 3d 66 7d =m, .finalize=f}
0200: 0a 0a 23 69 66 64 65 66 20 44 45 42 55 47 0a 23 ..#ifdef DEBUG.#
0210: 64 65 66 69 6e 65 20 6d 61 6c 6c 6f 63 28 73 69 define malloc(si
0220: 7a 65 29 20 6d 61 6c 6c 6f 63 5f 64 28 73 69 7a ze) malloc_d(siz
0230: 65 2c 20 5f 5f 46 49 4c 45 5f 5f 2c 20 5f 5f 4c e, __FILE__, __L
0240: 49 4e 45 5f 5f 29 0a 23 64 65 66 69 6e 65 20 63 INE__).#define c
0250: 61 6c 6c 6f 63 28 63 6f 75 6e 74 2c 20 73 69 7a alloc(count, siz
0260: 65 29 20 63 61 6c 6c 6f 63 5f 64 28 63 6f 75 6e e) calloc_d(coun
0270: 74 2c 20 73 69 7a 65 2c 20 5f 5f 46 49 4c 45 5f t, size, __FILE_
0280: 5f 2c 20 5f 5f 4c 49 4e 45 5f 5f 29 0a 23 64 65 _, __LINE__).#de
0290: 66 69 6e 65 20 72 65 61 6c 6c 6f 63 28 70 2c 20 fine realloc(p,
02a0: 73 69 7a 65 29 20 72 65 61 6c 6c 6f 63 5f 64 28 size) realloc_d(
02b0: 70 2c 20 73 69 7a 65 2c 20 5f 5f 46 49 4c 45 5f p, size, __FILE_
02c0: 5f 2c 20 5f 5f 4c 49 4e 45 5f 5f 29 0a 23 64 65 _, __LINE__).#de
02d0: 66 69 6e 65 20 73 6c 61 62 5f 61 6c 6c 6f 63 28 fine slab_alloc(
02e0: 74 79 70 65 29 20 73 6c 61 62 5f 61 6c 6c 6f 63 type) slab_alloc
02f0: 5f 64 28 74 79 70 65 2c 20 5f 5f 46 49 4c 45 5f _d(type, __FILE_
0300: 5f 2c 20 5f 5f 4c 49 4e 45 5f 5f 29 0a 23 64 65 _, __LINE__).#de
0310: 66 69 6e 65 20 73 6c 61 62 5f 63 61 6c 6c 6f 63 fine slab_calloc
0320: 28 74 79 70 65 29 20 73 6c 61 62 5f 63 61 6c 6c (type) slab_call
0330: 6f 63 5f 64 28 74 79 70 65 2c 20 5f 5f 46 49 4c oc_d(type, __FIL
0340: 45 5f 5f 2c 20 5f 5f 4c 49 4e 45 5f 5f 29 0a 23 E__, __LINE__).#
0350: 65 6c 73 65 0a 23 64 65 66 69 6e 65 20 6d 61 6c else.#define mal
0360: 6c 6f 63 28 73 69 7a 65 29 20 6d 61 6c 6c 6f 63 loc(size) malloc
0370: 5f 70 28 73 69 7a 65 29 0a 23 64 65 66 69 6e 65 _p(size).#define
0380: 20 63 61 6c 6c 6f 63 28 63 6f 75 6e 74 2c 20 73 calloc(count, s
0390: 69 7a 65 29 20 63 61 6c 6c 6f 63 5f 70 28 63 6f ize) calloc_p(co
03a0: 75 6e 74 2c 20 73 69 7a 65 29 0a 23 64 65 66 69 unt, size).#defi
03b0: 6e 65 20 72 65 61 6c 6c 6f 63 28 70 2c 20 73 69 ne realloc(p, si
03c0: 7a 65 29 20 72 65 61 6c 6c 6f 63 5f 70 28 70 2c ze) realloc_p(p,
03d0: 20 73 69 7a 65 29 0a 23 64 65 66 69 6e 65 20 73 size).#define s
03e0: 6c 61 62 5f 61 6c 6c 6f 63 28 74 79 70 65 29 20 lab_alloc(type)
03f0: 73 6c 61 62 5f 61 6c 6c 6f 63 5f 70 28 74 79 70 slab_alloc_p(typ
0400: 65 29 0a 23 64 65 66 69 6e 65 20 73 6c 61 62 5f e).#define slab_
0410: 63 61 6c 6c 6f 63 28 74 79 70 65 29 20 73 6c 61 calloc(type) sla
0420: 62 5f 63 61 6c 6c 6f 63 5f 70 28 74 79 70 65 29 b_calloc_p(type)
0430: 0a 23 65 6e 64 69 66 0a 0a 23 64 65 66 69 6e 65 .#endif..#define
0440: 20 6d 63 6c 6f 6e 65 28 70 29 20 6d 63 6c 6f 6e mclone(p) mclon
0450: 65 5f 73 69 7a 65 64 28 70 2c 20 73 69 7a 65 6f e_sized(p, sizeo
0460: 66 28 2a 70 29 29 0a 0a 23 64 65 66 69 6e 65 20 f(*p))..#define
0470: 47 43 52 4f 4f 54 20 5f 5f 61 74 74 72 69 62 75 GCROOT __attribu
0480: 74 65 5f 5f 28 28 73 65 63 74 69 6f 6e 28 22 2e te__((section(".
0490: 67 63 72 6f 6f 74 22 29 29 29 0a 0a 23 65 6e 64 gcroot")))..#end
04a0: 69 66 0a 0a 65 78 63 65 70 74 69 6f 6e 5f 64 65 if..exception_de
04b0: 66 20 4f 75 74 4f 66 4d 65 6d 6f 72 79 45 78 63 f OutOfMemoryExc
04c0: 65 70 74 69 6f 6e 20 3d 20 7b 20 22 4f 75 74 4f eption = { "OutO
04d0: 66 4d 65 6d 6f 72 79 45 78 63 65 70 74 69 6f 6e fMemoryException
04e0: 22 2c 20 26 45 78 63 65 70 74 69 6f 6e 20 7d 3b ", &Exception };
04f0: 0a 65 78 63 65 70 74 69 6f 6e 5f 64 65 66 20 41 .exception_def A
0500: 6c 6c 6f 63 61 74 69 6f 6e 54 6f 6f 42 69 67 45 llocationTooBigE
0510: 78 63 65 70 74 69 6f 6e 20 3d 20 7b 20 22 41 6c xception = { "Al
0520: 6c 6f 63 61 74 69 6f 6e 54 6f 6f 42 69 67 45 78 locationTooBigEx
0530: 63 65 70 74 69 6f 6e 22 2c 20 26 45 78 63 65 70 ception", &Excep
0540: 74 69 6f 6e 20 7d 3b 0a 0a 74 79 70 65 64 65 66 tion };..typedef
0550: 20 73 74 72 75 63 74 20 73 6c 61 62 5f 73 6c 6f struct slab_slo
0560: 74 5f 74 20 73 6c 61 62 5f 73 6c 6f 74 5f 74 3b t_t slab_slot_t;
0570: 0a 73 74 72 75 63 74 20 73 6c 61 62 5f 73 6c 6f .struct slab_slo
0580: 74 5f 74 20 7b 0a 09 75 69 6e 74 36 34 5f 74 20 t_t {..uint64_t
0590: 73 65 71 3b 0a 23 69 66 64 65 66 20 44 45 42 55 seq;.#ifdef DEBU
05a0: 47 0a 09 63 68 61 72 20 2a 20 66 69 6c 65 3b 0a G..char * file;.
05b0: 09 69 6e 74 20 6c 69 6e 65 3b 0a 09 76 6f 69 64 .int line;..void
05c0: 20 2a 20 62 61 63 6b 74 72 61 63 65 5b 39 5d 3b * backtrace[9];
05d0: 0a 23 65 6e 64 69 66 0a 7d 3b 0a 0a 74 79 70 65 .#endif.};..type
05e0: 64 65 66 20 73 74 72 75 63 74 20 73 6c 61 62 20 def struct slab
05f0: 7b 0a 09 75 69 6e 74 33 32 5f 74 20 6d 61 67 69 {..uint32_t magi
0600: 63 3b 0a 09 73 74 72 75 63 74 20 73 6c 61 62 20 c;..struct slab
0610: 2a 20 6e 65 78 74 2c 20 2a 20 70 72 65 76 3b 0a * next, * prev;.
0620: 09 73 6c 61 62 5f 74 79 70 65 5f 74 20 2a 20 74 .slab_type_t * t
0630: 79 70 65 3b 0a 09 75 69 6e 74 33 32 5f 74 20 2a ype;..uint32_t *
0640: 20 61 76 61 69 6c 61 62 6c 65 3b 0a 09 75 69 6e available;..uin
0650: 74 33 32 5f 74 20 2a 20 66 69 6e 61 6c 69 7a 65 t32_t * finalize
0660: 3b 0a 09 63 68 61 72 20 2a 20 64 61 74 61 3b 0a ;..char * data;.
0670: 7d 20 73 6c 61 62 5f 74 3b 0a 0a 73 74 61 74 69 } slab_t;..stati
0680: 63 20 73 6c 61 62 5f 74 79 70 65 5f 74 20 2a 20 c slab_type_t *
0690: 74 79 70 65 73 3b 0a 0a 23 69 66 20 30 0a 73 74 types;..#if 0.st
06a0: 61 74 69 63 20 74 68 72 65 61 64 5f 74 20 2a 20 atic thread_t *
06b0: 63 6c 65 61 6e 65 72 5f 74 68 72 65 61 64 3b 0a cleaner_thread;.
06c0: 69 6e 74 20 69 73 5f 63 6c 65 61 6e 65 72 28 29 int is_cleaner()
06d0: 0a 7b 0a 09 72 65 74 75 72 6e 20 61 72 63 68 5f .{..return arch_
06e0: 67 65 74 5f 74 68 72 65 61 64 28 29 20 3d 3d 20 get_thread() ==
06f0: 63 6c 65 61 6e 65 72 5f 74 68 72 65 61 64 3b 0a cleaner_thread;.
0700: 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 63 }..static void c
0710: 6c 65 61 6e 65 72 28 29 0a 7b 0a 09 63 6c 65 61 leaner().{..clea
0720: 6e 65 72 5f 74 68 72 65 61 64 20 3d 20 61 72 63 ner_thread = arc
0730: 68 5f 67 65 74 5f 74 68 72 65 61 64 28 29 3b 0a h_get_thread();.
0740: 09 69 6e 74 20 70 61 67 65 73 20 3d 20 70 61 67 .int pages = pag
0750: 65 5f 63 6f 75 6e 74 28 29 3b 0a 09 77 68 69 6c e_count();..whil
0760: 65 28 31 29 20 7b 0a 09 09 4d 4f 4e 49 54 4f 52 e(1) {...MONITOR
0770: 5f 41 55 54 4f 4c 4f 43 4b 28 63 6c 65 61 6e 73 _AUTOLOCK(cleans
0780: 69 67 6e 61 6c 29 20 7b 0a 09 09 09 6d 6f 6e 69 ignal) {....moni
0790: 74 6f 72 5f 77 61 69 74 28 63 6c 65 61 6e 73 69 tor_wait(cleansi
07a0: 67 6e 61 6c 29 3b 0a 09 09 7d 0a 09 09 69 6e 74 gnal);...}...int
07b0: 20 70 72 65 66 72 65 65 20 3d 20 70 61 67 65 5f prefree = page_
07c0: 63 6f 75 6e 74 5f 66 72 65 65 28 29 3b 0a 09 09 count_free();...
07d0: 74 68 72 65 61 64 5f 67 63 28 29 3b 0a 09 09 69 thread_gc();...i
07e0: 6e 74 20 70 6f 73 74 66 72 65 65 20 3d 20 70 61 nt postfree = pa
07f0: 67 65 5f 63 6f 75 6e 74 5f 66 72 65 65 28 29 3b ge_count_free();
0800: 0a 09 09 4d 4f 4e 49 54 4f 52 5f 41 55 54 4f 4c ...MONITOR_AUTOL
0810: 4f 43 4b 28 66 72 65 65 73 69 67 6e 61 6c 29 20 OCK(freesignal)
0820: 7b 0a 09 09 09 6d 6f 6e 69 74 6f 72 5f 62 72 6f {....monitor_bro
0830: 61 64 63 61 73 74 28 66 72 65 65 73 69 67 6e 61 adcast(freesigna
0840: 6c 29 3b 0a 09 09 7d 0a 09 7d 0a 7d 0a 23 65 6e l);...}..}.}.#en
0850: 64 69 66 0a 0a 76 6f 69 64 20 73 6c 61 62 5f 69 dif..void slab_i
0860: 6e 69 74 28 29 0a 7b 0a 7d 0a 0a 73 74 61 74 69 nit().{.}..stati
0870: 63 20 6d 75 74 65 78 5f 74 20 73 6c 61 62 6c 6f c mutex_t slablo
0880: 63 6b 5b 31 5d 3b 0a 73 74 61 74 69 63 20 76 6f ck[1];.static vo
0890: 69 64 20 73 6c 61 62 5f 6c 6f 63 6b 28 69 6e 74 id slab_lock(int
08a0: 20 67 63 29 0a 7b 0a 09 69 66 20 28 67 63 29 20 gc).{..if (gc)
08b0: 7b 0a 09 09 6d 75 74 65 78 5f 6c 6f 63 6b 28 73 {...mutex_lock(s
08c0: 6c 61 62 6c 6f 63 6b 29 3b 0a 09 7d 20 65 6c 73 lablock);..} els
08d0: 65 20 7b 0a 09 09 6d 75 74 65 78 5f 6c 6f 63 6b e {...mutex_lock
08e0: 28 73 6c 61 62 6c 6f 63 6b 29 3b 0a 09 7d 0a 7d (slablock);..}.}
08f0: 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 73 6c ..static void sl
0900: 61 62 5f 75 6e 6c 6f 63 6b 28 29 0a 7b 0a 09 6d ab_unlock().{..m
0910: 75 74 65 78 5f 75 6e 6c 6f 63 6b 28 73 6c 61 62 utex_unlock(slab
0920: 6c 6f 63 6b 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 lock);.}..static
0930: 20 73 6c 61 62 5f 74 79 70 65 5f 74 20 2a 20 73 slab_type_t * s
0940: 6c 61 62 5f 6d 69 6e 20 3d 20 30 3b 0a 73 74 61 lab_min = 0;.sta
0950: 74 69 63 20 73 6c 61 62 5f 74 79 70 65 5f 74 20 tic slab_type_t
0960: 2a 20 73 6c 61 62 5f 6d 61 78 20 3d 20 30 3b 0a * slab_max = 0;.
0970: 73 74 61 74 69 63 20 76 6f 69 64 20 73 6c 61 62 static void slab
0980: 5f 72 65 67 69 73 74 65 72 28 73 6c 61 62 5f 74 _register(slab_t
0990: 79 70 65 5f 74 20 2a 20 73 74 79 70 65 29 0a 7b ype_t * stype).{
09a0: 0a 09 69 66 20 28 30 20 3d 3d 20 73 6c 61 62 5f ..if (0 == slab_
09b0: 6d 69 6e 20 7c 7c 20 73 74 79 70 65 20 3c 20 73 min || stype < s
09c0: 6c 61 62 5f 6d 69 6e 29 20 7b 0a 09 09 73 6c 61 lab_min) {...sla
09d0: 62 5f 6d 69 6e 20 3d 20 73 74 79 70 65 3b 0a 09 b_min = stype;..
09e0: 7d 0a 09 69 66 20 28 30 20 3d 3d 20 73 6c 61 62 }..if (0 == slab
09f0: 5f 6d 61 78 20 7c 7c 20 73 74 79 70 65 20 3e 20 _max || stype >
0a00: 73 6c 61 62 5f 6d 61 78 29 20 7b 0a 09 09 73 6c slab_max) {...sl
0a10: 61 62 5f 6d 61 78 20 3d 20 73 74 79 70 65 3b 0a ab_max = stype;.
0a20: 09 7d 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 .}.}..static int
0a30: 20 73 6c 61 62 5f 76 61 6c 69 64 28 73 6c 61 62 slab_valid(slab
0a40: 5f 74 79 70 65 5f 74 20 2a 20 73 74 79 70 65 29 _type_t * stype)
0a50: 0a 7b 0a 09 72 65 74 75 72 6e 20 28 73 6c 61 62 .{..return (slab
0a60: 5f 6d 69 6e 20 3c 3d 20 73 74 79 70 65 20 26 26 _min <= stype &&
0a70: 20 73 74 79 70 65 20 3c 3d 20 73 6c 61 62 5f 6d stype <= slab_m
0a80: 61 78 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 73 ax);.}..static s
0a90: 6c 61 62 5f 74 20 2a 20 73 6c 61 62 5f 6e 65 77 lab_t * slab_new
0aa0: 28 73 6c 61 62 5f 74 79 70 65 5f 74 20 2a 20 73 (slab_type_t * s
0ab0: 74 79 70 65 29 0a 7b 0a 09 69 66 20 28 30 20 3d type).{..if (0 =
0ac0: 3d 20 73 74 79 70 65 2d 3e 6d 61 67 69 63 29 20 = stype->magic)
0ad0: 7b 0a 09 09 2f 2a 20 49 6e 69 74 69 61 6c 69 7a {.../* Initializ
0ae0: 65 20 74 79 70 65 20 2a 2f 0a 09 09 73 74 79 70 e type */...styp
0af0: 65 2d 3e 66 69 72 73 74 20 3d 20 30 3b 0a 09 09 e->first = 0;...
0b00: 73 74 79 70 65 2d 3e 6d 61 67 69 63 20 3d 20 39 stype->magic = 9
0b10: 39 37 20 2a 20 28 75 69 6e 74 33 32 5f 74 29 73 97 * (uint32_t)s
0b20: 74 79 70 65 3b 0a 09 09 73 74 79 70 65 2d 3e 73 type;...stype->s
0b30: 6c 6f 74 73 69 7a 65 20 3d 20 52 4f 55 4e 44 55 lotsize = ROUNDU
0b40: 50 28 73 74 79 70 65 2d 3e 65 73 69 7a 65 2b 73 P(stype->esize+s
0b50: 69 7a 65 6f 66 28 73 6c 61 62 5f 73 6c 6f 74 5f izeof(slab_slot_
0b60: 74 29 2c 20 73 69 7a 65 6f 66 28 69 6e 74 70 74 t), sizeof(intpt
0b70: 72 5f 74 29 29 3b 0a 0a 09 09 2f 2a 20 20 20 20 r_t));..../*
0b80: 20 20 20 20 20 20 20 3c 2d 2d 2d 2d 2d 2d 2d 2d <--------
0b90: 2d 2d 2d 2d 2d 2d 2d 2d 2d 64 2d 2d 2d 2d 2d 2d ---------d------
0ba0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 3e 0a 09 09 ------------>...
0bb0: 20 2a 20 7c 20 73 6c 61 62 5f 74 20 7c 61 7c 66 * | slab_t |a|f
0bc0: 7c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 64 | d
0bd0: 61 74 61 20 20 20 20 20 20 20 20 20 20 20 20 20 ata
0be0: 20 20 20 7c 0a 09 09 20 2a 20 20 3c 2d 2d 2d 2d |... * <----
0bf0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 70 61 67 -------------pag
0c00: 65 20 73 69 7a 65 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d e size----------
0c10: 2d 2d 2d 2d 2d 2d 2d 2d 2d 3e 0a 09 09 20 2a 20 --------->... *
0c20: 64 61 74 61 20 2b 20 61 20 2b 20 66 20 3d 20 41 data + a + f = A
0c30: 52 43 48 5f 50 41 47 45 5f 53 49 5a 45 2d 73 69 RCH_PAGE_SIZE-si
0c40: 7a 65 6f 66 28 73 6c 61 62 5f 74 29 0a 09 09 20 zeof(slab_t)...
0c50: 2a 20 63 2a 73 20 2b 20 28 63 2b 33 31 29 2f 38 * c*s + (c+31)/8
0c60: 20 2b 20 28 63 2b 33 31 29 2f 38 20 3d 20 70 73 + (c+31)/8 = ps
0c70: 7a 2d 73 6c 61 62 5f 74 20 3d 20 64 0a 09 09 20 z-slab_t = d...
0c80: 2a 20 63 2a 73 20 2b 20 28 63 2b 33 31 29 2f 34 * c*s + (c+31)/4
0c90: 20 3d 20 70 73 7a 2d 73 6c 61 62 5f 74 20 3d 20 = psz-slab_t =
0ca0: 64 0a 09 09 20 2a 20 34 63 2a 73 20 2b 20 28 63 d... * 4c*s + (c
0cb0: 2b 33 31 29 20 3d 20 70 73 7a 2d 73 6c 61 62 5f +31) = psz-slab_
0cc0: 74 20 3d 20 34 64 0a 09 09 20 2a 20 34 63 2a 73 t = 4d... * 4c*s
0cd0: 20 2b 20 63 20 2b 20 33 31 20 3d 20 70 73 7a 2d + c + 31 = psz-
0ce0: 73 6c 61 62 5f 74 20 3d 20 34 64 0a 09 09 20 2a slab_t = 4d... *
0cf0: 20 34 63 2a 73 20 2b 20 63 20 3d 20 34 64 20 2d 4c*s + c = 4d -
0d00: 20 33 31 0a 09 09 20 2a 20 63 28 34 73 20 2b 20 31... * c(4s +
0d10: 31 29 20 3d 20 34 64 20 2d 20 33 31 0a 09 09 20 1) = 4d - 31...
0d20: 2a 20 63 20 3d 20 28 34 64 20 2d 20 33 31 29 20 * c = (4d - 31)
0d30: 2f 20 28 34 73 20 2b 20 31 29 0a 09 09 20 2a 2f / (4s + 1)... */
0d40: 0a 09 09 73 74 79 70 65 2d 3e 63 6f 75 6e 74 20 ...stype->count
0d50: 3d 20 28 34 2a 28 41 52 43 48 5f 50 41 47 45 5f = (4*(ARCH_PAGE_
0d60: 53 49 5a 45 2d 73 69 7a 65 6f 66 28 73 6c 61 62 SIZE-sizeof(slab
0d70: 5f 74 29 29 2d 33 31 29 20 2f 20 28 34 20 2a 20 _t))-31) / (4 *
0d80: 73 74 79 70 65 2d 3e 73 6c 6f 74 73 69 7a 65 20 stype->slotsize
0d90: 2b 20 31 29 3b 0a 09 09 73 6c 61 62 5f 6c 6f 63 + 1);...slab_loc
0da0: 6b 28 30 29 3b 0a 09 09 4c 49 53 54 5f 41 50 50 k(0);...LIST_APP
0db0: 45 4e 44 28 74 79 70 65 73 2c 20 73 74 79 70 65 END(types, stype
0dc0: 29 3b 0a 09 09 73 6c 61 62 5f 72 65 67 69 73 74 );...slab_regist
0dd0: 65 72 28 73 74 79 70 65 29 3b 0a 09 09 73 6c 61 er(stype);...sla
0de0: 62 5f 75 6e 6c 6f 63 6b 28 29 3b 0a 09 7d 0a 0a b_unlock();..}..
0df0: 09 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 61 6e 64 ./* Allocate and
0e00: 20 6d 61 70 20 70 61 67 65 20 2a 2f 0a 09 73 6c map page */..sl
0e10: 61 62 5f 74 20 2a 20 73 6c 61 62 20 3d 20 70 61 ab_t * slab = pa
0e20: 67 65 5f 68 65 61 70 5f 61 6c 6c 6f 63 28 29 3b ge_heap_alloc();
0e30: 0a 09 69 66 20 28 73 6c 61 62 29 20 7b 0a 09 09 ..if (slab) {...
0e40: 73 6c 61 62 2d 3e 6d 61 67 69 63 20 3d 20 73 74 slab->magic = st
0e50: 79 70 65 2d 3e 6d 61 67 69 63 3b 0a 09 09 73 6c ype->magic;...sl
0e60: 61 62 2d 3e 74 79 70 65 20 3d 20 73 74 79 70 65 ab->type = stype
0e70: 3b 0a 09 09 73 6c 61 62 2d 3e 61 76 61 69 6c 61 ;...slab->availa
0e80: 62 6c 65 20 3d 20 28 75 69 6e 74 33 32 5f 74 2a ble = (uint32_t*
0e90: 29 28 73 6c 61 62 2b 31 29 3b 0a 09 09 73 6c 61 )(slab+1);...sla
0ea0: 62 2d 3e 66 69 6e 61 6c 69 7a 65 20 3d 20 73 6c b->finalize = sl
0eb0: 61 62 2d 3e 61 76 61 69 6c 61 62 6c 65 20 2b 20 ab->available +
0ec0: 28 73 6c 61 62 2d 3e 74 79 70 65 2d 3e 63 6f 75 (slab->type->cou
0ed0: 6e 74 2b 33 32 29 2f 33 32 3b 0a 09 09 73 6c 61 nt+32)/32;...sla
0ee0: 62 2d 3e 64 61 74 61 20 3d 20 28 63 68 61 72 2a b->data = (char*
0ef0: 29 28 73 6c 61 62 2d 3e 66 69 6e 61 6c 69 7a 65 )(slab->finalize
0f00: 20 2b 20 28 73 6c 61 62 2d 3e 74 79 70 65 2d 3e + (slab->type->
0f10: 63 6f 75 6e 74 2b 33 32 29 2f 33 32 29 3b 0a 09 count+32)/32);..
0f20: 09 62 69 74 61 72 72 61 79 5f 73 65 74 61 6c 6c .bitarray_setall
0f30: 28 73 6c 61 62 2d 3e 61 76 61 69 6c 61 62 6c 65 (slab->available
0f40: 2c 20 73 74 79 70 65 2d 3e 63 6f 75 6e 74 2c 20 , stype->count,
0f50: 31 29 3b 0a 0a 09 09 4c 49 53 54 5f 50 52 45 50 1);....LIST_PREP
0f60: 45 4e 44 28 73 74 79 70 65 2d 3e 66 69 72 73 74 END(stype->first
0f70: 2c 20 73 6c 61 62 29 3b 0a 0a 09 09 61 73 73 65 , slab);....asse
0f80: 72 74 28 73 6c 61 62 2d 3e 74 79 70 65 29 3b 0a rt(slab->type);.
0f90: 09 7d 0a 0a 09 72 65 74 75 72 6e 20 73 6c 61 62 .}...return slab
0fa0: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 ;.}..static void
0fb0: 20 64 65 62 75 67 5f 66 69 6c 6c 62 75 66 28 76 debug_fillbuf(v
0fc0: 6f 69 64 20 2a 20 70 2c 20 73 69 7a 65 5f 74 20 oid * p, size_t
0fd0: 6c 2c 20 69 6e 74 20 63 29 0a 7b 0a 09 6d 65 6d l, int c).{..mem
0fe0: 73 65 74 28 70 2c 20 63 2c 20 6c 29 3b 0a 7d 0a set(p, c, l);.}.
0ff0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 64 65 62 .static void deb
1000: 75 67 5f 63 68 65 63 6b 62 75 66 28 76 6f 69 64 ug_checkbuf(void
1010: 20 2a 20 70 2c 20 73 69 7a 65 5f 74 20 6c 29 0a * p, size_t l).
1020: 7b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 20 {..const char *
1030: 63 70 20 3d 20 70 3b 0a 09 63 68 61 72 20 63 20 cp = p;..char c
1040: 3d 20 2a 63 70 3b 0a 0a 09 66 6f 72 28 69 6e 74 = *cp;...for(int
1050: 20 69 3d 30 3b 20 69 3c 6c 3b 20 69 2b 2b 29 0a i=0; i<l; i++).
1060: 09 7b 0a 09 09 69 66 20 28 63 20 21 3d 20 2a 63 .{...if (c != *c
1070: 70 29 20 7b 0a 09 09 09 6b 65 72 6e 65 6c 5f 70 p) {....kernel_p
1080: 61 6e 69 63 28 22 43 6f 72 72 75 70 74 65 64 20 anic("Corrupted
1090: 62 75 66 66 65 72 3a 20 25 70 22 2c 20 70 29 3b buffer: %p", p);
10a0: 0a 09 09 7d 0a 09 7d 0a 7d 0a 0a 0a 23 64 65 66 ...}..}.}...#def
10b0: 69 6e 65 20 53 4c 41 42 5f 53 4c 4f 54 28 73 6c ine SLAB_SLOT(sl
10c0: 61 62 2c 20 73 6c 6f 74 29 20 28 28 73 6c 61 62 ab, slot) ((slab
10d0: 5f 73 6c 6f 74 5f 74 2a 29 28 73 6c 61 62 2d 3e _slot_t*)(slab->
10e0: 64 61 74 61 20 2b 20 73 6c 61 62 2d 3e 74 79 70 data + slab->typ
10f0: 65 2d 3e 73 6c 6f 74 73 69 7a 65 2a 73 6c 6f 74 e->slotsize*slot
1100: 29 29 0a 23 64 65 66 69 6e 65 20 53 4c 41 42 5f )).#define SLAB_
1110: 53 4c 4f 54 5f 55 53 45 52 28 73 6c 61 62 2c 20 SLOT_USER(slab,
1120: 73 6c 6f 74 29 20 28 53 4c 41 42 5f 53 4c 4f 54 slot) (SLAB_SLOT
1130: 28 73 6c 61 62 2c 20 73 6c 6f 74 29 2b 31 29 0a (slab, slot)+1).
1140: 0a 23 69 66 20 31 0a 23 64 65 66 69 6e 65 20 53 .#if 1.#define S
1150: 4c 41 42 5f 53 4c 4f 54 5f 4e 55 4d 28 73 6c 61 LAB_SLOT_NUM(sla
1160: 62 2c 20 70 29 20 28 28 28 28 63 68 61 72 2a 29 b, p) ((((char*)
1170: 70 29 2d 73 6c 61 62 2d 3e 64 61 74 61 29 20 2f p)-slab->data) /
1180: 20 73 6c 61 62 2d 3e 74 79 70 65 2d 3e 73 6c 6f slab->type->slo
1190: 74 73 69 7a 65 29 0a 23 65 6c 73 65 0a 73 74 61 tsize).#else.sta
11a0: 74 69 63 20 69 6e 74 20 53 4c 41 42 5f 53 4c 4f tic int SLAB_SLO
11b0: 54 5f 4e 55 4d 28 73 6c 61 62 5f 74 20 2a 20 73 T_NUM(slab_t * s
11c0: 6c 61 62 2c 20 76 6f 69 64 20 2a 20 70 29 0a 7b lab, void * p).{
11d0: 0a 09 63 68 61 72 20 2a 20 75 73 65 72 20 3d 20 ..char * user =
11e0: 70 3b 0a 09 70 74 72 64 69 66 66 5f 74 20 64 69 p;..ptrdiff_t di
11f0: 66 66 20 3d 20 75 73 65 72 20 2d 20 73 6c 61 62 ff = user - slab
1200: 2d 3e 64 61 74 61 3b 0a 09 69 6e 74 20 73 6c 6f ->data;..int slo
1210: 74 20 3d 20 64 69 66 66 20 2f 20 73 6c 61 62 2d t = diff / slab-
1220: 3e 74 79 70 65 2d 3e 73 6c 6f 74 73 69 7a 65 3b >type->slotsize;
1230: 0a 09 61 73 73 65 72 74 28 73 6c 6f 74 3c 73 6c ..assert(slot<sl
1240: 61 62 2d 3e 74 79 70 65 2d 3e 63 6f 75 6e 74 29 ab->type->count)
1250: 3b 0a 09 72 65 74 75 72 6e 20 73 6c 6f 74 3b 0a ;..return slot;.
1260: 7d 0a 23 65 6e 64 69 66 0a 0a 76 6f 69 64 20 2a }.#endif..void *
1270: 20 73 6c 61 62 5f 61 6c 6c 6f 63 5f 70 28 73 6c slab_alloc_p(sl
1280: 61 62 5f 74 79 70 65 5f 74 20 2a 20 73 74 79 70 ab_type_t * styp
1290: 65 29 0a 7b 0a 09 73 74 61 74 69 63 20 75 6e 73 e).{..static uns
12a0: 69 67 6e 65 64 20 69 6e 74 20 73 65 71 20 3d 20 igned int seq =
12b0: 30 3b 0a 09 6d 75 74 65 78 5f 6c 6f 63 6b 28 73 0;..mutex_lock(s
12c0: 74 79 70 65 2d 3e 6c 6f 63 6b 29 3b 0a 09 73 6c type->lock);..sl
12d0: 61 62 5f 74 20 2a 20 73 6c 61 62 20 3d 20 73 74 ab_t * slab = st
12e0: 79 70 65 2d 3e 66 69 72 73 74 20 3f 20 73 74 79 ype->first ? sty
12f0: 70 65 2d 3e 66 69 72 73 74 20 3a 20 73 6c 61 62 pe->first : slab
1300: 5f 6e 65 77 28 73 74 79 70 65 29 3b 0a 0a 09 73 _new(stype);...s
1310: 6c 61 62 5f 6c 6f 63 6b 28 30 29 3b 0a 09 77 68 lab_lock(0);..wh
1320: 69 6c 65 28 73 6c 61 62 29 20 7b 0a 09 09 61 73 ile(slab) {...as
1330: 73 65 72 74 28 73 74 79 70 65 20 3d 3d 20 73 6c sert(stype == sl
1340: 61 62 2d 3e 74 79 70 65 29 3b 0a 09 09 69 6e 74 ab->type);...int
1350: 20 73 6c 6f 74 20 3d 20 62 69 74 61 72 72 61 79 slot = bitarray
1360: 5f 66 69 72 73 74 73 65 74 28 73 6c 61 62 2d 3e _firstset(slab->
1370: 61 76 61 69 6c 61 62 6c 65 2c 20 73 6c 61 62 2d available, slab-
1380: 3e 74 79 70 65 2d 3e 63 6f 75 6e 74 29 3b 0a 09 >type->count);..
1390: 09 61 73 73 65 72 74 28 73 6c 6f 74 3c 73 6c 61 .assert(slot<sla
13a0: 62 2d 3e 74 79 70 65 2d 3e 63 6f 75 6e 74 29 3b b->type->count);
13b0: 0a 09 09 69 66 20 28 73 6c 6f 74 3e 3d 30 29 20 ...if (slot>=0)
13c0: 7b 0a 09 09 09 69 66 20 28 62 69 74 61 72 72 61 {....if (bitarra
13d0: 79 5f 67 65 74 28 73 6c 61 62 2d 3e 66 69 6e 61 y_get(slab->fina
13e0: 6c 69 7a 65 2c 20 73 6c 6f 74 29 29 20 7b 0a 09 lize, slot)) {..
13f0: 09 09 09 6b 65 72 6e 65 6c 5f 62 72 65 61 6b 28 ...kernel_break(
1400: 29 3b 0a 09 09 09 7d 0a 09 09 09 62 69 74 61 72 );....}....bitar
1410: 72 61 79 5f 73 65 74 28 73 6c 61 62 2d 3e 61 76 ray_set(slab->av
1420: 61 69 6c 61 62 6c 65 2c 20 73 6c 6f 74 2c 20 30 ailable, slot, 0
1430: 29 3b 0a 09 09 09 2f 2f 62 69 74 61 72 72 61 79 );....//bitarray
1440: 5f 73 65 74 28 73 6c 61 62 2d 3e 66 69 6e 61 6c _set(slab->final
1450: 69 7a 65 2c 20 73 6c 6f 74 2c 20 30 29 3b 0a 09 ize, slot, 0);..
1460: 09 09 73 74 79 70 65 2d 3e 66 69 72 73 74 20 3d ..stype->first =
1470: 20 73 6c 61 62 3b 0a 09 09 09 73 6c 61 62 5f 75 slab;....slab_u
1480: 6e 6c 6f 63 6b 28 29 3b 0a 09 09 09 6d 75 74 65 nlock();....mute
1490: 78 5f 75 6e 6c 6f 63 6b 28 73 74 79 70 65 2d 3e x_unlock(stype->
14a0: 6c 6f 63 6b 29 3b 0a 09 09 09 73 6c 61 62 5f 73 lock);....slab_s
14b0: 6c 6f 74 5f 74 20 2a 20 65 6e 74 72 79 20 3d 20 lot_t * entry =
14c0: 53 4c 41 42 5f 53 4c 4f 54 28 73 6c 61 62 2c 20 SLAB_SLOT(slab,
14d0: 73 6c 6f 74 29 3b 0a 09 09 09 76 6f 69 64 20 2a slot);....void *
14e0: 20 70 20 3d 20 53 4c 41 42 5f 53 4c 4f 54 5f 55 p = SLAB_SLOT_U
14f0: 53 45 52 28 73 6c 61 62 2c 20 73 6c 6f 74 29 3b SER(slab, slot);
1500: 0a 09 09 09 61 73 73 65 72 74 28 70 3d 3d 28 76 ....assert(p==(v
1510: 6f 69 64 2a 29 28 65 6e 74 72 79 2b 31 29 29 3b oid*)(entry+1));
1520: 0a 09 09 09 53 4c 41 42 5f 53 4c 4f 54 28 73 6c ....SLAB_SLOT(sl
1530: 61 62 2c 20 73 6c 6f 74 29 2d 3e 73 65 71 20 3d ab, slot)->seq =
1540: 20 2b 2b 73 65 71 3b 0a 09 09 09 64 65 62 75 67 ++seq;....debug
1550: 5f 63 68 65 63 6b 62 75 66 28 70 2c 20 73 6c 61 _checkbuf(p, sla
1560: 62 2d 3e 74 79 70 65 2d 3e 65 73 69 7a 65 29 3b b->type->esize);
1570: 0a 09 09 09 64 65 62 75 67 5f 66 69 6c 6c 62 75 ....debug_fillbu
1580: 66 28 70 2c 20 73 6c 61 62 2d 3e 74 79 70 65 2d f(p, slab->type-
1590: 3e 65 73 69 7a 65 2c 20 30 78 30 61 29 3b 0a 09 >esize, 0x0a);..
15a0: 09 09 72 65 74 75 72 6e 20 70 3b 0a 09 09 7d 0a ..return p;...}.
15b0: 0a 09 09 4c 49 53 54 5f 4e 45 58 54 28 73 74 79 ...LIST_NEXT(sty
15c0: 70 65 2d 3e 66 69 72 73 74 2c 73 6c 61 62 29 3b pe->first,slab);
15d0: 0a 09 09 69 66 20 28 30 20 3d 3d 20 73 6c 61 62 ...if (0 == slab
15e0: 29 20 7b 0a 09 09 09 73 6c 61 62 20 3d 20 73 6c ) {....slab = sl
15f0: 61 62 5f 6e 65 77 28 73 74 79 70 65 29 3b 0a 09 ab_new(stype);..
1600: 09 7d 0a 09 7d 0a 0a 09 73 6c 61 62 5f 75 6e 6c .}..}...slab_unl
1610: 6f 63 6b 28 29 3b 0a 09 6d 75 74 65 78 5f 75 6e ock();..mutex_un
1620: 6c 6f 63 6b 28 73 74 79 70 65 2d 3e 6c 6f 63 6b lock(stype->lock
1630: 29 3b 0a 0a 09 4b 54 48 52 4f 57 28 4f 75 74 4f );...KTHROW(OutO
1640: 66 4d 65 6d 6f 72 79 45 78 63 65 70 74 69 6f 6e fMemoryException
1650: 2c 20 22 4f 75 74 20 6f 66 20 6d 65 6d 6f 72 79 , "Out of memory
1660: 22 29 3b 0a 7d 0a 0a 76 6f 69 64 20 2a 20 73 6c ");.}..void * sl
1670: 61 62 5f 63 61 6c 6c 6f 63 5f 70 28 73 6c 61 62 ab_calloc_p(slab
1680: 5f 74 79 70 65 5f 74 20 2a 20 73 74 79 70 65 29 _type_t * stype)
1690: 0a 7b 0a 09 76 6f 69 64 20 2a 20 70 20 3d 20 73 .{..void * p = s
16a0: 6c 61 62 5f 61 6c 6c 6f 63 5f 70 28 73 74 79 70 lab_alloc_p(styp
16b0: 65 29 3b 0a 09 6d 65 6d 73 65 74 28 70 2c 20 30 e);..memset(p, 0
16c0: 2c 20 73 74 79 70 65 2d 3e 65 73 69 7a 65 29 3b , stype->esize);
16d0: 0a 0a 09 72 65 74 75 72 6e 20 70 3b 0a 7d 0a 0a ...return p;.}..
16e0: 73 74 61 74 69 63 20 69 6e 74 20 73 6c 61 62 5f static int slab_
16f0: 61 6c 6c 5f 66 72 65 65 28 73 6c 61 62 5f 74 20 all_free(slab_t
1700: 2a 20 73 6c 61 62 29 0a 7b 0a 20 20 20 20 20 20 * slab).{.
1710: 20 20 66 6f 72 28 69 6e 74 20 69 3d 30 3b 20 69 for(int i=0; i
1720: 3c 73 6c 61 62 2d 3e 74 79 70 65 2d 3e 63 6f 75 <slab->type->cou
1730: 6e 74 3b 20 69 2b 3d 33 32 29 20 7b 0a 20 20 20 nt; i+=32) {.
1740: 20 20 20 20 20 20 20 20 20 20 20 20 20 75 69 6e uin
1750: 74 33 32 5f 74 20 6d 61 73 6b 20 3d 20 7e 30 20 t32_t mask = ~0
1760: 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ;.
1770: 20 20 69 66 20 28 73 6c 61 62 2d 3e 74 79 70 65 if (slab->type
1780: 2d 3e 63 6f 75 6e 74 2d 69 20 3c 20 33 32 29 20 ->count-i < 32)
1790: 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 {.
17a0: 20 20 20 20 20 20 20 20 20 20 6d 61 73 6b 20 3d mask =
17b0: 20 7e 28 6d 61 73 6b 20 3e 3e 20 28 73 6c 61 62 ~(mask >> (slab
17c0: 2d 3e 74 79 70 65 2d 3e 63 6f 75 6e 74 2d 69 29 ->type->count-i)
17d0: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 );.
17e0: 20 20 20 7d 0a 09 09 69 66 20 28 6d 61 73 6b 20 }...if (mask
17f0: 5e 20 73 6c 61 62 2d 3e 61 76 61 69 6c 61 62 6c ^ slab->availabl
1800: 65 5b 69 2f 33 32 5d 29 20 7b 0a 09 09 09 72 65 e[i/32]) {....re
1810: 74 75 72 6e 20 30 3b 0a 09 09 7d 0a 09 7d 0a 0a turn 0;...}..}..
1820: 09 72 65 74 75 72 6e 20 31 3b 0a 7d 0a 0a 76 6f .return 1;.}..vo
1830: 69 64 20 73 6c 61 62 5f 6e 6f 6d 61 72 6b 28 76 id slab_nomark(v
1840: 6f 69 64 20 2a 20 70 29 0a 7b 0a 09 2f 2a 20 44 oid * p).{../* D
1850: 6f 65 73 20 6e 6f 74 68 69 6e 67 20 2a 2f 0a 7d oes nothing */.}
1860: 0a 0a 67 63 5f 73 74 61 74 73 5f 74 20 67 63 5f ..gc_stats_t gc_
1870: 73 74 61 74 73 20 3d 20 7b 30 7d 3b 0a 0a 73 74 stats = {0};..st
1880: 61 74 69 63 20 73 74 72 75 63 74 20 67 63 63 6f atic struct gcco
1890: 6e 74 65 78 74 20 7b 0a 09 2f 2a 20 54 68 65 20 ntext {../* The
18a0: 62 6c 6f 63 6b 20 74 6f 20 62 65 20 73 63 61 6e block to be scan
18b0: 6e 65 64 20 2a 2f 0a 09 76 6f 69 64 20 2a 2a 20 ned */..void **
18c0: 66 72 6f 6d 3b 0a 09 76 6f 69 64 20 2a 2a 20 74 from;..void ** t
18d0: 6f 3b 0a 23 69 66 20 30 0a 09 2f 2a 20 50 72 65 o;.#if 0../* Pre
18e0: 76 69 6f 75 73 20 63 6f 6e 74 65 78 74 20 2a 2f vious context */
18f0: 0a 09 61 72 65 6e 61 5f 73 74 61 74 65 20 73 74 ..arena_state st
1900: 61 74 65 3b 0a 09 73 74 72 75 63 74 20 67 63 63 ate;..struct gcc
1910: 6f 6e 74 65 78 74 20 2a 20 70 72 65 76 3b 0a 23 ontext * prev;.#
1920: 65 6e 64 69 66 0a 7d 20 63 6f 6e 74 65 78 74 5b endif.} context[
1930: 32 35 36 5d 3b 0a 0a 73 74 61 74 69 63 20 69 6e 256];..static in
1940: 74 20 67 63 6c 65 76 65 6c 20 3d 20 30 3b 0a 0a t gclevel = 0;..
1950: 76 6f 69 64 20 73 6c 61 62 5f 67 63 5f 62 65 67 void slab_gc_beg
1960: 69 6e 28 29 0a 7b 0a 09 73 6c 61 62 5f 6c 6f 63 in().{..slab_loc
1970: 6b 28 31 29 3b 0a 09 73 6c 61 62 5f 74 79 70 65 k(1);..slab_type
1980: 5f 74 20 2a 20 73 74 79 70 65 20 3d 20 74 79 70 _t * stype = typ
1990: 65 73 3b 0a 0a 09 67 63 5f 73 74 61 74 73 2e 69 es;...gc_stats.i
19a0: 6e 75 73 65 20 3d 20 30 3b 0a 09 67 63 5f 73 74 nuse = 0;..gc_st
19b0: 61 74 73 2e 74 6f 74 61 6c 20 3d 20 30 3b 0a 0a ats.total = 0;..
19c0: 09 2f 2a 20 4d 61 72 6b 20 61 6c 6c 20 65 6c 65 ./* Mark all ele
19d0: 6d 65 6e 74 73 20 61 76 61 69 6c 61 62 6c 65 20 ments available
19e0: 2a 2f 0a 09 77 68 69 6c 65 28 73 74 79 70 65 29 */..while(stype)
19f0: 20 7b 0a 09 09 73 6c 61 62 5f 74 20 2a 20 73 6c {...slab_t * sl
1a00: 61 62 20 3d 20 73 74 79 70 65 2d 3e 66 69 72 73 ab = stype->firs
1a10: 74 3b 0a 0a 09 09 77 68 69 6c 65 28 73 6c 61 62 t;....while(slab
1a20: 29 20 7b 0a 09 09 09 67 63 5f 73 74 61 74 73 2e ) {....gc_stats.
1a30: 74 6f 74 61 6c 20 2b 3d 20 73 74 79 70 65 2d 3e total += stype->
1a40: 65 73 69 7a 65 20 2a 20 73 74 79 70 65 2d 3e 63 esize * stype->c
1a50: 6f 75 6e 74 3b 0a 09 09 09 2f 2a 20 50 72 6f 76 ount;..../* Prov
1a60: 69 73 69 6f 6e 61 6c 6c 79 20 66 69 6e 61 6c 69 isionally finali
1a70: 7a 65 20 61 6c 6c 20 61 6c 6c 6f 63 61 74 65 64 ze all allocated
1a80: 20 73 6c 6f 74 73 20 2a 2f 0a 09 09 09 62 69 74 slots */....bit
1a90: 61 72 72 61 79 5f 63 6f 70 79 28 73 6c 61 62 2d array_copy(slab-
1aa0: 3e 66 69 6e 61 6c 69 7a 65 2c 20 73 6c 61 62 2d >finalize, slab-
1ab0: 3e 61 76 61 69 6c 61 62 6c 65 2c 20 73 74 79 70 >available, styp
1ac0: 65 2d 3e 63 6f 75 6e 74 29 3b 0a 09 09 09 62 69 e->count);....bi
1ad0: 74 61 72 72 61 79 5f 69 6e 76 65 72 74 28 73 6c tarray_invert(sl
1ae0: 61 62 2d 3e 66 69 6e 61 6c 69 7a 65 2c 20 73 74 ab->finalize, st
1af0: 79 70 65 2d 3e 63 6f 75 6e 74 29 3b 0a 09 09 09 ype->count);....
1b00: 4c 49 53 54 5f 4e 45 58 54 28 73 74 79 70 65 2d LIST_NEXT(stype-
1b10: 3e 66 69 72 73 74 2c 20 73 6c 61 62 29 3b 0a 09 >first, slab);..
1b20: 09 7d 0a 0a 09 09 4c 49 53 54 5f 4e 45 58 54 28 .}....LIST_NEXT(
1b30: 74 79 70 65 73 2c 20 73 74 79 70 65 29 3b 0a 09 types, stype);..
1b40: 7d 0a 0a 09 2f 2a 20 50 75 74 20 74 68 65 20 72 }.../* Put the r
1b50: 6f 6f 74 73 20 69 6e 20 74 68 65 20 71 75 65 75 oots in the queu
1b60: 65 20 2a 2f 0a 09 65 78 74 65 72 6e 20 63 68 61 e */..extern cha
1b70: 72 20 67 63 72 6f 6f 74 5f 73 74 61 72 74 5b 5d r gcroot_start[]
1b80: 3b 0a 09 65 78 74 65 72 6e 20 63 68 61 72 20 67 ;..extern char g
1b90: 63 72 6f 6f 74 5f 65 6e 64 5b 5d 3b 0a 09 73 6c croot_end[];..sl
1ba0: 61 62 5f 67 63 5f 6d 61 72 6b 5f 72 61 6e 67 65 ab_gc_mark_range
1bb0: 28 67 63 72 6f 6f 74 5f 73 74 61 72 74 2c 20 67 (gcroot_start, g
1bc0: 63 72 6f 6f 74 5f 65 6e 64 29 3b 0a 7d 0a 0a 73 croot_end);.}..s
1bd0: 74 61 74 69 63 20 73 6c 61 62 5f 74 20 2a 20 73 tatic slab_t * s
1be0: 6c 61 62 5f 67 65 74 28 76 6f 69 64 20 2a 20 70 lab_get(void * p
1bf0: 29 0a 7b 0a 09 69 66 20 28 61 72 63 68 5f 69 73 ).{..if (arch_is
1c00: 5f 68 65 61 70 5f 70 6f 69 6e 74 65 72 28 70 29 _heap_pointer(p)
1c10: 29 20 7b 0a 09 09 2f 2a 20 43 68 65 63 6b 20 6d ) {.../* Check m
1c20: 61 67 69 63 20 6e 75 6d 62 65 72 73 20 2a 2f 0a agic numbers */.
1c30: 09 09 73 6c 61 62 5f 74 20 2a 20 73 6c 61 62 20 ..slab_t * slab
1c40: 3d 20 41 52 43 48 5f 50 41 47 45 5f 41 4c 49 47 = ARCH_PAGE_ALIG
1c50: 4e 28 70 29 3b 0a 0a 09 09 69 66 20 28 73 6c 61 N(p);....if (sla
1c60: 62 20 3d 3d 20 41 52 43 48 5f 50 41 47 45 5f 41 b == ARCH_PAGE_A
1c70: 4c 49 47 4e 28 73 6c 61 62 2d 3e 64 61 74 61 29 LIGN(slab->data)
1c80: 20 26 26 20 73 6c 61 62 5f 76 61 6c 69 64 28 73 && slab_valid(s
1c90: 6c 61 62 2d 3e 74 79 70 65 29 20 26 26 20 73 6c lab->type) && sl
1ca0: 61 62 2d 3e 6d 61 67 69 63 20 3d 3d 20 73 6c 61 ab->magic == sla
1cb0: 62 2d 3e 74 79 70 65 2d 3e 6d 61 67 69 63 20 26 b->type->magic &
1cc0: 26 20 28 73 6c 61 62 5f 73 6c 6f 74 5f 74 2a 29 & (slab_slot_t*)
1cd0: 73 6c 61 62 2d 3e 64 61 74 61 20 3c 3d 20 28 73 slab->data <= (s
1ce0: 6c 61 62 5f 73 6c 6f 74 5f 74 2a 29 70 29 20 7b lab_slot_t*)p) {
1cf0: 0a 09 09 09 72 65 74 75 72 6e 20 73 6c 61 62 3b ....return slab;
1d00: 0a 09 09 7d 0a 09 7d 0a 0a 09 72 65 74 75 72 6e ...}..}...return
1d10: 20 30 3b 0a 7d 0a 0a 76 6f 69 64 20 73 6c 61 62 0;.}..void slab
1d20: 5f 67 63 5f 6d 61 72 6b 28 76 6f 69 64 20 2a 20 _gc_mark(void *
1d30: 72 6f 6f 74 29 0a 7b 0a 09 73 6c 61 62 5f 74 20 root).{..slab_t
1d40: 2a 20 73 6c 61 62 20 3d 20 73 6c 61 62 5f 67 65 * slab = slab_ge
1d50: 74 28 72 6f 6f 74 29 3b 0a 09 69 66 20 28 73 6c t(root);..if (sl
1d60: 61 62 29 20 7b 0a 09 09 2f 2a 20 45 6e 74 72 79 ab) {.../* Entry
1d70: 20 77 69 74 68 69 6e 20 74 68 65 20 73 6c 61 62 within the slab
1d80: 20 2a 2f 0a 09 09 69 6e 74 20 73 6c 6f 74 20 3d */...int slot =
1d90: 20 53 4c 41 42 5f 53 4c 4f 54 5f 4e 55 4d 28 73 SLAB_SLOT_NUM(s
1da0: 6c 61 62 2c 20 72 6f 6f 74 29 3b 0a 09 09 69 66 lab, root);...if
1db0: 20 28 73 6c 6f 74 3e 3d 73 6c 61 62 2d 3e 74 79 (slot>=slab->ty
1dc0: 70 65 2d 3e 63 6f 75 6e 74 29 20 7b 0a 09 09 09 pe->count) {....
1dd0: 2f 2a 20 4e 6f 74 20 61 20 76 61 6c 69 64 20 70 /* Not a valid p
1de0: 6f 69 6e 74 65 72 20 2d 20 64 6f 6e 27 74 20 6d ointer - don't m
1df0: 61 72 6b 20 2a 2f 0a 09 09 09 72 65 74 75 72 6e ark */....return
1e00: 3b 0a 09 09 7d 0a 09 09 61 73 73 65 72 74 28 73 ;...}...assert(s
1e10: 6c 6f 74 3c 73 6c 61 62 2d 3e 74 79 70 65 2d 3e lot<slab->type->
1e20: 63 6f 75 6e 74 29 3b 0a 0a 09 09 2f 2a 20 41 64 count);..../* Ad
1e30: 6a 75 73 74 20 72 6f 6f 74 20 74 6f 20 70 6f 69 just root to poi
1e40: 6e 74 20 74 6f 20 74 68 65 20 73 74 61 72 74 20 nt to the start
1e50: 6f 66 20 74 68 65 20 73 6c 61 62 20 73 6c 6f 74 of the slab slot
1e60: 20 2a 2f 0a 09 09 72 6f 6f 74 20 3d 20 53 4c 41 */...root = SLA
1e70: 42 5f 53 4c 4f 54 5f 55 53 45 52 28 73 6c 61 62 B_SLOT_USER(slab
1e80: 2c 20 73 6c 6f 74 29 3b 0a 0a 09 09 69 66 20 28 , slot);....if (
1e90: 62 69 74 61 72 72 61 79 5f 67 65 74 28 73 6c 61 bitarray_get(sla
1ea0: 62 2d 3e 66 69 6e 61 6c 69 7a 65 2c 20 73 6c 6f b->finalize, slo
1eb0: 74 29 29 20 7b 0a 09 09 09 2f 2a 20 4d 61 72 6b t)) {..../* Mark
1ec0: 65 64 20 66 6f 72 20 66 69 6e 61 6c 69 7a 61 74 ed for finalizat
1ed0: 69 6f 6e 2c 20 63 6c 65 61 72 20 74 68 65 20 6d ion, clear the m
1ee0: 61 72 6b 20 2a 2f 0a 09 09 09 62 69 74 61 72 72 ark */....bitarr
1ef0: 61 79 5f 73 65 74 28 73 6c 61 62 2d 3e 66 69 6e ay_set(slab->fin
1f00: 61 6c 69 7a 65 2c 20 73 6c 6f 74 2c 20 30 29 3b alize, slot, 0);
1f10: 0a 09 09 09 67 63 5f 73 74 61 74 73 2e 69 6e 75 ....gc_stats.inu
1f20: 73 65 20 2b 3d 20 73 6c 61 62 2d 3e 74 79 70 65 se += slab->type
1f30: 2d 3e 65 73 69 7a 65 3b 0a 0a 09 09 09 69 66 20 ->esize;.....if
1f40: 28 73 6c 61 62 2d 3e 74 79 70 65 2d 3e 6d 61 72 (slab->type->mar
1f50: 6b 29 20 7b 0a 09 09 09 09 2f 2a 20 43 61 6c 6c k) {...../* Call
1f60: 20 74 79 70 65 20 73 70 65 63 69 66 69 63 20 6d type specific m
1f70: 61 72 6b 20 2a 2f 0a 09 09 09 09 73 6c 61 62 2d ark */.....slab-
1f80: 3e 74 79 70 65 2d 3e 6d 61 72 6b 28 72 6f 6f 74 >type->mark(root
1f90: 29 3b 0a 09 09 09 7d 20 65 6c 73 65 20 7b 0a 09 );....} else {..
1fa0: 09 09 09 2f 2a 20 47 65 6e 65 72 69 63 20 6d 61 .../* Generic ma
1fb0: 72 6b 20 2a 2f 0a 09 09 09 09 73 6c 61 62 5f 67 rk */.....slab_g
1fc0: 63 5f 6d 61 72 6b 5f 62 6c 6f 63 6b 28 72 6f 6f c_mark_block(roo
1fd0: 74 2c 20 73 6c 61 62 2d 3e 74 79 70 65 2d 3e 65 t, slab->type->e
1fe0: 73 69 7a 65 29 3b 0a 09 09 09 7d 0a 09 09 7d 0a size);....}...}.
1ff0: 09 7d 0a 7d 0a 0a 76 6f 69 64 20 73 6c 61 62 5f .}.}..void slab_
2000: 67 63 5f 6d 61 72 6b 5f 72 61 6e 67 65 28 76 6f gc_mark_range(vo
2010: 69 64 20 2a 20 66 72 6f 6d 2c 20 76 6f 69 64 20 id * from, void
2020: 2a 20 74 6f 29 0a 7b 0a 09 67 63 6c 65 76 65 6c * to).{..gclevel
2030: 2b 2b 3b 0a 09 61 73 73 65 72 74 28 67 63 6c 65 ++;..assert(gcle
2040: 76 65 6c 3c 63 6f 75 6e 74 6f 66 28 63 6f 6e 74 vel<countof(cont
2050: 65 78 74 29 29 3b 0a 09 63 6f 6e 74 65 78 74 5b ext));..context[
2060: 67 63 6c 65 76 65 6c 5d 2e 66 72 6f 6d 20 3d 20 gclevel].from =
2070: 66 72 6f 6d 3b 0a 09 63 6f 6e 74 65 78 74 5b 67 from;..context[g
2080: 63 6c 65 76 65 6c 5d 2e 74 6f 20 3d 20 74 6f 3b clevel].to = to;
2090: 0a 7d 0a 0a 76 6f 69 64 20 73 6c 61 62 5f 67 63 .}..void slab_gc
20a0: 28 29 0a 7b 0a 09 6d 75 74 65 78 5f 74 20 6c 6f ().{..mutex_t lo
20b0: 63 6b 5b 31 5d 20 3d 20 7b 30 7d 3b 0a 0a 09 4d ck[1] = {0};...M
20c0: 55 54 45 58 5f 41 55 54 4f 4c 4f 43 4b 28 6c 6f UTEX_AUTOLOCK(lo
20d0: 63 6b 29 20 7b 0a 09 09 77 68 69 6c 65 28 67 63 ck) {...while(gc
20e0: 6c 65 76 65 6c 29 20 7b 0a 09 09 09 2f 2a 20 43 level) {..../* C
20f0: 68 65 63 6b 20 74 68 65 20 6e 65 78 74 20 70 6f heck the next po
2100: 69 6e 74 65 72 20 69 6e 20 74 68 65 20 62 6c 6f inter in the blo
2110: 63 6b 20 2a 2f 0a 09 09 09 69 66 20 28 63 6f 6e ck */....if (con
2120: 74 65 78 74 5b 67 63 6c 65 76 65 6c 5d 2e 66 72 text[gclevel].fr
2130: 6f 6d 20 26 26 20 63 6f 6e 74 65 78 74 5b 67 63 om && context[gc
2140: 6c 65 76 65 6c 5d 2e 66 72 6f 6d 20 3c 20 63 6f level].from < co
2150: 6e 74 65 78 74 5b 67 63 6c 65 76 65 6c 5d 2e 74 ntext[gclevel].t
2160: 6f 29 20 7b 0a 09 09 09 09 73 6c 61 62 5f 67 63 o) {.....slab_gc
2170: 5f 6d 61 72 6b 28 2a 63 6f 6e 74 65 78 74 5b 67 _mark(*context[g
2180: 63 6c 65 76 65 6c 5d 2e 66 72 6f 6d 2b 2b 29 3b clevel].from++);
2190: 0a 09 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 ....} else {....
21a0: 09 63 6f 6e 74 65 78 74 5b 67 63 6c 65 76 65 6c .context[gclevel
21b0: 5d 2e 66 72 6f 6d 20 3d 20 63 6f 6e 74 65 78 74 ].from = context
21c0: 5b 67 63 6c 65 76 65 6c 5d 2e 74 6f 20 3d 20 30 [gclevel].to = 0
21d0: 3b 0a 09 09 09 09 67 63 6c 65 76 65 6c 2d 2d 3b ;.....gclevel--;
21e0: 0a 09 09 09 7d 0a 09 09 7d 0a 09 7d 0a 7d 0a 0a ....}...}..}.}..
21f0: 76 6f 69 64 20 73 6c 61 62 5f 67 63 5f 6d 61 72 void slab_gc_mar
2200: 6b 5f 62 6c 6f 63 6b 28 76 6f 69 64 20 2a 2a 20 k_block(void **
2210: 62 6c 6f 63 6b 2c 20 73 69 7a 65 5f 74 20 73 69 block, size_t si
2220: 7a 65 29 0a 7b 0a 09 73 6c 61 62 5f 67 63 5f 6d ze).{..slab_gc_m
2230: 61 72 6b 5f 72 61 6e 67 65 28 62 6c 6f 63 6b 2c ark_range(block,
2240: 20 62 6c 6f 63 6b 20 2b 20 73 69 7a 65 2f 73 69 block + size/si
2250: 7a 65 6f 66 28 2a 62 6c 6f 63 6b 29 29 3b 0a 7d zeof(*block));.}
2260: 0a 0a 76 6f 69 64 20 73 6c 61 62 5f 67 63 5f 65 ..void slab_gc_e
2270: 6e 64 28 29 0a 7b 0a 09 69 66 20 28 67 63 5f 73 nd().{..if (gc_s
2280: 74 61 74 73 2e 69 6e 75 73 65 20 3e 3d 20 67 63 tats.inuse >= gc
2290: 5f 73 74 61 74 73 2e 70 65 61 6b 29 20 7b 0a 09 _stats.peak) {..
22a0: 09 67 63 5f 73 74 61 74 73 2e 70 65 61 6b 20 3d .gc_stats.peak =
22b0: 20 67 63 5f 73 74 61 74 73 2e 69 6e 75 73 65 3b gc_stats.inuse;
22c0: 0a 09 7d 0a 0a 09 2f 2a 20 46 69 6e 61 6c 69 7a ..}.../* Finaliz
22d0: 65 20 65 6c 65 6d 65 6e 74 73 20 6e 6f 77 20 61 e elements now a
22e0: 76 61 69 6c 61 62 6c 65 20 2a 2f 0a 09 73 6c 61 vailable */..sla
22f0: 62 5f 74 79 70 65 5f 74 20 2a 20 73 74 79 70 65 b_type_t * stype
2300: 20 3d 20 74 79 70 65 73 3b 0a 09 77 68 69 6c 65 = types;..while
2310: 28 73 74 79 70 65 29 20 7b 0a 09 09 73 6c 61 62 (stype) {...slab
2320: 5f 74 20 2a 20 73 6c 61 62 20 3d 20 73 74 79 70 _t * slab = styp
2330: 65 2d 3e 66 69 72 73 74 3b 0a 0a 09 09 77 68 69 e->first;....whi
2340: 6c 65 28 73 6c 61 62 29 20 7b 0a 09 09 09 2f 2a le(slab) {..../*
2350: 20 53 74 65 70 20 74 68 72 6f 75 67 68 20 65 61 Step through ea
2360: 63 68 20 66 69 6e 61 6c 69 7a 61 62 6c 65 20 73 ch finalizable s
2370: 6c 6f 74 20 2a 2f 0a 09 09 09 69 6e 74 20 73 6c lot */....int sl
2380: 6f 74 3d 62 69 74 61 72 72 61 79 5f 66 69 72 73 ot=bitarray_firs
2390: 74 73 65 74 28 73 6c 61 62 2d 3e 66 69 6e 61 6c tset(slab->final
23a0: 69 7a 65 2c 20 73 74 79 70 65 2d 3e 63 6f 75 6e ize, stype->coun
23b0: 74 29 3b 0a 09 09 09 77 68 69 6c 65 28 73 6c 6f t);....while(slo
23c0: 74 3e 3d 30 29 20 7b 0a 09 09 09 09 73 6c 61 62 t>=0) {.....slab
23d0: 5f 73 6c 6f 74 5f 74 20 2a 20 65 6e 74 72 79 20 _slot_t * entry
23e0: 3d 20 53 4c 41 42 5f 53 4c 4f 54 28 73 6c 61 62 = SLAB_SLOT(slab
23f0: 2c 20 73 6c 6f 74 29 3b 0a 09 09 09 09 69 66 20 , slot);.....if
2400: 28 73 74 79 70 65 2d 3e 66 69 6e 61 6c 69 7a 65 (stype->finalize
2410: 29 20 7b 0a 09 09 09 09 09 73 6c 61 62 2d 3e 74 ) {......slab->t
2420: 79 70 65 2d 3e 66 69 6e 61 6c 69 7a 65 28 53 4c ype->finalize(SL
2430: 41 42 5f 53 4c 4f 54 5f 55 53 45 52 28 73 6c 61 AB_SLOT_USER(sla
2440: 62 2c 20 73 6c 6f 74 29 29 3b 0a 09 09 09 09 7d b, slot));.....}
2450: 0a 09 09 09 09 64 65 62 75 67 5f 66 69 6c 6c 62 .....debug_fillb
2460: 75 66 28 65 6e 74 72 79 2b 31 2c 20 73 6c 61 62 uf(entry+1, slab
2470: 2d 3e 74 79 70 65 2d 3e 65 73 69 7a 65 2c 20 30 ->type->esize, 0
2480: 78 63 30 29 3b 0a 09 09 09 09 65 6e 74 72 79 2d xc0);.....entry-
2490: 3e 73 65 71 20 3d 20 30 3b 0a 09 09 09 09 62 69 >seq = 0;.....bi
24a0: 74 61 72 72 61 79 5f 73 65 74 28 73 6c 61 62 2d tarray_set(slab-
24b0: 3e 66 69 6e 61 6c 69 7a 65 2c 20 73 6c 6f 74 2c >finalize, slot,
24c0: 20 30 29 3b 0a 09 09 09 09 62 69 74 61 72 72 61 0);.....bitarra
24d0: 79 5f 73 65 74 28 73 6c 61 62 2d 3e 61 76 61 69 y_set(slab->avai
24e0: 6c 61 62 6c 65 2c 20 73 6c 6f 74 2c 20 31 29 3b lable, slot, 1);
24f0: 0a 09 09 09 09 73 6c 6f 74 3d 62 69 74 61 72 72 .....slot=bitarr
2500: 61 79 5f 66 69 72 73 74 73 65 74 28 73 6c 61 62 ay_firstset(slab
2510: 2d 3e 66 69 6e 61 6c 69 7a 65 2c 20 73 74 79 70 ->finalize, styp
2520: 65 2d 3e 63 6f 75 6e 74 29 3b 0a 09 09 09 7d 0a e->count);....}.
2530: 0a 09 09 09 2f 2a 20 52 65 6c 65 61 73 65 20 70 ..../* Release p
2540: 61 67 65 20 69 66 20 6e 6f 77 20 65 6d 70 74 79 age if now empty
2550: 20 2a 2f 0a 09 09 09 69 66 20 28 30 20 26 26 20 */....if (0 &&
2560: 73 6c 61 62 5f 61 6c 6c 5f 66 72 65 65 28 73 6c slab_all_free(sl
2570: 61 62 29 29 20 7b 0a 09 09 09 09 73 6c 61 62 5f ab)) {.....slab_
2580: 74 20 2a 20 65 6d 70 74 79 20 3d 20 73 6c 61 62 t * empty = slab
2590: 3b 0a 09 09 09 09 4c 49 53 54 5f 4e 45 58 54 28 ;.....LIST_NEXT(
25a0: 73 74 79 70 65 2d 3e 66 69 72 73 74 2c 20 73 6c stype->first, sl
25b0: 61 62 29 3b 0a 09 09 09 09 4c 49 53 54 5f 44 45 ab);.....LIST_DE
25c0: 4c 45 54 45 28 73 74 79 70 65 2d 3e 66 69 72 73 LETE(stype->firs
25d0: 74 2c 20 65 6d 70 74 79 29 3b 0a 09 09 09 09 70 t, empty);.....p
25e0: 61 67 65 5f 68 65 61 70 5f 66 72 65 65 28 65 6d age_heap_free(em
25f0: 70 74 79 29 3b 0a 09 09 09 7d 20 65 6c 73 65 20 pty);....} else
2600: 7b 0a 09 09 09 09 4c 49 53 54 5f 4e 45 58 54 28 {.....LIST_NEXT(
2610: 73 74 79 70 65 2d 3e 66 69 72 73 74 2c 20 73 6c stype->first, sl
2620: 61 62 29 3b 0a 09 09 09 7d 0a 09 09 7d 0a 0a 09 ab);....}...}...
2630: 09 4c 49 53 54 5f 4e 45 58 54 28 74 79 70 65 73 .LIST_NEXT(types
2640: 2c 20 73 74 79 70 65 29 3b 0a 09 7d 0a 09 73 6c , stype);..}..sl
2650: 61 62 5f 75 6e 6c 6f 63 6b 28 29 3b 0a 7d 0a 0a ab_unlock();.}..
2660: 73 74 61 74 69 63 20 76 6f 69 64 20 73 6c 61 62 static void slab
2670: 5f 74 65 73 74 5f 66 69 6e 61 6c 69 7a 65 28 76 _test_finalize(v
2680: 6f 69 64 20 2a 20 70 29 0a 7b 0a 09 6b 65 72 6e oid * p).{..kern
2690: 65 6c 5f 70 72 69 6e 74 6b 28 22 46 69 6e 61 6c el_printk("Final
26a0: 69 7a 69 6e 67 3a 20 25 70 5c 6e 22 2c 20 70 29 izing: %p\n", p)
26b0: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 ;.}..static void
26c0: 20 73 6c 61 62 5f 74 65 73 74 5f 6d 61 72 6b 28 slab_test_mark(
26d0: 76 6f 69 64 20 2a 70 29 0a 7b 0a 09 6b 65 72 6e void *p).{..kern
26e0: 65 6c 5f 70 72 69 6e 74 6b 28 22 4d 61 72 6b 69 el_printk("Marki
26f0: 6e 67 3a 20 25 70 5c 6e 22 2c 20 70 29 3b 0a 7d ng: %p\n", p);.}
2700: 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 73 6c ..static void sl
2710: 61 62 5f 77 65 61 6b 72 65 66 5f 6d 61 72 6b 28 ab_weakref_mark(
2720: 76 6f 69 64 20 2a 20 70 29 0a 7b 0a 09 73 6c 61 void * p).{..sla
2730: 62 5f 77 65 61 6b 72 65 66 5f 74 20 2a 20 72 65 b_weakref_t * re
2740: 66 20 3d 20 28 73 6c 61 62 5f 77 65 61 6b 72 65 f = (slab_weakre
2750: 66 5f 74 2a 29 70 3b 0a 09 69 66 20 28 72 65 66 f_t*)p;..if (ref
2760: 2d 3e 63 68 61 6e 63 65 73 29 20 7b 0a 09 09 72 ->chances) {...r
2770: 65 66 2d 3e 63 68 61 6e 63 65 73 2d 2d 3b 0a 09 ef->chances--;..
2780: 09 73 6c 61 62 5f 67 63 5f 6d 61 72 6b 28 72 65 .slab_gc_mark(re
2790: 66 2d 3e 70 29 3b 0a 09 7d 0a 7d 0a 0a 73 6c 61 f->p);..}.}..sla
27a0: 62 5f 77 65 61 6b 72 65 66 5f 74 20 2a 20 73 6c b_weakref_t * sl
27b0: 61 62 5f 77 65 61 6b 72 65 66 28 76 6f 69 64 20 ab_weakref(void
27c0: 2a 20 70 29 0a 7b 0a 09 73 74 61 74 69 63 20 73 * p).{..static s
27d0: 6c 61 62 5f 74 79 70 65 5f 74 20 77 65 61 6b 72 lab_type_t weakr
27e0: 65 66 73 5b 5d 20 3d 20 7b 0a 09 09 53 4c 41 42 efs[] = {...SLAB
27f0: 5f 54 59 50 45 28 73 69 7a 65 6f 66 28 73 6c 61 _TYPE(sizeof(sla
2800: 62 5f 77 65 61 6b 72 65 66 5f 74 29 2c 20 73 6c b_weakref_t), sl
2810: 61 62 5f 77 65 61 6b 72 65 66 5f 6d 61 72 6b 2c ab_weakref_mark,
2820: 20 30 29 2c 0a 09 7d 3b 0a 09 73 74 61 74 69 63 0),..};..static
2830: 20 73 6c 61 62 5f 77 65 61 6b 72 65 66 5f 74 20 slab_weakref_t
2840: 6e 75 6c 6c 72 65 66 5b 5d 20 3d 20 7b 30 7d 3b nullref[] = {0};
2850: 0a 0a 09 73 6c 61 62 5f 74 20 2a 20 73 6c 61 62 ...slab_t * slab
2860: 20 3d 20 73 6c 61 62 5f 67 65 74 28 70 29 3b 0a = slab_get(p);.
2870: 09 69 66 20 28 73 6c 61 62 29 20 7b 0a 09 09 73 .if (slab) {...s
2880: 6c 61 62 5f 77 65 61 6b 72 65 66 5f 74 20 2a 20 lab_weakref_t *
2890: 72 65 66 20 3d 20 73 6c 61 62 5f 61 6c 6c 6f 63 ref = slab_alloc
28a0: 28 77 65 61 6b 72 65 66 73 29 3b 0a 09 09 69 6e (weakrefs);...in
28b0: 74 20 73 6c 6f 74 20 3d 20 53 4c 41 42 5f 53 4c t slot = SLAB_SL
28c0: 4f 54 5f 4e 55 4d 28 73 6c 61 62 2c 20 70 29 3b OT_NUM(slab, p);
28d0: 0a 09 09 72 65 66 2d 3e 73 65 71 20 3d 20 53 4c ...ref->seq = SL
28e0: 41 42 5f 53 4c 4f 54 28 73 6c 61 62 2c 20 73 6c AB_SLOT(slab, sl
28f0: 6f 74 29 2d 3e 73 65 71 3b 0a 09 09 72 65 66 2d ot)->seq;...ref-
2900: 3e 70 20 3d 20 70 3b 0a 09 09 72 65 66 2d 3e 63 >p = p;...ref->c
2910: 68 61 6e 63 65 73 3d 30 3b 0a 0a 09 09 72 65 74 hances=0;....ret
2920: 75 72 6e 20 72 65 66 3b 0a 09 7d 0a 0a 09 72 65 urn ref;..}...re
2930: 74 75 72 6e 20 6e 75 6c 6c 72 65 66 3b 0a 7d 0a turn nullref;.}.
2940: 0a 76 6f 69 64 20 2a 20 73 6c 61 62 5f 77 65 61 .void * slab_wea
2950: 6b 72 65 66 5f 67 65 74 28 73 6c 61 62 5f 77 65 kref_get(slab_we
2960: 61 6b 72 65 66 5f 74 20 2a 20 72 65 66 29 0a 7b akref_t * ref).{
2970: 0a 09 73 6c 61 62 5f 74 20 2a 20 73 6c 61 62 20 ..slab_t * slab
2980: 3d 20 73 6c 61 62 5f 67 65 74 28 72 65 66 2d 3e = slab_get(ref->
2990: 70 29 3b 0a 09 69 66 20 28 73 6c 61 62 29 20 7b p);..if (slab) {
29a0: 0a 09 09 69 6e 74 20 73 6c 6f 74 20 3d 20 53 4c ...int slot = SL
29b0: 41 42 5f 53 4c 4f 54 5f 4e 55 4d 28 73 6c 61 62 AB_SLOT_NUM(slab
29c0: 2c 20 72 65 66 2d 3e 70 29 3b 0a 09 09 69 66 20 , ref->p);...if
29d0: 28 72 65 66 2d 3e 73 65 71 20 3d 3d 20 53 4c 41 (ref->seq == SLA
29e0: 42 5f 53 4c 4f 54 28 73 6c 61 62 2c 20 73 6c 6f B_SLOT(slab, slo
29f0: 74 29 2d 3e 73 65 71 29 20 7b 0a 09 09 09 72 65 t)->seq) {....re
2a00: 74 75 72 6e 20 72 65 66 2d 3e 70 3b 0a 09 09 7d turn ref->p;...}
2a10: 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 20 30 3b 0a ..}...return 0;.
2a20: 7d 0a 0a 23 64 65 66 69 6e 65 20 53 4c 41 42 5f }..#define SLAB_
2a30: 4d 41 58 5f 44 41 54 41 5f 41 52 45 41 28 73 6c MAX_DATA_AREA(sl
2a40: 6f 74 73 29 20 52 4f 55 4e 44 44 4f 57 4e 28 28 ots) ROUNDDOWN((
2a50: 28 28 41 52 43 48 5f 50 41 47 45 5f 53 49 5a 45 ((ARCH_PAGE_SIZE
2a60: 2d 73 69 7a 65 6f 66 28 73 6c 61 62 5f 74 29 2d -sizeof(slab_t)-
2a70: 32 2a 73 69 7a 65 6f 66 28 75 69 6e 74 33 32 5f 2*sizeof(uint32_
2a80: 74 29 29 2f 73 6c 6f 74 73 29 2d 73 69 7a 65 6f t))/slots)-sizeo
2a90: 66 28 73 6c 61 62 5f 73 6c 6f 74 5f 74 29 29 2c f(slab_slot_t)),
2aa0: 38 29 0a 73 74 61 74 69 63 20 73 6c 61 62 5f 74 8).static slab_t
2ab0: 79 70 65 5f 74 20 70 6f 6f 6c 73 5b 5d 20 3d 20 ype_t pools[] =
2ac0: 7b 0a 09 53 4c 41 42 5f 54 59 50 45 28 38 2c 20 {..SLAB_TYPE(8,
2ad0: 30 2c 20 30 29 2c 0a 09 53 4c 41 42 5f 54 59 50 0, 0),..SLAB_TYP
2ae0: 45 28 31 32 2c 20 30 2c 20 30 29 2c 0a 09 53 4c E(12, 0, 0),..SL
2af0: 41 42 5f 54 59 50 45 28 31 36 2c 20 30 2c 20 30 AB_TYPE(16, 0, 0
2b00: 29 2c 0a 09 53 4c 41 42 5f 54 59 50 45 28 32 34 ),..SLAB_TYPE(24
2b10: 2c 20 30 2c 20 30 29 2c 0a 09 53 4c 41 42 5f 54 , 0, 0),..SLAB_T
2b20: 59 50 45 28 33 32 2c 20 30 2c 20 30 29 2c 0a 09 YPE(32, 0, 0),..
2b30: 53 4c 41 42 5f 54 59 50 45 28 34 38 2c 20 30 2c SLAB_TYPE(48, 0,
2b40: 20 30 29 2c 0a 09 53 4c 41 42 5f 54 59 50 45 28 0),..SLAB_TYPE(
2b50: 36 34 2c 20 30 2c 20 30 29 2c 0a 09 53 4c 41 42 64, 0, 0),..SLAB
2b60: 5f 54 59 50 45 28 39 36 2c 20 30 2c 20 30 29 2c _TYPE(96, 0, 0),
2b70: 0a 09 53 4c 41 42 5f 54 59 50 45 28 31 32 38 2c ..SLAB_TYPE(128,
2b80: 20 30 2c 20 30 29 2c 0a 09 53 4c 41 42 5f 54 59 0, 0),..SLAB_TY
2b90: 50 45 28 31 39 36 2c 20 30 2c 20 30 29 2c 0a 09 PE(196, 0, 0),..
2ba0: 53 4c 41 42 5f 54 59 50 45 28 32 35 36 2c 20 30 SLAB_TYPE(256, 0
2bb0: 2c 20 30 29 2c 0a 09 53 4c 41 42 5f 54 59 50 45 , 0),..SLAB_TYPE
2bc0: 28 33 38 34 2c 20 30 2c 20 30 29 2c 0a 09 53 4c (384, 0, 0),..SL
2bd0: 41 42 5f 54 59 50 45 28 35 31 32 2c 20 30 2c 20 AB_TYPE(512, 0,
2be0: 30 29 2c 0a 09 53 4c 41 42 5f 54 59 50 45 28 37 0),..SLAB_TYPE(7
2bf0: 36 38 2c 20 30 2c 20 30 29 2c 0a 09 53 4c 41 42 68, 0, 0),..SLAB
2c00: 5f 54 59 50 45 28 31 30 32 34 2c 20 30 2c 20 30 _TYPE(1024, 0, 0
2c10: 29 2c 0a 09 53 4c 41 42 5f 54 59 50 45 28 53 4c ),..SLAB_TYPE(SL
2c20: 41 42 5f 4d 41 58 5f 44 41 54 41 5f 41 52 45 41 AB_MAX_DATA_AREA
2c30: 28 33 29 2c 20 30 2c 20 30 29 2c 0a 09 53 4c 41 (3), 0, 0),..SLA
2c40: 42 5f 54 59 50 45 28 53 4c 41 42 5f 4d 41 58 5f B_TYPE(SLAB_MAX_
2c50: 44 41 54 41 5f 41 52 45 41 28 32 29 2c 20 30 2c DATA_AREA(2), 0,
2c60: 20 30 29 2c 0a 09 53 4c 41 42 5f 54 59 50 45 28 0),..SLAB_TYPE(
2c70: 53 4c 41 42 5f 4d 41 58 5f 44 41 54 41 5f 41 52 SLAB_MAX_DATA_AR
2c80: 45 41 28 31 29 2c 20 30 2c 20 30 29 2c 0a 7d 3b EA(1), 0, 0),.};
2c90: 0a 0a 23 69 66 64 65 66 20 44 45 42 55 47 0a 0a ..#ifdef DEBUG..
2ca0: 73 74 61 74 69 63 20 73 6c 61 62 5f 73 6c 6f 74 static slab_slot
2cb0: 5f 74 20 2a 20 61 75 64 69 74 5b 33 32 5d 3b 0a _t * audit[32];.
2cc0: 0a 76 6f 69 64 20 2a 20 61 64 64 5f 61 6c 6c 6f .void * add_allo
2cd0: 63 5f 61 75 64 69 74 28 76 6f 69 64 20 2a 20 70 c_audit(void * p
2ce0: 2c 20 63 68 61 72 20 2a 20 66 69 6c 65 2c 20 69 , char * file, i
2cf0: 6e 74 20 6c 69 6e 65 2c 20 73 69 7a 65 5f 74 20 nt line, size_t
2d00: 73 69 7a 65 2c 20 73 6c 61 62 5f 74 79 70 65 5f size, slab_type_
2d10: 74 20 2a 20 74 79 70 65 29 0a 7b 0a 09 73 74 61 t * type).{..sta
2d20: 74 69 63 20 69 6e 74 20 6e 65 78 74 20 3d 20 30 tic int next = 0
2d30: 3b 0a 0a 09 73 6c 61 62 5f 73 6c 6f 74 5f 74 20 ;...slab_slot_t
2d40: 2a 20 73 6c 6f 74 20 3d 20 28 28 73 6c 61 62 5f * slot = ((slab_
2d50: 73 6c 6f 74 5f 74 20 2a 29 70 29 2d 31 3b 0a 09 slot_t *)p)-1;..
2d60: 61 75 64 69 74 5b 6e 65 78 74 5d 20 3d 20 73 6c audit[next] = sl
2d70: 6f 74 3b 0a 0a 09 69 66 20 28 63 6f 75 6e 74 6f ot;...if (counto
2d80: 66 28 61 75 64 69 74 29 20 3d 3d 20 2b 2b 6e 65 f(audit) == ++ne
2d90: 78 74 29 20 7b 0a 09 09 6e 65 78 74 20 3d 20 30 xt) {...next = 0
2da0: 3b 0a 09 7d 0a 0a 23 69 66 20 44 45 42 55 47 0a ;..}..#if DEBUG.
2db0: 09 73 6c 6f 74 2d 3e 66 69 6c 65 20 3d 20 66 69 .slot->file = fi
2dc0: 6c 65 3b 0a 09 73 6c 6f 74 2d 3e 6c 69 6e 65 20 le;..slot->line
2dd0: 3d 20 6c 69 6e 65 3b 0a 09 74 68 72 65 61 64 5f = line;..thread_
2de0: 62 61 63 6b 74 72 61 63 65 28 73 6c 6f 74 2d 3e backtrace(slot->
2df0: 62 61 63 6b 74 72 61 63 65 2c 20 63 6f 75 6e 74 backtrace, count
2e00: 6f 66 28 73 6c 6f 74 2d 3e 62 61 63 6b 74 72 61 of(slot->backtra
2e10: 63 65 29 29 3b 0a 23 65 6e 64 69 66 0a 0a 09 72 ce));.#endif...r
2e20: 65 74 75 72 6e 20 70 3b 0a 7d 0a 0a 23 69 66 20 eturn p;.}..#if
2e30: 30 0a 76 6f 69 64 20 64 75 6d 70 5f 61 6c 6c 6f 0.void dump_allo
2e40: 63 5f 61 75 64 69 74 28 76 6f 69 64 20 2a 20 70 c_audit(void * p
2e50: 29 0a 7b 0a 09 66 6f 72 28 69 6e 74 20 69 3d 30 ).{..for(int i=0
2e60: 3b 20 69 3c 63 6f 75 6e 74 6f 66 28 61 75 64 69 ; i<countof(audi
2e70: 74 29 3b 20 69 2b 2b 29 20 7b 0a 09 09 73 6c 61 t); i++) {...sla
2e80: 62 5f 73 6c 6f 74 5f 74 20 2a 20 73 6c 6f 74 20 b_slot_t * slot
2e90: 3d 20 61 75 64 69 74 5b 69 5d 3b 0a 09 09 63 68 = audit[i];...ch
2ea0: 61 72 20 2a 20 63 70 20 3d 20 28 63 68 61 72 2a ar * cp = (char*
2eb0: 29 70 3b 0a 09 09 63 68 61 72 20 2a 20 62 61 73 )p;...char * bas
2ec0: 65 20 3d 20 28 63 68 61 72 2a 29 73 6c 6f 74 2b e = (char*)slot+
2ed0: 31 3b 0a 0a 09 09 69 66 20 28 63 70 3e 3d 62 61 1;....if (cp>=ba
2ee0: 73 65 20 26 26 20 63 70 3c 62 61 73 65 2b 73 6c se && cp<base+sl
2ef0: 6f 74 2d 3e 73 69 7a 65 29 20 7b 0a 09 09 09 6b ot->size) {....k
2f00: 65 72 6e 65 6c 5f 70 72 69 6e 74 6b 28 22 70 6f ernel_printk("po
2f10: 69 6e 74 65 72 20 61 6c 6c 6f 63 27 64 20 61 74 inter alloc'd at
2f20: 20 25 73 3a 25 64 5c 6e 22 2c 20 73 6c 6f 74 2d %s:%d\n", slot-
2f30: 3e 66 69 6c 65 2c 20 73 6c 6f 74 2d 3e 6c 69 6e >file, slot->lin
2f40: 65 29 3b 0a 09 09 7d 0a 09 7d 0a 7d 0a 23 65 6e e);...}..}.}.#en
2f50: 64 69 66 0a 0a 76 6f 69 64 20 2a 20 6d 61 6c 6c dif..void * mall
2f60: 6f 63 5f 64 28 73 69 7a 65 5f 74 20 73 69 7a 65 oc_d(size_t size
2f70: 2c 20 63 68 61 72 20 2a 20 66 69 6c 65 2c 20 69 , char * file, i
2f80: 6e 74 20 6c 69 6e 65 29 0a 7b 0a 09 72 65 74 75 nt line).{..retu
2f90: 72 6e 20 61 64 64 5f 61 6c 6c 6f 63 5f 61 75 64 rn add_alloc_aud
2fa0: 69 74 28 6d 61 6c 6c 6f 63 5f 70 28 73 69 7a 65 it(malloc_p(size
2fb0: 29 2c 20 66 69 6c 65 2c 20 6c 69 6e 65 2c 20 73 ), file, line, s
2fc0: 69 7a 65 2c 20 30 29 3b 0a 7d 0a 0a 76 6f 69 64 ize, 0);.}..void
2fd0: 20 2a 20 63 61 6c 6c 6f 63 5f 64 28 69 6e 74 20 * calloc_d(int
2fe0: 6e 75 6d 2c 20 73 69 7a 65 5f 74 20 73 69 7a 65 num, size_t size
2ff0: 2c 20 63 68 61 72 20 2a 20 66 69 6c 65 2c 20 69 , char * file, i
3000: 6e 74 20 6c 69 6e 65 29 0a 7b 0a 09 72 65 74 75 nt line).{..retu
3010: 72 6e 20 61 64 64 5f 61 6c 6c 6f 63 5f 61 75 64 rn add_alloc_aud
3020: 69 74 28 63 61 6c 6c 6f 63 5f 70 28 6e 75 6d 2c it(calloc_p(num,
3030: 20 73 69 7a 65 29 2c 20 66 69 6c 65 2c 20 6c 69 size), file, li
3040: 6e 65 2c 20 6e 75 6d 2a 73 69 7a 65 2c 20 30 29 ne, num*size, 0)
3050: 3b 0a 7d 0a 0a 76 6f 69 64 20 2a 20 72 65 61 6c ;.}..void * real
3060: 6c 6f 63 5f 64 28 76 6f 69 64 20 2a 20 70 2c 20 loc_d(void * p,
3070: 73 69 7a 65 5f 74 20 73 69 7a 65 2c 20 63 68 61 size_t size, cha
3080: 72 20 2a 20 66 69 6c 65 2c 20 69 6e 74 20 6c 69 r * file, int li
3090: 6e 65 29 0a 7b 0a 09 72 65 74 75 72 6e 20 61 64 ne).{..return ad
30a0: 64 5f 61 6c 6c 6f 63 5f 61 75 64 69 74 28 72 65 d_alloc_audit(re
30b0: 61 6c 6c 6f 63 5f 70 28 70 2c 20 73 69 7a 65 29 alloc_p(p, size)
30c0: 2c 20 66 69 6c 65 2c 20 6c 69 6e 65 2c 20 73 69 , file, line, si
30d0: 7a 65 2c 20 30 29 3b 0a 7d 0a 0a 76 6f 69 64 20 ze, 0);.}..void
30e0: 2a 20 73 6c 61 62 5f 61 6c 6c 6f 63 5f 64 28 73 * slab_alloc_d(s
30f0: 6c 61 62 5f 74 79 70 65 5f 74 20 2a 20 73 74 79 lab_type_t * sty
3100: 70 65 2c 20 63 68 61 72 20 2a 20 66 69 6c 65 2c pe, char * file,
3110: 20 69 6e 74 20 6c 69 6e 65 29 0a 7b 0a 09 72 65 int line).{..re
3120: 74 75 72 6e 20 61 64 64 5f 61 6c 6c 6f 63 5f 61 turn add_alloc_a
3130: 75 64 69 74 28 73 6c 61 62 5f 61 6c 6c 6f 63 5f udit(slab_alloc_
3140: 70 28 73 74 79 70 65 29 2c 20 66 69 6c 65 2c 20 p(stype), file,
3150: 6c 69 6e 65 2c 20 73 74 79 70 65 2d 3e 65 73 69 line, stype->esi
3160: 7a 65 2c 20 73 74 79 70 65 29 3b 0a 7d 0a 0a 76 ze, stype);.}..v
3170: 6f 69 64 20 2a 20 73 6c 61 62 5f 63 61 6c 6c 6f oid * slab_callo
3180: 63 5f 64 28 73 6c 61 62 5f 74 79 70 65 5f 74 20 c_d(slab_type_t
3190: 2a 20 73 74 79 70 65 2c 20 63 68 61 72 20 2a 20 * stype, char *
31a0: 66 69 6c 65 2c 20 69 6e 74 20 6c 69 6e 65 29 0a file, int line).
31b0: 7b 0a 09 72 65 74 75 72 6e 20 61 64 64 5f 61 6c {..return add_al
31c0: 6c 6f 63 5f 61 75 64 69 74 28 73 6c 61 62 5f 63 loc_audit(slab_c
31d0: 61 6c 6c 6f 63 5f 70 28 73 74 79 70 65 29 2c 20 alloc_p(stype),
31e0: 66 69 6c 65 2c 20 6c 69 6e 65 2c 20 73 74 79 70 file, line, styp
31f0: 65 2d 3e 65 73 69 7a 65 2c 20 73 74 79 70 65 29 e->esize, stype)
3200: 3b 0a 7d 0a 23 65 6c 73 65 0a 0a 76 6f 69 64 20 ;.}.#else..void
3210: 64 75 6d 70 5f 61 6c 6c 6f 63 5f 61 75 64 69 74 dump_alloc_audit
3220: 28 76 6f 69 64 20 2a 20 70 29 0a 7b 0a 09 6b 65 (void * p).{..ke
3230: 72 6e 65 6c 5f 70 72 69 6e 74 6b 28 22 4e 6f 20 rnel_printk("No
3240: 61 6c 6c 6f 63 20 61 75 64 69 74 20 6c 6f 67 5c alloc audit log\
3250: 6e 22 29 3b 0a 7d 0a 0a 23 65 6e 64 69 66 0a 0a n");.}..#endif..
3260: 76 6f 69 64 20 2a 20 6d 61 6c 6c 6f 63 5f 70 28 void * malloc_p(
3270: 73 69 7a 65 5f 74 20 73 69 7a 65 29 0a 7b 0a 09 size_t size).{..
3280: 66 6f 72 28 69 6e 74 20 69 3d 30 3b 20 69 3c 73 for(int i=0; i<s
3290: 69 7a 65 6f 66 28 70 6f 6f 6c 73 29 2f 73 69 7a izeof(pools)/siz
32a0: 65 6f 66 28 70 6f 6f 6c 73 5b 30 5d 29 3b 69 2b eof(pools[0]);i+
32b0: 2b 29 20 7b 0a 09 09 69 66 20 28 70 6f 6f 6c 73 +) {...if (pools
32c0: 5b 69 5d 2e 65 73 69 7a 65 20 3e 20 73 69 7a 65 [i].esize > size
32d0: 29 20 7b 0a 09 09 09 72 65 74 75 72 6e 20 73 6c ) {....return sl
32e0: 61 62 5f 61 6c 6c 6f 63 5f 70 28 70 6f 6f 6c 73 ab_alloc_p(pools
32f0: 2b 69 29 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 4b 54 +i);...}..}...KT
3300: 48 52 4f 57 46 28 41 6c 6c 6f 63 61 74 69 6f 6e HROWF(Allocation
3310: 54 6f 6f 42 69 67 45 78 63 65 70 74 69 6f 6e 2c TooBigException,
3320: 20 22 41 6c 6c 6f 63 61 74 69 6f 6e 20 74 6f 6f "Allocation too
3330: 20 62 69 67 20 66 6f 72 20 6d 61 6c 6c 6f 63 3a big for malloc:
3340: 20 25 64 22 2c 20 73 69 7a 65 29 3b 0a 0a 09 2f %d", size);.../
3350: 2a 20 4e 65 76 65 72 20 72 65 61 63 68 65 64 20 * Never reached
3360: 2a 2f 0a 09 72 65 74 75 72 6e 20 30 3b 0a 7d 0a */..return 0;.}.
3370: 0a 76 6f 69 64 20 66 72 65 65 28 76 6f 69 64 20 .void free(void
3380: 2a 70 29 0a 7b 0a 7d 0a 0a 76 6f 69 64 20 2a 20 *p).{.}..void *
3390: 63 61 6c 6c 6f 63 5f 70 28 73 69 7a 65 5f 74 20 calloc_p(size_t
33a0: 6e 75 6d 2c 20 73 69 7a 65 5f 74 20 73 69 7a 65 num, size_t size
33b0: 29 0a 7b 0a 09 76 6f 69 64 20 2a 20 70 20 3d 20 ).{..void * p =
33c0: 6d 61 6c 6c 6f 63 5f 70 28 6e 75 6d 2a 73 69 7a malloc_p(num*siz
33d0: 65 29 3b 0a 09 69 66 20 28 70 29 20 7b 0a 09 09 e);..if (p) {...
33e0: 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20 6e 75 6d memset(p, 0, num
33f0: 2a 73 69 7a 65 29 3b 0a 09 7d 0a 0a 09 72 65 74 *size);..}...ret
3400: 75 72 6e 20 70 3b 0a 7d 0a 0a 76 6f 69 64 20 2a urn p;.}..void *
3410: 72 65 61 6c 6c 6f 63 5f 70 28 76 6f 69 64 20 2a realloc_p(void *
3420: 70 2c 20 73 69 7a 65 5f 74 20 73 69 7a 65 29 0a p, size_t size).
3430: 7b 0a 09 69 66 20 28 30 20 3d 3d 20 70 29 20 7b {..if (0 == p) {
3440: 0a 09 09 72 65 74 75 72 6e 20 6d 61 6c 6c 6f 63 ...return malloc
3450: 5f 70 28 73 69 7a 65 29 3b 0a 09 7d 0a 0a 09 73 _p(size);..}...s
3460: 6c 61 62 5f 74 20 2a 20 73 6c 61 62 20 3d 20 73 lab_t * slab = s
3470: 6c 61 62 5f 67 65 74 28 70 29 3b 0a 0a 09 69 66 lab_get(p);...if
3480: 20 28 73 6c 61 62 29 20 7b 0a 09 09 69 66 20 28 (slab) {...if (
3490: 73 69 7a 65 20 3c 3d 20 73 6c 61 62 2d 3e 74 79 size <= slab->ty
34a0: 70 65 2d 3e 65 73 69 7a 65 29 20 7b 0a 09 09 09 pe->esize) {....
34b0: 2f 2a 20 4e 6f 74 68 69 6e 67 20 74 6f 20 64 6f /* Nothing to do
34c0: 2c 20 6e 65 77 20 6d 65 6d 6f 72 79 20 66 69 74 , new memory fit
34d0: 73 20 69 6e 20 65 78 69 73 74 69 6e 67 20 73 6c s in existing sl
34e0: 6f 74 20 2a 2f 0a 09 09 09 72 65 74 75 72 6e 20 ot */....return
34f0: 70 3b 0a 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09 p;...} else {...
3500: 09 76 6f 69 64 20 2a 20 6e 65 77 20 3d 20 6d 61 .void * new = ma
3510: 6c 6c 6f 63 5f 70 28 73 69 7a 65 29 3b 0a 0a 09 lloc_p(size);...
3520: 09 09 2f 2a 20 43 6f 70 79 20 6f 6c 64 20 64 61 ../* Copy old da
3530: 74 61 20 28 6f 66 20 6f 6c 64 20 73 69 7a 65 29 ta (of old size)
3540: 20 74 6f 20 6e 65 77 20 62 75 66 66 65 72 20 2a to new buffer *
3550: 2f 0a 09 09 09 72 65 74 75 72 6e 20 6d 65 6d 63 /....return memc
3560: 70 79 28 6e 65 77 2c 20 70 2c 20 73 6c 61 62 2d py(new, p, slab-
3570: 3e 74 79 70 65 2d 3e 65 73 69 7a 65 29 3b 0a 09 >type->esize);..
3580: 09 7d 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09 2f .}..} else {.../
3590: 2a 20 46 49 58 4d 45 3a 20 57 65 20 73 68 6f 75 * FIXME: We shou
35a0: 6c 64 20 64 6f 20 73 6f 6d 65 74 68 69 6e 67 20 ld do something
35b0: 68 65 72 65 20 74 6f 20 77 61 72 6e 20 6f 66 20 here to warn of
35c0: 6d 69 73 75 73 65 20 2a 2f 0a 09 09 6b 65 72 6e misuse */...kern
35d0: 65 6c 5f 70 61 6e 69 63 28 22 72 65 61 6c 6c 6f el_panic("reallo
35e0: 63 3a 20 49 6e 76 61 6c 69 64 20 68 65 61 70 20 c: Invalid heap
35f0: 70 6f 69 6e 74 65 72 3a 20 25 70 5c 6e 22 2c 20 pointer: %p\n",
3600: 70 29 3b 0a 09 7d 0a 0a 09 6b 65 72 6e 65 6c 5f p);..}...kernel_
3610: 70 61 6e 69 63 28 22 72 65 61 6c 6c 6f 63 3a 20 panic("realloc:
3620: 77 65 20 73 68 6f 75 6c 64 6e 27 74 20 67 65 74 we shouldn't get
3630: 20 68 65 72 65 21 22 29 3b 0a 09 72 65 74 75 72 here!");..retur
3640: 6e 20 30 3b 0a 7d 0a 0a 76 6f 69 64 20 2a 20 6d n 0;.}..void * m
3650: 63 6c 6f 6e 65 5f 73 69 7a 65 64 28 76 6f 69 64 clone_sized(void
3660: 20 2a 20 73 72 63 2c 20 73 69 7a 65 5f 74 20 73 * src, size_t s
3670: 69 7a 65 29 0a 7b 0a 09 76 6f 69 64 20 2a 20 70 ize).{..void * p
3680: 20 3d 20 6d 61 6c 6c 6f 63 28 73 69 7a 65 29 3b = malloc(size);
3690: 0a 09 72 65 74 75 72 6e 20 6d 65 6d 63 70 79 28 ..return memcpy(
36a0: 70 2c 20 73 72 63 2c 20 73 69 7a 65 29 3b 0a 7d p, src, size);.}
36b0: 0a 0a 76 6f 69 64 20 73 6c 61 62 5f 74 65 73 74 ..void slab_test
36c0: 28 29 0a 7b 0a 09 73 74 61 74 69 63 20 73 6c 61 ().{..static sla
36d0: 62 5f 74 79 70 65 5f 74 20 74 5b 31 5d 20 3d 20 b_type_t t[1] =
36e0: 7b 53 4c 41 42 5f 54 59 50 45 28 31 32 37 30 2c {SLAB_TYPE(1270,
36f0: 20 73 6c 61 62 5f 74 65 73 74 5f 6d 61 72 6b 2c slab_test_mark,
3700: 20 73 6c 61 62 5f 74 65 73 74 5f 66 69 6e 61 6c slab_test_final
3710: 69 7a 65 29 7d 3b 0a 09 76 6f 69 64 20 2a 20 70 ize)};..void * p
3720: 5b 34 5d 3b 0a 0a 09 70 5b 30 5d 20 3d 20 73 6c [4];...p[0] = sl
3730: 61 62 5f 61 6c 6c 6f 63 28 74 29 3b 0a 09 70 5b ab_alloc(t);..p[
3740: 31 5d 20 3d 20 73 6c 61 62 5f 61 6c 6c 6f 63 28 1] = slab_alloc(
3750: 74 29 3b 0a 09 70 5b 32 5d 20 3d 20 73 6c 61 62 t);..p[2] = slab
3760: 5f 61 6c 6c 6f 63 28 74 29 3b 0a 09 70 5b 33 5d _alloc(t);..p[3]
3770: 20 3d 20 73 6c 61 62 5f 61 6c 6c 6f 63 28 74 29 = slab_alloc(t)
3780: 3b 0a 0a 09 2f 2a 20 4e 6f 74 68 69 6e 67 20 73 ;.../* Nothing s
3790: 68 6f 75 6c 64 20 62 65 20 66 69 6e 61 6c 69 7a hould be finaliz
37a0: 65 64 20 68 65 72 65 20 2a 2f 0a 09 74 68 72 65 ed here */..thre
37b0: 61 64 5f 67 63 28 29 3b 0a 09 70 5b 30 5d 20 3d ad_gc();..p[0] =
37c0: 20 70 5b 31 5d 20 3d 20 70 5b 32 5d 20 3d 20 70 p[1] = p[2] = p
37d0: 5b 33 5d 20 3d 20 6d 61 6c 6c 6f 63 28 36 35 33 [3] = malloc(653
37e0: 29 3b 0a 0a 09 2f 2a 20 70 20 61 72 72 61 79 20 );.../* p array
37f0: 73 68 6f 75 6c 64 20 62 65 20 66 69 6e 61 6c 69 should be finali
3800: 7a 65 64 20 68 65 72 65 20 2a 2f 0a 09 74 68 72 zed here */..thr
3810: 65 61 64 5f 67 63 28 29 3b 0a 0a 09 70 5b 30 5d ead_gc();...p[0]
3820: 20 3d 20 70 5b 31 5d 20 3d 20 70 5b 32 5d 20 3d = p[1] = p[2] =
3830: 20 70 5b 33 5d 20 3d 20 72 65 61 6c 6c 6f 63 28 p[3] = realloc(
3840: 70 5b 30 5d 2c 20 37 33 36 29 3b 0a 09 70 5b 30 p[0], 736);..p[0
3850: 5d 20 3d 20 70 5b 31 5d 20 3d 20 70 5b 32 5d 20 ] = p[1] = p[2]
3860: 3d 20 70 5b 33 5d 20 3d 20 72 65 61 6c 6c 6f 63 = p[3] = realloc
3870: 28 70 5b 30 5d 2c 20 31 37 33 36 29 3b 0a 0a 09 (p[0], 1736);...
3880: 74 68 72 65 61 64 5f 67 63 28 29 3b 0a 7d 0a thread_gc();.}.