X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2Fsave.c;h=1518e614b8c1d1777bef5d15a551e5fdf1b3c878;hb=447477e72bd4fe54e678a28bdcc4a2802797d6ed;hp=d0e5026e4447813c03ad75524cd5ec2cc740240a;hpb=90744b007c22898033177a2848f15600264e4208;p=sbcl.git diff --git a/src/runtime/save.c b/src/runtime/save.c index d0e5026..1518e61 100644 --- a/src/runtime/save.c +++ b/src/runtime/save.c @@ -34,6 +34,10 @@ #include "genesis/static-symbols.h" #include "genesis/symbol.h" +#if defined(LISP_FEATURE_SB_THREAD) && defined(LISP_FEATURE_SB_LUTEX) +#include "genesis/lutex.h" +#endif + static void write_lispobj(lispobj obj, FILE *file) { @@ -76,6 +80,79 @@ write_bytes(FILE *file, char *addr, long bytes, os_vm_offset_t file_offset) return ((data - file_offset) / os_vm_page_size) - 1; } +#if defined(LISP_FEATURE_SB_THREAD) && defined(LISP_FEATURE_SB_LUTEX) +/* saving lutexes in the core */ +static void **lutex_addresses; +static long n_lutexes = 0; +static long max_lutexes = 0; + +static long +default_scan_action(lispobj *obj) +{ + return (sizetab[widetag_of(*obj)])(obj); +} + +static long +lutex_scan_action(lispobj *obj) +{ + /* note the address of the lutex */ + if(n_lutexes >= max_lutexes) { + max_lutexes *= 2; + lutex_addresses = realloc(lutex_addresses, max_lutexes * sizeof(void *)); + gc_assert(lutex_addresses); + } + + lutex_addresses[n_lutexes++] = obj; + + return (*sizetab[widetag_of(*obj)])(obj); +} + +typedef long (*scan_table[256])(lispobj *obj); + +static void +scan_objects(lispobj *start, long n_words, scan_table table) +{ + lispobj *end = start + n_words; + lispobj *object_ptr; + long n_words_scanned; + for (object_ptr = start; + object_ptr < end; + object_ptr += n_words_scanned) { + lispobj obj = *object_ptr; + + n_words_scanned = (table[widetag_of(obj)])(object_ptr); + } +} + +static void +scan_for_lutexes(lispobj *addr, long n_words) +{ + static int initialized = 0; + static scan_table lutex_scan_table; + + if (!initialized) { + int i; + + /* allocate a little space to get started */ + lutex_addresses = malloc(16*sizeof(void *)); + gc_assert(lutex_addresses); + max_lutexes = 16; + + /* initialize the mapping table */ + for(i = 0; i < ((sizeof lutex_scan_table)/(sizeof lutex_scan_table[0])); ++i) { + lutex_scan_table[i] = default_scan_action; + } + + lutex_scan_table[LUTEX_WIDETAG] = lutex_scan_action; + + initialized = 1; + } + + /* do the scan */ + scan_objects(addr, n_words, lutex_scan_table); +} +#endif + static void output_space(FILE *file, int id, lispobj *addr, lispobj *end, os_vm_offset_t file_offset) { @@ -88,6 +165,11 @@ output_space(FILE *file, int id, lispobj *addr, lispobj *end, os_vm_offset_t fil bytes = words * sizeof(lispobj); +#if defined(LISP_FEATURE_SB_THREAD) && defined(LISP_FEATURE_SB_LUTEX) + printf("scanning space for lutexes...\n"); + scan_for_lutexes((char *)addr, words); +#endif + printf("writing %ld bytes from the %s space at 0x%08lx\n", bytes, names[id], (unsigned long)addr); @@ -217,6 +299,24 @@ save_to_filehandle(FILE *file, char *filename, lispobj init_function, } #endif +#if defined(LISP_FEATURE_SB_THREAD) && defined(LISP_FEATURE_SB_LUTEX) + if(n_lutexes > 0) { + long offset; + printf("writing %d lutexes to the core...\n", n_lutexes); + write_lispobj(LUTEX_TABLE_CORE_ENTRY_TYPE_CODE, file); + /* word count of the entry */ + write_lispobj(4, file); + /* indicate how many lutexes we saved */ + write_lispobj(n_lutexes, file); + /* save the lutexes */ + offset = write_bytes(file, (char *) lutex_addresses, + n_lutexes * sizeof(*lutex_addresses), + core_start_pos); + + write_lispobj(offset, file); + } +#endif + write_lispobj(END_CORE_ENTRY_TYPE_CODE, file); /* Write a trailing header, ignored when parsing the core normally.