/* Initialize the catch all gc */ void gc_catch(void) { struct sigaction act, old; memset(&act,0,sizeof(act)); act.sa_handler = gc_handler; sigemptyset(&act.sa_mask); sigaction(SIGINT, &act, &old); sigaction(SIGQUIT, &act, &old); sigaction(SIGTERM, &act, &old); sigaction(SIGABRT, &act, &old); sigaction(SIGTSTP, &act, &old); sigaction(SIGBUS, &act, &old); sigaction(SIGILL, &act, &old); sigaction(SIGSEGV, &act, &old); sigaction(SIGFPE, &act, &old); if(sigsetjmp(gc_cleanup, 0) == 0) return; /* Call all GC functions */ exit(gc_run()); }
Cell alloc(int n) { Cell p; if (free_ptr + n > heap_area) gc_run(NULL, NULL); assert(free_ptr + n <= heap_area); p = free_ptr; free_ptr += n; return p; }
Cell pair(Cell fst, Cell snd) { Cell c; if (free_ptr >= heap_area) gc_run(&fst, &snd); assert(free_ptr < heap_area); c = free_ptr++; car(c) = fst; cdr(c) = snd; return c; }
void gc_run(Cell *save1, Cell *save2) { static Pair* free_area = NULL; int num_alive; Pair *scan; clock_t start = clock(); if (free_area == NULL) { free_area = malloc(sizeof(Pair) * next_heap_size); if (free_area == NULL) errexit("Cannot allocate heap storage (%d cells)\n", next_heap_size); } free_ptr = scan = free_area; free_area = heap_area - heap_size; heap_area = free_ptr + next_heap_size; rs_copy(); if (save1) *save1 = copy_cell(*save1); if (save2) *save2 = copy_cell(*save2); while (scan < free_ptr) { car(scan) = copy_cell(car(scan)); cdr(scan) = copy_cell(cdr(scan)); scan++; } num_alive = free_ptr - (heap_area - next_heap_size); if (gc_notify) fprintf(stderr, "GC: %d / %d\n", num_alive, heap_size); if (heap_size != next_heap_size || num_alive * 8 > next_heap_size) { heap_size = next_heap_size; if (num_alive * 8 > next_heap_size) next_heap_size = num_alive * 8; free(free_area); free_area = NULL; } total_gc_time += (clock() - start) / (double)CLOCKS_PER_SEC; if (free_ptr >= heap_area) gc_run(save1, save2); }
void gc_handler(int sig) { if(((sig == SIGINT || sig == SIGTERM || sig == SIGTSTP) && gc_enable == 1) || (!(sig == SIGINT || sig == SIGTERM || sig == SIGTSTP) && gc_enable == 0)) { if(configfile != NULL && gc_enable == 1) { gc_enable = 0; JsonNode *joutput = config2json(-1); char *output = json_stringify(joutput, "\t"); config_write(output); json_delete(joutput); sfree((void *)&output); joutput = NULL; sfree((void *)&configfile); configfile = NULL; } gc_enable = 0; config_gc(); gc_run(); } }