/** * \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(); } }
/* 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 }
/* System calls for handling locks */ int syscall_lock_create(lock_t* lock) { return lock_reset(lock); }