inline void *pmemalloc_reserv_virtual(size_t size, void **tmp){ #ifdef INTEL_PMEM void *ptr = pmemalloc_reserve(Pmp, size); *tmp = ptr; return PMEM(Pmp, ptr); #else return malloc(size); #endif }
void* pmalloc(size_t sz) { pthread_mutex_lock(&pmp_mutex); /* if(sz==32){ //32 is the size of vector, and vectors can be appended, so we need to reserve extra space // to avoid the need for realloc sz=100*32; }*/ void* ret = pmemalloc_reserve(sz); pthread_mutex_unlock(&pmp_mutex); return ret; }
int main(int argc, char *argv[]) { const char *path; int opt; int retval; unsigned long thrd; int mbx; void **sa_ptr; mailbox_array_t *mbx_offset_; Myname = argv[0]; while ((opt = getopt(argc, argv, "t:r:s:d")) != -1) { switch (opt) { case 't': if (sscanf(optarg, "%u", &num_threads) == EOF) { USAGE( "-t option error"); } if (num_threads > MAX_THREADS) { fprintf( stderr, "using max threads %d\n", MAX_THREADS ); num_threads = MAX_THREADS; } break; case 'r': if (sscanf(optarg, "%u", &runtime)==EOF) { USAGE("-r option error"); } break; case 's': if (sscanf(optarg, "%u", &max_malloc)==EOF) USAGE("-s option error"); break; case 'd': Debug=TRUE; break; default: USAGE(NULL); } } /* end while opt */ if (optind >= argc) USAGE("No path given"); path = argv[optind++]; if (optind < argc) USAGE(NULL); /* * Use the alloc_init lib function to open the pool * via pmfs, and map it into our address space. * This returns a regular (absolute) pointer. */ if ((pmp = pmemalloc_init(path, POOL_SIZE)) == NULL) FATALSYS("pmemalloc_init on %s", path); /* * Fetch our static info. * The first word is used to store a relative pointer to * the mailbox array. The library function converts this * to an absolute pointer. */ sa_ptr = (void**)pmemalloc_static_area(pmp); /* The static area for a new pmem pool is zero'd */ if (*sa_ptr == NULL) { /* * Create and initialize the mailbox array in PM */ if ((mbx_offset_=pmemalloc_reserve(pmp, sizeof(mailbox_array_t))) == NULL ) FATALSYS("pmemalloc mailbox array"); /* * Place a pointer to this array in the first word of the * static area on activation */ pmemalloc_onactive( pmp, mbx_offset_, (void**)sa_ptr, mbx_offset_ ); pmemalloc_activate( pmp, mbx_offset_ ); /* Set the static, regular pointer to be used in the program */ mbx_array_ptr = PMEM( pmp, mbx_offset_ ); for (thrd=0; thrd<MAX_THREADS; ++thrd) { for (mbx=0; mbx<MAILBOXES; ++mbx) { (*mbx_array_ptr)[thrd][mbx] = NULL; } } } else { /* * This region already exists from a previous run. * Free any pmem spaces still in the mailbox. */ mbx_array_ptr = PMEM( pmp, (mailbox_array_t*)*sa_ptr ); for (thrd=0; thrd<MAX_THREADS; ++thrd) { for (mbx=0; mbx<MAILBOXES; ++mbx) { if ((*mbx_array_ptr)[thrd][mbx] != NULL) { pmemalloc_onfree( pmp, (*mbx_array_ptr)[thrd][mbx], &(*mbx_array_ptr)[thrd][mbx], NULL ); pmemalloc_free( pmp, (*mbx_array_ptr)[thrd][mbx] ); } } } } /* Commit the initialized mailbox to persistent media */ pmem_persist( mbx_array_ptr, sizeof(mailbox_array_t), 0 ); DEBUG( "Number of threads = %d", num_threads); DEBUG( "Runtime: %d seconds", runtime ); DEBUG( "Max alloc size %d bytes", max_malloc ); /* * Create each allocating thread. Each allocating thread * will create its corresponding freeing thread. * Once each each thread is created, signal the start condition * so they all start running around the same time. */ for (thrd=0; thrd<num_threads; ++thrd) { retval = pthread_create( &alloc_threads[thrd], NULL, alloc_main, (void *) thrd ); if (retval) { errno = retval; FATALSYS( "alloc thread create %d\n", thrd ); } } /* Give the new threads a chance to start */ sleep(0); pthread_mutex_lock( &start_lock ); b_start_flag = TRUE; pthread_cond_broadcast( &start_cv ); pthread_mutex_unlock( &start_lock ); /* Let run for the desired seconds then tell all threads to stop */ sleep( runtime ); b_all_stop = TRUE; /* Wait for each alloating thread to complete. */ for (thrd=0; thrd<num_threads; ++thrd) { retval = pthread_join( alloc_threads[thrd], NULL ); if (retval) { errno = retval; FATALSYS( "Allocating thread JOIN %d", thrd ); } } /* Commit the final mailbox array to persistent media */ pmem_persist( mbx_array_ptr, sizeof(mailbox_array_t), 0 ); DEBUG("Done."); exit(0); }
/* * main() for the allocating thread. */ void * alloc_main( void *tparam ) { unsigned long thread_num = (unsigned long) tparam; int retval; void **mbx_list = (*mbx_array_ptr)[thread_num]; pthread_t free_thread; void *rel_mem_ptr_ = NULL; unsigned int malloc_size = 0; int mbx; DEBUG( "Enter alloc thread %d\n", thread_num ); retval = pthread_create( &free_thread, NULL, free_main, (void *) thread_num ); if (retval) { errno = retval; FATALSYS( "free thread create in thread %l\n", thread_num ); } /* * Wait for the starting gun to send all the threads * off and running.... */ pthread_mutex_lock( &start_lock ); while (!b_start_flag) { pthread_cond_wait( &start_cv, &start_lock ); } pthread_mutex_unlock( &start_lock ); /* * Until the parent thread says to stop just keep looping * through the mailboxes looking for empty ones. When one is * found, do a random sized alloc and put a pointer in the mailbox * for the freeing thread to free. */ while (!b_all_stop) { for (mbx=0; mbx<MAILBOXES; ++mbx) { if (mbx_list[mbx] == NULL) { malloc_size = (int)random() % max_malloc; if( (rel_mem_ptr_=pmemalloc_reserve( pmp, malloc_size )) != NULL ) { pmemalloc_onactive( pmp, rel_mem_ptr_, &mbx_list[mbx], rel_mem_ptr_ ); pmemalloc_activate( pmp, rel_mem_ptr_ ); DEBUG( "malloc %d bytes", malloc_size ); } else { /* * Malloc failed. * Sleep to let the Freeing thread catch up. */ DEBUG( "malloc failed for size %d\n", malloc_size ); sleep(0); } } /* end if mbx empty */ } /* end for each mbx */ } /* end while not all_stop */ /* * Time to stop. Wait for the freeing thread to complete. */ retval = pthread_join( free_thread, NULL ); if (retval) { errno = retval; FATALSYS( "Join with freeing thread %d\n", thread_num ); } pthread_exit( NULL ); }
int main(int argc, char *argv[]) { const char *path; int opt; int fflag = 0; int iflag = 0; unsigned long icount; void *pmp; struct static_info *sp; struct node *parent_; struct node *np_; Myname = argv[0]; while ((opt = getopt(argc, argv, "FMdfi:")) != -1) { switch (opt) { case 'F': pmem_fit_mode(); break; case 'M': pmem_msync_mode(); break; case 'd': Debug++; break; case 'f': fflag++; break; case 'i': iflag++; icount = strtoul(optarg, NULL, 10); break; default: USAGE(NULL); } } if (optind >= argc) USAGE("No path given"); path = argv[optind++]; if ((pmp = pmemalloc_init(path, MY_POOL_SIZE)) == NULL) FATALSYS("pmemalloc_init on %s", path); /* fetch our static info */ sp = (struct static_info *) pmemalloc_static_area(pmp); if (optind < argc) { /* numbers supplied as arguments? */ int i; if (fflag) USAGE("unexpected extra arguments given with -f flag"); if (iflag) icount_start(icount); /* start instruction count */ for (i = optind; i < argc; i++) { int value = atoi(argv[i]); if ((np_ = pmemalloc_reserve(pmp, sizeof(*np_))) == NULL) FATALSYS("pmemalloc_reserve"); /* link it in at the beginning of the list */ PMEM(pmp, np_)->next_ = sp->rootnp_; PMEM(pmp, np_)->value = value; pmemalloc_onactive(pmp, np_, (void **) &sp->rootnp_, np_); pmemalloc_activate(pmp, np_); } if (iflag) { icount_stop(); /* end instruction count */ printf("Total instruction count: %lu\n", icount_total()); } } else if (fflag) { /* * remove first item from list */ if (sp->rootnp_ == NULL) FATAL("the list is empty"); if (iflag) icount_start(icount); /* start instruction count */ np_ = sp->rootnp_; pmemalloc_onfree(pmp, np_, (void **) &sp->rootnp_, PMEM(pmp, np_)->next_); pmemalloc_free(pmp, np_); if (iflag) { icount_stop(); /* end instruction count */ printf("Total instruction count: %lu\n", icount_total()); } } else { char *sep = ""; /* * traverse the list, printing the numbers found */ np_ = sp->rootnp_; while (np_) { printf("%s%d", sep, PMEM(pmp, np_)->value); sep = " "; np_ = PMEM(pmp, np_)->next_; } printf("\n"); } DEBUG("Done."); exit(0); }