static void test(mps_ap_t leafap, mps_ap_t exactap, mps_ap_t weakap, mps_ap_t bogusap) { mps_word_t *weaktable; mps_word_t *exacttable; mps_word_t *preserve[TABLE_SLOTS]; /* preserves objects in the weak */ /* table by referring to them */ unsigned long i, j; void *p; exacttable = alloc_table(TABLE_SLOTS, exactap); weaktable = alloc_table(TABLE_SLOTS, weakap); table_link(exacttable, weaktable); /* Leave bogusap between reserve and commit for the duration */ die(mps_reserve(&p, bogusap, 64), "Reserve bogus"); for(i = 0; i < TABLE_SLOTS; ++i) { mps_word_t *string; if(rnd() < P_A_HALF) { string = alloc_string("iamalive", leafap); preserve[i] = string; } else { string = alloc_string("iamdead", leafap); preserve[i] = 0; } set_table_slot(weaktable, i, string); string = alloc_string("iamexact", leafap); set_table_slot(exacttable, i, string); } for(j = 0; j < ITERATIONS; ++j) { for(i = 0; i < TABLE_SLOTS; ++i) { mps_word_t *string; string = alloc_string("spong", leafap); } } for(i = 0; i < TABLE_SLOTS; ++i) { if(preserve[i] == 0) { if(table_slot(weaktable, i)) { fprintf(stdout, "Strongly unreachable weak table entry found, " "slot %lu.\n", i); } else { if(table_slot(exacttable, i) != 0) { fprintf(stdout, "Weak table entry deleted, but corresponding " "exact table entry not deleted, slot %lu.\n", i); } } } } (void)mps_commit(bogusap, p, 64); puts("A okay\n"); }
struct global_state *new_global_state(struct machine_specification *machine) /* Returns: A new global state for a motlle interpreter for machine */ { struct global_state *gstate; GCPRO1(machine); gstate = (struct global_state *)allocate_record(type_vector, 5); GCPRO1(gstate); gstate->modules = alloc_table(DEF_TABLE_SIZE); gstate->mvars = alloc_vector(GLOBAL_SIZE); gstate->global = alloc_table(GLOBAL_SIZE); gstate->environment = alloc_env(GLOBAL_SIZE); gstate->machine = machine; GCPOP(2); return gstate; }
static value make_table(cstlist csts, fncode fn) { struct table *t = alloc_table(DEF_TABLE_SIZE); GCPRO1(t); for (; csts; csts = csts->next) table_set(t, csts->cst->u.constpair->cst1->u.string, make_constant(csts->cst->u.constpair->cst2, FALSE, fn), NULL); table_foreach(t, protect_symbol); SET_READONLY(t); GCPOP(1); return t; }
static value make_table(cstlist csts) { struct table *t = alloc_table(DEF_TABLE_SIZE); GCPRO1(t); for (; csts; csts = csts->next) table_set_len(t, csts->cst->u.constpair->cst1->u.string.str, csts->cst->u.constpair->cst1->u.string.len, make_constant(csts->cst->u.constpair->cst2)); table_foreach(t, NULL, protect_symbol); immutable_table(t); UNGCPRO(); return t; }
static void test(mps_arena_t arena, mps_ap_t leafap, mps_ap_t exactap, mps_ap_t weakap, mps_ap_t bogusap) { mps_word_t *weaktable; mps_word_t *exacttable; mps_word_t *preserve[TABLE_SLOTS]; /* preserves objects in the weak */ /* table by referring to them */ size_t i, j; void *p; exacttable = alloc_table(TABLE_SLOTS, exactap); weaktable = alloc_table(TABLE_SLOTS, weakap); table_link(exacttable, weaktable); /* Leave bogusap between reserve and commit for the duration */ die(mps_reserve(&p, bogusap, 64), "Reserve bogus"); for(i = 0; i < TABLE_SLOTS; ++i) { mps_word_t *string; /* Ensure that the first and last entries in the table are * preserved, so that we don't get false positives due to the * local variables 'weak_table' and 'string' keeping these entries * alive (see job003436). */ if (rnd() % 2 == 0 || i == 0 || i + 1 == TABLE_SLOTS) { string = alloc_string("iamalive", leafap); preserve[i] = string; } else { string = alloc_string("iamdead", leafap); preserve[i] = 0; } set_table_slot(weaktable, i, string); string = alloc_string("iamexact", leafap); set_table_slot(exacttable, i, string); } for(j = 0; j < ITERATIONS; ++j) { for(i = 0; i < TABLE_SLOTS; ++i) { (void)alloc_string("spong", leafap); } } die(mps_arena_collect(arena), "mps_arena_collect"); mps_arena_release(arena); for(i = 0; i < TABLE_SLOTS; ++i) { if (preserve[i] == 0) { if (table_slot(weaktable, i)) { error("Strongly unreachable weak table entry found, " "slot %"PRIuLONGEST".\n", (ulongest_t)i); } else { if (table_slot(exacttable, i) != 0) { error("Weak table entry deleted, but corresponding " "exact table entry not deleted, slot %"PRIuLONGEST".\n", (ulongest_t)i); } } } } (void)mps_commit(bogusap, p, 64); }
int main(int argc, char **argv) { int i; int opt; int threads = -1; int cpu; char *needle = NULL; char *dir = NULL; struct kmp_table table; struct queue q; struct produce_arg parg; struct consume_arg carg; pthread_t producer; pthread_t *consumers; while ((opt = getopt(argc, argv, "n:s:d:")) != -1) { switch (opt) { case 'n': threads = atoi(optarg); break; case 's': needle = checked_strdup(optarg); break; case 'd': dir = checked_strdup(optarg); break; case '?': default: usage(argv[0]); return (1); } } if (!needle || strlen(needle) <= 0) { usage(argv[0]); return (1); } if (!dir) { dir = checked_malloc(sizeof (char) * 2); dir[0] = '.'; dir[1] = 0; } if (threads <= 0) { cpu = sysconf(_SC_NPROCESSORS_ONLN); if (cpu <= 1) { threads = 1; } else if (cpu >= 20) { threads = 20; } else { threads = cpu; } } alloc_table(&table, needle); fill_table(&table); alloc_queue(&q, INITIAL_CAPACITY); parg.q = &q; parg.path = dir; parg.consumer_count = threads; carg.q = &q; carg.t = &table; consumers = checked_malloc(sizeof (pthread_t) * threads); checked_thread_create(&producer, NULL, &produce, &parg); for (i = 0; i < threads; i++) { checked_thread_create(consumers + i, NULL, &consume, &carg); } checked_thread_join(producer, NULL); for (i = 0; i < threads; i++) { checked_thread_join(consumers[i], NULL); } free_queue(&q); free_table(&table); free(consumers); free(needle); free(dir); return (0); }