TWCOS Kernel

Hex Artifact Content
Login

Artifact 2189697305e45a43360b3fe60870dd74c592353b:


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();.}.