static NOINLINE void * slow_alloc(size_t obj_size) { void *obj; GCSTAT_TRIGGER(obj_size); do_gc(); if (HEAP_REST(sml_heap_from_space) >= obj_size) { obj = sml_heap_from_space.free; sml_heap_from_space.free += obj_size; #ifdef GC_STAT sml_heap_alloced(obj_size); #endif /* GC_STAT */ } else { #ifdef GCSTAT stat_notice("---"); stat_notice("event: error"); stat_notice("heap exceeded: intented to allocate %lu bytes.", (unsigned long)obj_size); if (gcstat.file) fclose(gcstat.file); #endif /* GCSTAT */ sml_fatal(0, "heap exceeded: intended to allocate %lu bytes.", (unsigned long)obj_size); } GIANT_UNLOCK(); #ifndef FAIR_COMPARISON sml_run_finalizer(); #endif /* FAIR_COMPARISON */ return obj; }
void sml_heap_gc(void) { GIANT_LOCK(); do_gc(); GIANT_UNLOCK(); #ifndef FAIR_COMPARISON sml_run_finalizer(); #endif /* FAIR_COMPARISON */ }
mr_object_t mr_object_new_by_size(mr_heap_t heap, mr_uintptr_t size) { if (heap && heap->object_count >= heap->gc_threshold) { if (do_gc(heap) != 0) return NULL; } mr_gc_header_t gc = (mr_gc_header_t)MR_MALLOC(sizeof(mr_gc_header_s) + size); if (gc == NULL) return NULL; gc->type = &dummy_type; gc->gc_status = heap ? GC_STATUS_UNTOUCH : GC_STATUS_HOST; gc->extern_ref = 1; if (heap) { heap->tracker[heap->object_count] = MR_TO_OBJECT(gc); ++ heap->object_count; } return MR_TO_OBJECT(gc); }
bool CompController::receive_command(const CommandInfo& host_cmd) { std::list<LPCMD> tmp_cmd_list; extract_hcmd_to_lp(host_cmd, tmp_cmd_list); // for test //std::for_each(tmp_cmd_list.begin(), tmp_cmd_list.end(), [](LPCMD& lp) { // std::cout<< lp.lpn << "," << lp.rmw_needed << "\n"; //}); if( host_cmd.opcode == IO_READ ) { std::list<LPCMD>::iterator itr; for( itr = tmp_cmd_list.begin(); itr != tmp_cmd_list.end(); itr++ ) if( !lp_read( (*itr).lpn ) ) ERR_AND_RTN; } else if( host_cmd.opcode == IO_WRITE ) { std::list<LPCMD>::iterator itr; for( itr = tmp_cmd_list.begin(); itr != tmp_cmd_list.end(); itr++ ) { if( (*itr).rmw_needed && !lp_read((*itr).lpn) ) ERR_AND_RTN; if( !lp_write((*itr).lpn) ) ERR_AND_RTN; } }else return false; if( free_list.size() < gc_threshold && !do_gc() ) ERR_AND_RTN; record_statis( host_cmd ); return true; }
int main(int argc, char *argv[]) { SetDefaultLogging("TEST"); SetNamePgm("test_configurable_lru"); char buf[LENBUF]; int ok = 1; int hrc = 0; int rc = 0; int expected_rc; char c; char *p; int key; LRU_status_t status = 0; LRU_list_t *plru; LRU_parameter_t param; param.nb_entry_prealloc = PREALLOC; param.entry_to_str = print_entry; param.clean_entry = clean_entry; param.name = "Test"; BuddyInit(NULL); if((plru = LRU_Init(param, &status)) == NULL) { LogTest("Test ECHOUE : Mauvaise init"); exit(1); } /* * * La syntaxe d'un test est * 'i key rc' : invalide l'entree avec la clef key * 'n key rc' : cree une nouvelle entree avec la clef key * 'g key rc' : passage du garbage collector (key ne sert a rien) * 'p key rc' : imprime le LRU (key et rc ne servent a rien). * * Une ligne qui debute par '#' est un commentaire * Une ligne qui debute par un espace ou un tab est une ligne vide [meme si il y a des trucs derriere.. :-( ] * Une ligne vide (juste un CR) est une ligne vide (cette citation a recu le Premier Prix lors du Festival International * de la Tautologie de Langue Francaise (FITLF), a Poully le Marais, en Aout 2004) * */ LogTest("============ Debut de l'interactif ================="); while(ok) { /* Code interactif, pompe sur le test rbt de Jacques */ fputs("> ", stdout); if((p = fgets(buf, LENBUF, stdin)) == NULL) { LogTest("fin des commandes"); ok = 0; continue; } if((p = strchr(buf, '\n')) != NULL) *p = '\0'; rc = sscanf(buf, "%c %d %d", &c, &key, &expected_rc); if(c == '#') { /* # indique un commentaire */ continue; } else if(c == ' ' || c == '\t' || rc == -1) { /* Cas d'une ligne vide */ if(rc > 1) LogTest("Erreur de syntaxe : mettre un diese au debut d'un commentaire"); continue; } else { if(rc != 3) { LogTest("Erreur de syntaxe : sscanf retourne %d au lieu de 3", rc); continue; } LogTest("---> %c %d %d", c, key, expected_rc); } switch (c) { case 'i': /* set overwrite */ LogTest("invalidate %d --> %d ?", key, expected_rc); hrc = do_invalidate(plru, key); if(hrc != expected_rc) LogTest(">>>> ERREUR: invalidate %d : %d != %d (expected)", key, hrc, expected_rc); else LogTest(">>>> OK invalidate %d", key); break; case 'n': /* test */ LogTest("new %d --> %d ?", key, expected_rc); hrc = do_new(plru, key); if(hrc != expected_rc) LogTest(">>>> ERREUR: new %d : %d != %d (expected)", key, hrc, expected_rc); else LogTest(">>>> OK new %d", key); break; case 'g': /* set no overwrite */ LogTest("gc %d --> %d ?", key, expected_rc); hrc = do_gc(plru); if(hrc != expected_rc) LogTest(">>>> ERREUR: gc %d: %d != %d (expected)", key, hrc, expected_rc); else LogTest(">>>> OK new %d", key); break; case 'p': /* Print */ LRU_Print(plru); break; default: /* syntaxe error */ LogTest("ordre '%c' non-reconnu", c); break; } } LogTest("===================================================="); LogTest("Test reussi : tous les tests sont passes avec succes"); exit(0); return; } /* main */
SML_PRIMITIVE void * sml_alloc(unsigned int objsize, void *frame_pointer) { size_t alloc_size; unsigned int blocksize_log2; struct alloc_ptr *ptr; void *obj; /* ensure that alloc_size is at least BLOCKSIZE_MIN. */ alloc_size = ALIGNSIZE(OBJ_HEADER_SIZE + objsize, BLOCKSIZE_MIN); if (alloc_size > BLOCKSIZE_MAX) { GCSTAT_ALLOC_COUNT(malloc, 0, alloc_size); sml_save_frame_pointer(frame_pointer); return sml_obj_malloc(alloc_size); } blocksize_log2 = CEIL_LOG2(alloc_size); ASSERT(BLOCKSIZE_MIN_LOG2 <= blocksize_log2 && blocksize_log2 <= BLOCKSIZE_MAX_LOG2); ptr = &ALLOC_PTR_SET()->alloc_ptr[blocksize_log2]; if (!BITPTR_TEST(ptr->freebit)) { GCSTAT_ALLOC_COUNT(fast, blocksize_log2, alloc_size); BITPTR_INC(ptr->freebit); obj = ptr->free; ptr->free += ptr->blocksize_bytes; goto alloced; } sml_save_frame_pointer(frame_pointer); if (ptr->free != NULL) { obj = find_bitmap(ptr); if (obj) goto alloced; } obj = find_segment(ptr); if (obj) goto alloced; GCSTAT_TRIGGER(blocksize_log2); do_gc(MAJOR); obj = find_segment(ptr); if (obj) goto alloced_major; extend_heap(heap_space.extend_step); obj = find_segment(ptr); if (obj) goto alloced_major; sml_fatal(0, "heap exceeded: intended to allocate %u bytes.", ptr->blocksize_bytes); alloced_major: ASSERT(check_newobj(obj)); /* NOTE: sml_run_finalizer may cause garbage collection. */ obj = sml_run_finalizer(obj); goto finished; alloced: ASSERT(check_newobj(obj)); finished: OBJ_HEADER(obj) = 0; return obj; }
void sml_heap_gc() { do_gc(); sml_run_finalizer(NULL); }