Beispiel #1
0
/**
 * \brief Extract an object from a mallocator
 * \param m a mallocator
 *
 * Remove an object from the mallocator and return it.
 * This function is designed to be used instead of malloc().
 * If the mallocator is not empty, an object is
 * extracted from the mallocator and no malloc is done.
 *
 * If the mallocator is empty, a new object is created,
 * by calling the function new_f().
 *
 * In both cases, the function reset_f() (if defined) is called on the object.
 *
 * \see xbt_mallocator_release()
 */
void *xbt_mallocator_get(xbt_mallocator_t m)
{
  void *object;

  if (m->objects != NULL) { // this mallocator is active, stop thinking and go for it!
    lock_acquire(m);
    if (m->current_size <= 0) {
      /* No object is ready yet. Create a bunch of them to try to group the
       * mallocs on the same memory pages (to help the cache lines) */

      /* XBT_DEBUG("Create a new object for mallocator %p (size:%d/%d)", */
      /*           m, m->current_size, m->max_size); */
      int i;
      int amount = MIN(m->max_size / 2, 1000);
      for (i = 0; i < amount; i++)
        m->objects[i] = m->new_f();
      m->current_size = amount;
    }

    /* there is at least an available object, now */
    /* XBT_DEBUG("Reuse an old object for mallocator %p (size:%d/%d)", */
    /*           m, m->current_size, m->max_size); */
    object = m->objects[--m->current_size];
    lock_release(m);
  } else {
    if (xbt_mallocator_is_active()) {
      // We have to switch this mallocator from inactive to active (and then get an object)
      m->objects = xbt_new0(void *, m->max_size);
      lock_reset(m);
      return xbt_mallocator_get(m);
    } else {
      object = m->new_f();
    }
  }
Beispiel #2
0
/* Called once (from main) to initialize STM infrastructure. */
void stm_init()
{
    DEBUG_START
    DPRINTF("stm init\n");
    GLOBAL_VERSION=1;
    
    allocated = NULL;
    unused_tx = NULL;
    GLOBAL_VERSION=1;
    
#ifdef VALGRIND
    // valgrind cannot memalgin >1meg
    if (posix_memalign((void**)&locks, LOCK_HASH_ARRAY_SIZE/4, LOCK_HASH_ARRAY_SIZE*sizeof(stm_word_t))) {
#else
    if (posix_memalign((void**)&locks, LOCK_HASH_ARRAY_SIZE*sizeof(stm_word_t), LOCK_HASH_ARRAY_SIZE*sizeof(stm_word_t))) {
#endif
	printf("Could not allocate locks\n");
	exit(1);
    }
    lock_reset();
    pthread_mutex_init(&unused_tx_mutex, NULL);

}


/* Called once (from main) to clean up STM infrastructure. */
void stm_exit()
{
    DPRINTF("stm exit\n");
    /* free buffers */
    while (allocated!=NULL) {
	mem_block_t *cur = allocated;
	allocated = allocated->next;
	free(cur->addr);
	free(cur);
    }
    free((stm_word_t*)locks);

    pthread_mutex_destroy(&unused_tx_mutex);
    while (unused_tx!=NULL) {
	tx_block_t *cur = unused_tx;
	unused_tx = unused_tx->next;
	free_tx((stm_tx_t*)cur->tx);
	free(cur);
    }
    
#ifdef GLOBAL_STATS
    printf("Total nr of new transactions: %ld\n", xxstm_nr_tx);
#endif
    DEBUG_END
}
Beispiel #3
0
/* System calls for handling locks */
int syscall_lock_create(lock_t* lock)
{
    return lock_reset(lock);
}