Exemple #1
0
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;
}
Exemple #2
0
void
sml_heap_gc(void)
{
	GIANT_LOCK();
	do_gc();
	GIANT_UNLOCK();
#ifndef FAIR_COMPARISON
	sml_run_finalizer();
#endif /* FAIR_COMPARISON */
}
Exemple #3
0
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);
}
Exemple #4
0
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;
}
Exemple #5
0
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 */
Exemple #6
0
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;
}
Exemple #7
0
void
sml_heap_gc()
{
	do_gc();
	sml_run_finalizer(NULL);
}