/* * Allocates filebench objects from pre allocated region of * shareable memory. The memory region is partitioned into sets * of objects during initialization. This routine scans for * the first unallocated object of type "type" in the set of * available objects, and makes it as allocated. The routine * returns a pointer to the object, or NULL if all objects have * been allocated. */ void * ipc_malloc(int obj_type) { int start_idx; int max_idx; int i; (void) ipc_mutex_lock(&filebench_shm->shm_malloc_lock); start_idx = filebench_shm->shm_lastbitmapindex[obj_type]; max_idx = preallocated_entries(obj_type) - 1; i = start_idx; do { i++; if (i > max_idx) i = 0; if (filebench_shm->shm_bitmap[obj_type][i] == 0) break; } while (i != start_idx); if (i == start_idx) { filebench_log(LOG_ERROR, "Out of shared memory (%d)!", obj_type); (void) ipc_mutex_unlock(&filebench_shm->shm_malloc_lock); return (NULL); } filebench_shm->shm_bitmap[obj_type][i] = 1; filebench_shm->shm_lastbitmapindex[obj_type] = i; switch (obj_type) { case FILEBENCH_FILESET: (void) memset((char *)&filebench_shm->shm_fileset[i], 0, sizeof (fileset_t)); (void) ipc_mutex_unlock(&filebench_shm->shm_malloc_lock); return ((char *)&filebench_shm->shm_fileset[i]); case FILEBENCH_POSSET: (void) memset((char *)&filebench_shm->shm_posset[i], 0, sizeof (struct posset)); (void) ipc_mutex_unlock(&filebench_shm->shm_malloc_lock); return ((char *)&filebench_shm->shm_posset[i]); case FILEBENCH_FILESETENTRY: (void) memset((char *)&filebench_shm->shm_filesetentry[i], 0, sizeof (filesetentry_t)); (void) ipc_mutex_unlock(&filebench_shm->shm_malloc_lock); return ((char *)&filebench_shm->shm_filesetentry[i]); case FILEBENCH_PROCFLOW: (void) memset((char *)&filebench_shm->shm_procflow[i], 0, sizeof (procflow_t)); (void) ipc_mutex_unlock(&filebench_shm->shm_malloc_lock); return ((char *)&filebench_shm->shm_procflow[i]); case FILEBENCH_THREADFLOW: (void) memset((char *)&filebench_shm->shm_threadflow[i], 0, sizeof (threadflow_t)); (void) ipc_mutex_unlock(&filebench_shm->shm_malloc_lock); return ((char *)&filebench_shm->shm_threadflow[i]); case FILEBENCH_FLOWOP: (void) memset((char *)&filebench_shm->shm_flowop[i], 0, sizeof (flowop_t)); (void) ipc_mutex_unlock(&filebench_shm->shm_malloc_lock); return ((char *)&filebench_shm->shm_flowop[i]); case FILEBENCH_VARIABLE: (void) memset((char *)&filebench_shm->shm_var[i], 0, sizeof (var_t)); (void) ipc_mutex_unlock(&filebench_shm->shm_malloc_lock); return ((char *)&filebench_shm->shm_var[i]); case FILEBENCH_AVD: filebench_shm->shm_avd_ptrs[i].avd_type = AVD_INVALID; filebench_shm->shm_avd_ptrs[i].avd_val.varptr = NULL; (void) ipc_mutex_unlock(&filebench_shm->shm_malloc_lock); return ((char *)&filebench_shm->shm_avd_ptrs[i]); case FILEBENCH_RANDDIST: (void) memset((char *)&filebench_shm->shm_randdist[i], 0, sizeof (randdist_t)); (void) ipc_mutex_unlock(&filebench_shm->shm_malloc_lock); return ((char *)&filebench_shm->shm_randdist[i]); } filebench_log(LOG_ERROR, "Attempt to ipc_malloc unknown object type (%d)!", obj_type); (void) ipc_mutex_unlock(&filebench_shm->shm_malloc_lock); return (NULL); }
/* * Frees a filebench object of type "type" at the location * pointed to by "addr". It uses the type and address to * calculate which object is being freed, and clears its * allocation map entry. */ void ipc_free(int type, char *addr) { int item; caddr_t base = 0; size_t offset; size_t size = 0; if (addr == NULL) { filebench_log(LOG_ERROR, "Freeing type %d %zx", type, addr); return; } switch (type) { case FILEBENCH_FILESET: base = (caddr_t)&filebench_shm->shm_fileset[0]; size = sizeof (fileset_t); break; case FILEBENCH_FILESETENTRY: base = (caddr_t)&filebench_shm->shm_filesetentry[0]; size = sizeof (filesetentry_t); break; case FILEBENCH_POSSET: base = (caddr_t)&filebench_shm->shm_posset[0]; size = sizeof (struct posset); break; case FILEBENCH_PROCFLOW: base = (caddr_t)&filebench_shm->shm_procflow[0]; size = sizeof (procflow_t); break; case FILEBENCH_THREADFLOW: base = (caddr_t)&filebench_shm->shm_threadflow[0]; size = sizeof (threadflow_t); break; case FILEBENCH_FLOWOP: base = (caddr_t)&filebench_shm->shm_flowop[0]; size = sizeof (flowop_t); break; case FILEBENCH_VARIABLE: base = (caddr_t)&filebench_shm->shm_var[0]; size = sizeof (var_t); break; case FILEBENCH_AVD: base = (caddr_t)&filebench_shm->shm_avd_ptrs[0]; size = sizeof (avd_t); break; case FILEBENCH_RANDDIST: base = (caddr_t)&filebench_shm->shm_randdist[0]; size = sizeof (randdist_t); break; } offset = ((size_t)addr - (size_t)base); item = offset / size; (void) ipc_mutex_lock(&filebench_shm->shm_malloc_lock); filebench_shm->shm_bitmap[type][item] = 0; (void) ipc_mutex_unlock(&filebench_shm->shm_malloc_lock); }
/* * Frees a filebench object of type "type" at the location * pointed to by "addr". It uses the type and address to * calculate which object is being freed, and clears its * allocation map entry. */ void ipc_free(int type, char *addr) { int item; caddr_t base; size_t offset; size_t size; if (addr == NULL) { filebench_log(LOG_ERROR, "Freeing type %d %zx", type, addr); return; } switch (type) { case FILEBENCH_FILESET: base = (caddr_t)&filebench_shm->fileset[0]; size = sizeof (fileset_t); break; case FILEBENCH_FILESETENTRY: base = (caddr_t)&filebench_shm->filesetentry[0]; size = sizeof (filesetentry_t); break; case FILEBENCH_PROCFLOW: base = (caddr_t)&filebench_shm->procflow[0]; size = sizeof (procflow_t); break; case FILEBENCH_THREADFLOW: base = (caddr_t)&filebench_shm->threadflow[0]; size = sizeof (threadflow_t); break; case FILEBENCH_FLOWOP: base = (caddr_t)&filebench_shm->flowop[0]; size = sizeof (flowop_t); break; case FILEBENCH_INTEGER: base = (caddr_t)&filebench_shm->integer_ptrs[0]; size = sizeof (caddr_t); break; case FILEBENCH_STRING: base = (caddr_t)&filebench_shm->string_ptrs[0]; size = sizeof (caddr_t); break; case FILEBENCH_VARIABLE: base = (caddr_t)&filebench_shm->var[0]; size = sizeof (var_t); break; } offset = ((size_t)addr - (size_t)base); item = offset / size; (void) ipc_mutex_lock(&filebench_shm->malloc_lock); filebench_shm->bitmap[type][item] = 0; (void) ipc_mutex_unlock(&filebench_shm->malloc_lock); }
/* * Initialize the Interprocess Communication system and its associated shared * memory structure. It first creates a temporary file using the mkstemp() * function. It than sets the file large enough to hold the filebench_shm and an * additional megabyte. (Additional megabyte is required to make sure that all * sizeof(filebench_shm) bytes plus page alignment bytes will fit in the file.) * The file is then memory mapped. Once the shared memory region is created, * ipc_init initializes various locks, pointers, and variables in the shared * memory. It also uses ftok() to get a shared memory semaphore key for later * use in allocating shared semaphores. */ void ipc_init(void) { int shmfd; char tmpbuf[MB]; key_t key; #ifdef HAVE_SEM_RMID int sys_semid; #endif shmfd = mkstemp(shmpath); if (shmfd < 0) { filebench_log(LOG_FATAL, "Could not create shared memory " "file %s: %s", shmpath, strerror(errno)); exit(1); } (void)lseek(shmfd, sizeof(filebench_shm_t), SEEK_SET); if (write(shmfd, tmpbuf, MB) != MB) { filebench_log(LOG_FATAL, "Could not write to the shared memory " "file: %s", strerror(errno)); exit(1); } if ((filebench_shm = (filebench_shm_t *)mmap(NULL, sizeof(filebench_shm_t), PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0)) == MAP_FAILED) { filebench_log(LOG_FATAL, "Could not mmap the shared " "memory file: %s", strerror(errno)); exit(1); } (void) memset(filebench_shm, 0, (char *)&filebench_shm->shm_marker - (char *)filebench_shm); /* * First, initialize all the structures needed for the filebench_log() * function to work correctly with the log levels other than LOG_FATAL */ filebench_shm->shm_epoch = gethrtime(); filebench_shm->shm_debug_level = LOG_VERBOSE; /* Setup mutexes for object lists */ ipc_mutexattr_init(IPC_MUTEX_NORMAL); ipc_mutexattr_init(IPC_MUTEX_PRIORITY); ipc_mutexattr_init(IPC_MUTEX_ROBUST); ipc_mutexattr_init(IPC_MUTEX_PRI_ROB); (void) pthread_mutex_init(&filebench_shm->shm_msg_lock, ipc_mutexattr(IPC_MUTEX_NORMAL)); filebench_log(LOG_INFO, "Allocated %lldMB of shared memory", (sizeof(filebench_shm_t) + MB) / MB); filebench_shm->shm_rmode = FILEBENCH_MODE_TIMEOUT; filebench_shm->shm_string_ptr = &filebench_shm->shm_strings[0]; filebench_shm->shm_ptr = (char *)filebench_shm->shm_addr; filebench_shm->shm_path_ptr = &filebench_shm->shm_filesetpaths[0]; (void) pthread_mutex_init(&filebench_shm->shm_fileset_lock, ipc_mutexattr(IPC_MUTEX_NORMAL)); (void) pthread_mutex_init(&filebench_shm->shm_posset_lock, ipc_mutexattr(IPC_MUTEX_NORMAL)); (void) pthread_mutex_init(&filebench_shm->shm_procflow_lock, ipc_mutexattr(IPC_MUTEX_NORMAL)); (void) pthread_mutex_init(&filebench_shm->shm_procs_running_lock, ipc_mutexattr(IPC_MUTEX_NORMAL)); (void) pthread_mutex_init(&filebench_shm->shm_threadflow_lock, ipc_mutexattr(IPC_MUTEX_NORMAL)); (void) pthread_mutex_init(&filebench_shm->shm_flowop_lock, ipc_mutexattr(IPC_MUTEX_NORMAL)); (void) pthread_mutex_init(&filebench_shm->shm_eventgen_lock, ipc_mutexattr(IPC_MUTEX_PRI_ROB)); (void) pthread_mutex_init(&filebench_shm->shm_malloc_lock, ipc_mutexattr(IPC_MUTEX_NORMAL)); (void) pthread_mutex_init(&filebench_shm->shm_ism_lock, ipc_mutexattr(IPC_MUTEX_NORMAL)); (void) ipc_mutex_lock(&filebench_shm->shm_ism_lock); (void) pthread_cond_init(&filebench_shm->shm_eventgen_cv, ipc_condattr()); (void) pthread_rwlock_init(&filebench_shm->shm_flowop_find_lock, ipc_rwlockattr()); (void) pthread_rwlock_init(&filebench_shm->shm_run_lock, ipc_rwlockattr()); /* Create semaphore */ if ((key = ftok(shmpath, 1)) < 0) { filebench_log(LOG_ERROR, "cannot create sem: %s", strerror(errno)); exit(1); } #ifdef HAVE_SEM_RMID if ((sys_semid = semget(key, 0, 0)) != -1) (void) semctl(sys_semid, 0, IPC_RMID); #endif filebench_shm->shm_semkey = key; filebench_shm->shm_sys_semid = -1; filebench_shm->shm_log_fd = -1; filebench_shm->shm_dump_fd = -1; filebench_shm->shm_eventgen_hz = 0; filebench_shm->shm_id = -1; }
/* * Allocates filebench objects from pre allocated region of * shareable memory. The memory region is partitioned into sets * of objects during initialization. This routine scans for * the first unallocated object of type "type" in the set of * available objects, and makes it as allocated. The routine * returns a pointer to the object, or NULL if all objects have * been allocated. */ void * ipc_malloc(int type) { int i; int max = filebench_sizes[type]; (void) ipc_mutex_lock(&filebench_shm->malloc_lock); for (i = 0; i < max; i++) { if (filebench_shm->bitmap[type][i] == 0) break; } if (i >= max) { filebench_log(LOG_ERROR, "Out of shared memory (%d)!", type); (void) ipc_mutex_unlock(&filebench_shm->malloc_lock); return (NULL); } filebench_shm->bitmap[type][i] = 1; switch (type) { case FILEBENCH_FILESET: (void) memset((char *)&filebench_shm->fileset[i], 0, sizeof (fileset_t)); (void) ipc_mutex_unlock(&filebench_shm->malloc_lock); return ((char *)&filebench_shm->fileset[i]); case FILEBENCH_FILESETENTRY: (void) memset((char *)&filebench_shm->filesetentry[i], 0, sizeof (filesetentry_t)); (void) ipc_mutex_unlock(&filebench_shm->malloc_lock); return ((char *)&filebench_shm->filesetentry[i]); case FILEBENCH_PROCFLOW: (void) memset((char *)&filebench_shm->procflow[i], 0, sizeof (procflow_t)); (void) ipc_mutex_unlock(&filebench_shm->malloc_lock); return ((char *)&filebench_shm->procflow[i]); case FILEBENCH_THREADFLOW: (void) memset((char *)&filebench_shm->threadflow[i], 0, sizeof (threadflow_t)); (void) ipc_mutex_unlock(&filebench_shm->malloc_lock); return ((char *)&filebench_shm->threadflow[i]); case FILEBENCH_FLOWOP: (void) memset((char *)&filebench_shm->flowop[i], 0, sizeof (flowop_t)); (void) ipc_mutex_unlock(&filebench_shm->malloc_lock); return ((char *)&filebench_shm->flowop[i]); case FILEBENCH_INTEGER: filebench_shm->integer_ptrs[i] = NULL; (void) ipc_mutex_unlock(&filebench_shm->malloc_lock); return ((char *)&filebench_shm->integer_ptrs[i]); case FILEBENCH_STRING: filebench_shm->string_ptrs[i] = NULL; (void) ipc_mutex_unlock(&filebench_shm->malloc_lock); return ((char *)&filebench_shm->string_ptrs[i]); case FILEBENCH_VARIABLE: (void) memset((char *)&filebench_shm->var[i], 0, sizeof (var_t)); (void) ipc_mutex_unlock(&filebench_shm->malloc_lock); return ((char *)&filebench_shm->var[i]); } filebench_log(LOG_ERROR, "Attempt to ipc_malloc unknown type (%d)!", type); return (NULL); }
/* * Initialize the Interprocess Communication system and its * associated shared memory structure. It first creates a * temporary file using either the mkstemp() function or the * tempnam() and open() functions. If the process model is in * use,it than sets the file large enough to hold the * filebench_shm and an additional Megabyte. The file is then * memory mapped. If the process model is not in use, it simply * mallocs a region of sizeof (filebench_shm_t). * * Once the shared memory region / file is created, ipc_init * initializes various locks pointers, and variables in the * shared memory. It also uses ftok() to get a shared memory * semaphore key for later use in allocating shared semaphores. */ void ipc_init(void) { filebench_shm_t *buf = malloc(MB); key_t key; caddr_t c1; caddr_t c2; #ifdef HAVE_SEM_RMID int semid; #endif #ifdef HAVE_MKSTEMP shmpath = (char *)malloc(128); (void) strcpy(shmpath, "/var/tmp/fbenchXXXXXX"); shmfd = mkstemp(shmpath); #else shmfd = open(shmpath, O_CREAT | O_RDWR | O_TRUNC, 0666); shmpath = tempnam("/var/tmp", "fbench"); #endif /* HAVE_MKSTEMP */ #ifdef USE_PROCESS_MODEL if (shmfd < 0) { filebench_log(LOG_FATAL, "Cannot open shm %s: %s", shmpath, strerror(errno)); exit(1); } (void) lseek(shmfd, sizeof (filebench_shm_t), SEEK_SET); if (write(shmfd, buf, MB) != MB) { filebench_log(LOG_FATAL, "Cannot allocate shm: %s", strerror(errno)); exit(1); } /* LINTED E_BAD_PTR_CAST_ALIGN */ if ((filebench_shm = (filebench_shm_t *)mmap((caddr_t)0, sizeof (filebench_shm_t), PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0)) == NULL) { filebench_log(LOG_FATAL, "Cannot mmap shm"); exit(1); } #else if ((filebench_shm = (filebench_shm_t *)malloc(sizeof (filebench_shm_t))) == NULL) { filebench_log(LOG_FATAL, "Cannot malloc shm"); exit(1); } #endif /* USE_PROCESS_MODEL */ c1 = (caddr_t)filebench_shm; c2 = (caddr_t)&filebench_shm->marker; (void) memset(filebench_shm, 0, c2 - c1); filebench_shm->epoch = gethrtime(); filebench_shm->debug_level = LOG_VERBOSE; filebench_shm->shm_rmode = FILEBENCH_MODE_TIMEOUT; filebench_shm->string_ptr = &filebench_shm->strings[0]; filebench_shm->shm_ptr = (char *)filebench_shm->shm_addr; filebench_shm->path_ptr = &filebench_shm->filesetpaths[0]; /* Setup mutexes for object lists */ (void) pthread_mutex_init(&filebench_shm->fileset_lock, ipc_mutexattr()); (void) pthread_mutex_init(&filebench_shm->procflow_lock, ipc_mutexattr()); (void) pthread_mutex_init(&filebench_shm->threadflow_lock, ipc_mutexattr()); (void) pthread_mutex_init(&filebench_shm->flowop_lock, ipc_mutexattr()); (void) pthread_mutex_init(&filebench_shm->msg_lock, ipc_mutexattr()); (void) pthread_mutex_init(&filebench_shm->eventgen_lock, ipc_mutexattr()); (void) pthread_mutex_init(&filebench_shm->malloc_lock, ipc_mutexattr()); (void) pthread_mutex_init(&filebench_shm->ism_lock, ipc_mutexattr()); (void) pthread_cond_init(&filebench_shm->eventgen_cv, ipc_condattr()); (void) pthread_rwlock_init(&filebench_shm->flowop_find_lock, ipc_rwlockattr()); (void) pthread_rwlock_init(&filebench_shm->run_lock, ipc_rwlockattr()); (void) pthread_rwlock_rdlock(&filebench_shm->run_lock); (void) ipc_mutex_lock(&filebench_shm->ism_lock); /* Create semaphore */ if ((key = ftok(shmpath, 1)) < 0) { filebench_log(LOG_ERROR, "cannot create sem: %s", strerror(errno)); exit(1); } #ifdef HAVE_SEM_RMID if ((semid = semget(key, 0, 0)) != -1) (void) semctl(semid, 0, IPC_RMID); #endif filebench_shm->semkey = key; filebench_shm->log_fd = -1; filebench_shm->dump_fd = -1; filebench_shm->eventgen_hz = 0; filebench_shm->shm_id = -1; free(buf); }
struct posset * posset_alloc(avd_t name, avd_t type, avd_t seed, avd_t max, avd_t entries) { struct posset *ps; int ret; ps = (struct posset *)ipc_malloc(FILEBENCH_POSSET); if (!ps) { filebench_log(LOG_ERROR, "posset_alloc: " "can't malloc posset in IPC region"); return NULL; } /* we do not support any possets except "rnd" at the moment */ if (!strcmp(avd_get_str(type), "rnd")) { ps->ps_type = avd_int_alloc(POSSET_TYPE_RND); } else if (!strcmp(avd_get_str(type), "collection")) { ps->ps_type = avd_int_alloc(POSSET_TYPE_COLLECTION); } else { filebench_log(LOG_ERROR, "posset_alloc: wrong posset type"); ipc_free(FILEBENCH_POSSET, (char *)ps); return NULL; } ps->ps_name = name; ps->ps_rnd_seed = seed; ps->ps_rnd_max = max; ps->ps_entries = entries; if (avd_get_int(ps->ps_entries) > POSSET_MAX_ENTRIES) { filebench_log(LOG_ERROR, "posset_alloc: the number of posset " "entries is too high"); ipc_free(FILEBENCH_POSSET, (char *)ps); return NULL; } /* depending on the posset type generate (or load) positions */ switch (avd_get_int(ps->ps_type)) { case(POSSET_TYPE_RND): ret = posset_rnd_fill(ps); break; case(POSSET_TYPE_COLLECTION): ret = posset_collection_fill(ps); break; default: filebench_log(LOG_ERROR, "posset_alloc: wrong posset type"); ipc_free(FILEBENCH_POSSET, (char *)ps); return NULL; } if (ret < 0) { filebench_log(LOG_ERROR, "posset_alloc: could not fill posset"); ipc_free(FILEBENCH_POSSET, (char *)ps); return NULL; } /* add posset to the global list */ (void)ipc_mutex_lock(&filebench_shm->shm_posset_lock); if (filebench_shm->shm_possetlist == NULL) { filebench_shm->shm_possetlist = ps; ps->ps_next = NULL; } else { ps->ps_next = filebench_shm->shm_possetlist; filebench_shm->shm_possetlist = ps; } (void)ipc_mutex_unlock(&filebench_shm->shm_posset_lock); return ps; }
/* * Initializes a random distribution entity, converting avd_t * parameters to doubles, and converting the list of probability density * function table entries, if supplied, into a probablilty function table */ static void randdist_init_one(randdist_t *rndp) { probtabent_t *rdte_hdp, *ptep; double tablemean, tablemin; int pteidx; /* convert parameters to doubles */ rndp->rnd_dbl_gamma = (double)avd_get_int(rndp->rnd_gamma) / 1000.0; if (rndp->rnd_mean != NULL) rndp->rnd_dbl_mean = (double)avd_get_int(rndp->rnd_mean); else rndp->rnd_dbl_mean = rndp->rnd_dbl_gamma; /* de-reference min and round amounts for later use */ rndp->rnd_vint_min = avd_get_int(rndp->rnd_min); rndp->rnd_vint_round = avd_get_int(rndp->rnd_round); filebench_log(LOG_DEBUG_IMPL, "init random var %s: Mean = %6.0llf, Gamma = %6.3llf, Min = %llu", rndp->rnd_var->var_name, rndp->rnd_dbl_mean, rndp->rnd_dbl_gamma, (u_longlong_t)rndp->rnd_vint_min); /* initialize distribution to apply */ switch (rndp->rnd_type & RAND_TYPE_MASK) { case RAND_TYPE_UNIFORM: rndp->rnd_get = rand_uniform_get; break; case RAND_TYPE_GAMMA: rndp->rnd_get = rand_gamma_get; break; case RAND_TYPE_TABLE: rndp->rnd_get = rand_table_get; break; default: filebench_log(LOG_DEBUG_IMPL, "Random Type not Specified"); filebench_shutdown(1); return; } /* initialize source of random numbers */ if (rndp->rnd_type & RAND_SRC_GENERATOR) { rndp->rnd_src = rand_src_rand48; rand_seed_set(rndp); } else { rndp->rnd_src = rand_src_urandom; } /* any random distribution table to convert? */ if ((rdte_hdp = rndp->rnd_probtabs) == NULL) return; /* determine random distribution max and mins and initialize table */ pteidx = 0; tablemean = 0.0; for (ptep = rdte_hdp; ptep; ptep = ptep->pte_next) { double dmin, dmax; int entcnt; dmax = (double)avd_get_int(ptep->pte_segmax); dmin = (double)avd_get_int(ptep->pte_segmin); /* initialize table minimum on first pass */ if (pteidx == 0) tablemin = dmin; /* update table minimum */ if (tablemin > dmin) tablemin = dmin; entcnt = (int)avd_get_int(ptep->pte_percent); tablemean += (((dmin + dmax)/2.0) * (double)entcnt); /* populate the lookup table */ for (; entcnt > 0; entcnt--) { rndp->rnd_rft[pteidx].rf_base = dmin; rndp->rnd_rft[pteidx].rf_range = dmax - dmin; pteidx++; } } /* check to see if probability equals 100% */ if (pteidx != PF_TAB_SIZE) filebench_log(LOG_ERROR, "Prob table only totals %d%%", pteidx); /* If table is not supplied with a mean value, set it to table mean */ if (rndp->rnd_dbl_mean == 0.0) rndp->rnd_dbl_mean = (double)tablemean / (double)PF_TAB_SIZE; /* now normalize the entries for a min value of 0, mean of 1 */ tablemean = (tablemean / 100.0) - tablemin; /* special case if really a constant value */ if (tablemean == 0.0) { for (pteidx = 0; pteidx < PF_TAB_SIZE; pteidx++) { rndp->rnd_rft[pteidx].rf_base = 0.0; rndp->rnd_rft[pteidx].rf_range = 0.0; } return; } for (pteidx = 0; pteidx < PF_TAB_SIZE; pteidx++) { rndp->rnd_rft[pteidx].rf_base = ((rndp->rnd_rft[pteidx].rf_base - tablemin) / tablemean); rndp->rnd_rft[pteidx].rf_range = (rndp->rnd_rft[pteidx].rf_range / tablemean); } }
/* * Create a pool of shared memory to fit the per-thread * allocations. Uses shmget() to create a shared memory region * of size "size", attaches to it using shmat(), and stores * the returned address of the region in filebench_shm->shm_addr. * The pool is only created on the first call. The routine * returns 0 if successful or the pool already exists, * -1 otherwise. */ int ipc_ismcreate(size_t size) { #ifdef HAVE_SHM_SHARE_MMU int flag = SHM_SHARE_MMU; #else int flag = 0; #endif /* HAVE_SHM_SHARE_MMU */ int tmp_shmid; /* Already done? */ if (filebench_shm->shm_id != -1) return (0); filebench_log(LOG_VERBOSE, "Creating %zd bytes of ISM Shared Memory...", size); /* * We map a temp shared memory in place to force a gap * above any heap/anon allocations, to ensure we can * remap the shm at the same address in the slave procs * */ if ((tmp_shmid = shmget(0, 1048576, IPC_CREAT | 0666)) == -1) { filebench_log(LOG_ERROR, "Failed to create %zd bytes of ISM shared memory", 1048576); return (-1); } if ((filebench_shm->shm_addr = (caddr_t)shmat(tmp_shmid, 0, flag)) == (void *)-1) { filebench_log(LOG_ERROR, "Failed to attach %zd bytes of created ISM shared memory, id %lld", filebench_shm->shm_id, size); return (-1); } if ((filebench_shm->shm_id = shmget(0, size, IPC_CREAT | 0666)) == -1) { filebench_log(LOG_ERROR, "Failed to create %zd bytes of ISM shared memory", size); return (-1); } /* Remove the temp shm */ (void) shmctl(tmp_shmid, IPC_RMID, 0); if ((filebench_shm->shm_addr = (caddr_t)shmat(filebench_shm->shm_id, 0, flag)) == (void *)-1) { filebench_log(LOG_ERROR, "Failed to attach %zd bytes of created ISM shared memory, id %lld", size, filebench_shm->shm_id); return (-1); } filebench_shm->shm_ptr = (char *)filebench_shm->shm_addr; filebench_log(LOG_VERBOSE, "Allocated %zd bytes of ISM Shared Memory... at %zx, id %zd", size, filebench_shm->shm_addr, filebench_shm->shm_id); /* Locked until allocated to block allocs */ (void) ipc_mutex_unlock(&filebench_shm->ism_lock); return (0); }