Example #1
0
/*
 * Allocates a var (var_t) from interprocess shared memory.
 * Places the allocated var on the end of the globally shared
 * var_dyn_list. Finally, the routine allocates a string
 * containing a copy of the supplied "name" string. If any
 * allocations fails, returns NULL, otherwise it returns a
 * pointer to the newly allocated var.
 */
static var_t *
var_alloc_dynamic(char *name)
{
	var_t *var = NULL;
	var_t *prev = NULL;
	var_t *newvar;

	if ((newvar = (var_t *)ipc_malloc(FILEBENCH_VARIABLE)) == NULL) {
		filebench_log(LOG_ERROR, "Out of memory for variables");
		return (NULL);
	}
	(void) memset(newvar, 0, sizeof (newvar));

	for (var = filebench_shm->var_dyn_list; var != NULL;
	    var = var->var_next)
		prev = var; /* Find end of list */
	if (prev != NULL)
		prev->var_next = newvar;
	else
		filebench_shm->var_dyn_list = newvar;

	if ((newvar->var_name = ipc_stralloc(name)) == NULL) {
		filebench_log(LOG_ERROR, "Out of memory for variables");
		return (NULL);
	}

	return (newvar);
}
Example #2
0
/*
 * Allocates a var_integer_t from ipc memory space and
 * pre-loads it with the vinteger_t "integer". Returns
 * the var_integer_t on success, NULL on failure.
 */
var_integer_t
integer_alloc(vinteger_t integer)
{
	var_integer_t rtn;

	if ((rtn = (vinteger_t *)ipc_malloc(FILEBENCH_INTEGER)) == NULL) {
		filebench_log(LOG_ERROR, "Alloc integer failed");
		return (NULL);
	}

	*rtn = integer;

	filebench_log(LOG_DEBUG_IMPL, "Alloc integer %lld", integer);

	return (rtn);
}
Example #3
0
/*
 * Define a random entity which will contain the parameters of a random
 * distribution.
 */
randdist_t *
randdist_alloc(void)
{
	randdist_t *rndp;

	if ((rndp = (randdist_t *)ipc_malloc(FILEBENCH_RANDDIST)) == NULL) {
		filebench_log(LOG_ERROR, "Out of memory for random dist");
		return (NULL);
	}

	/* place on global list */
	rndp->rnd_next = filebench_shm->shm_rand_list;
	filebench_shm->shm_rand_list = rndp;

	return (rndp);
}
Example #4
0
/*
 * Allocate space for a new custom variable in the shared memory location.
 */
cvar_t *
cvar_alloc(void)
{
	cvar_t *cvar;

	if ((cvar = (cvar_t *)ipc_malloc(FILEBENCH_CVAR)) == NULL) {
		filebench_log(LOG_ERROR, "Out of memory for custom variable");
		return (NULL);
	}

	/* place on the head of the global list */
	cvar->next = filebench_shm->shm_cvar_list;
	filebench_shm->shm_cvar_list = cvar;

	return (cvar);
}
Example #5
0
/*
 * Allocates a string pointer in interprocess shared memory,
 * then allocates and initializes a piece of shared string memory,
 * putting the pointer to it into the just allocated string
 * pointer location. The routine returns a pointer to the
 * string pointer location or returns NULL on error.
 */
var_string_t
string_alloc(char *string)
{
	char **rtn;

	if ((rtn = (char **)ipc_malloc(FILEBENCH_STRING)) == NULL) {
		filebench_log(LOG_ERROR, "Alloc string failed");
		return (NULL);
	}

	*rtn = ipc_stralloc(string);

	filebench_log(LOG_DEBUG_IMPL,
	    "Alloc string %s ptr %zx",
	    string, rtn);

	return (rtn);
}
Example #6
0
/*
 * Obtaines a filesetentry entity for a file to be placed in a
 * (sub)directory of a fileset. The size of the file may be
 * specified by fs_meansize, or calculated from a gamma
 * distribution of parameter fs_sizegamma and of mean size
 * fs_meansize. The filesetentry entity is placed on the file
 * list in the specified parent filesetentry entity, which may
 * be a directory filesetentry, or the root filesetentry in the
 * fileset. It is also placed on the fileset's list of all
 * contained files. Returns 0 if successful or -1 if ipc memory
 * for the path string cannot be allocated.
 */
static int
fileset_populate_file(fileset_t *fileset, filesetentry_t *parent, int serial)
{
	char tmpname[16];
	filesetentry_t *entry;
	double drand;
	double gamma;

	if ((entry = (filesetentry_t *)ipc_malloc(FILEBENCH_FILESETENTRY))
	    == NULL) {
		filebench_log(LOG_ERROR,
		    "fileset_populate_file: Can't malloc filesetentry");
		return (-1);
	}

	(void) pthread_mutex_init(&entry->fse_lock, ipc_mutexattr());
	entry->fse_parent = parent;
	entry->fse_fileset = fileset;
	entry->fse_flags |= FSE_FREE;
	fileset_insfilelist(fileset, entry);

	(void) snprintf(tmpname, sizeof (tmpname), "%08d", serial);
	if ((entry->fse_path = (char *)ipc_pathalloc(tmpname)) == NULL) {
		filebench_log(LOG_ERROR,
		    "fileset_populate_file: Can't alloc path string");
		return (-1);
	}

	gamma = *(fileset->fs_sizegamma) / 1000.0;

	if (gamma > 0) {
		drand = gamma_dist_knuth(gamma, fileset->fs_meansize / gamma);
		entry->fse_size = (off64_t)drand;
	} else {
		entry->fse_size = (off64_t)fileset->fs_meansize;
	}

	fileset->fs_bytes += entry->fse_size;

	fileset->fs_realfiles++;
	return (0);
}
Example #7
0
/*
 * Create an in-memory thread object linked to a parent procflow.
 * A threadflow entity is allocated from shared memory and
 * initialized from the "inherit" threadflow if supplied,
 * otherwise to zeros. The threadflow is assigned a unique
 * thread id, the supplied instance number, the supplied name
 * and added to the procflow's pf_thread list. If no name is
 * supplied or the threadflow can't be allocated, NULL is
 * returned Otherwise a pointer to the newly allocated threadflow
 * is returned.
 *
 * The filebench_shm->shm_threadflow_lock must be held by the caller.
 */
static threadflow_t *
threadflow_define_common(procflow_t *procflow, char *name,
    threadflow_t *inherit, int instance)
{
	threadflow_t *threadflow;
	threadflow_t **threadlistp = &procflow->pf_threads;

	if (name == NULL)
		return (NULL);

	threadflow = (threadflow_t *)ipc_malloc(FILEBENCH_THREADFLOW);

	if (threadflow == NULL)
		return (NULL);

	if (inherit)
		(void) memcpy(threadflow, inherit, sizeof (threadflow_t));
	else
		(void) memset(threadflow, 0, sizeof (threadflow_t));

	threadflow->tf_utid = ++filebench_shm->shm_utid;

	threadflow->tf_instance = instance;
	(void) strcpy(threadflow->tf_name, name);
	threadflow->tf_process = procflow;
	(void) pthread_mutex_init(&threadflow->tf_lock,
	    ipc_mutexattr(IPC_MUTEX_NORMAL));

	filebench_log(LOG_DEBUG_IMPL, "Defining thread %s-%d",
	    name, instance);

	/* Add threadflow to list */
	if (*threadlistp == NULL) {
		*threadlistp = threadflow;
		threadflow->tf_next = NULL;
	} else {
		threadflow->tf_next = *threadlistp;
		*threadlistp = threadflow;
	}

	return (threadflow);
}
Example #8
0
/*
 * Return 0 on success and a non zero error code on failure.
 */
static int
alloc_cvar_lib_info(const char *filename)
{
	int ret = -1;
	cvar_library_info_t *cli = NULL;
	cvar_library_info_t *t;

	cli = (cvar_library_info_t *) ipc_malloc(FILEBENCH_CVAR_LIB_INFO);
	if (!cli)
		goto out;

	cli->filename = ipc_stralloc(filename);
	if (!cli->filename)
		goto out;

	cli->type = ipc_stralloc(gettype(filename));
	if (!cli->type)
		goto out;

	cli->next = NULL;

	if (filebench_shm->shm_cvar_lib_info_list) {
		for (t = filebench_shm->shm_cvar_lib_info_list; t->next != NULL;
				t = t->next); /* Seek to the last entry. */

		cli->index = t->index + 1;
		t->next = cli;
	} else {
		cli->index = 0;
		filebench_shm->shm_cvar_lib_info_list = cli;
	}

	ret = 0;

out:
	if (ret && cli) {
		/* NOTE: There is no mechanism to free cli->filename and cli->type. */
		ipc_free(FILEBENCH_CVAR_LIB_INFO, (char *) cli);
	}

	return ret;
}
Example #9
0
/*
 * Allocates a fileset instance, initializes fs_dirgamma and
 * fs_sizegamma default values, and sets the fileset name to the
 * supplied name string. Puts the allocated fileset on the
 * master fileset list and returns a pointer to it.
 */
fileset_t *
fileset_define(char *name)
{
	fileset_t *fileset;

	if (name == NULL)
		return (NULL);

	if ((fileset = (fileset_t *)ipc_malloc(FILEBENCH_FILESET)) == NULL) {
		filebench_log(LOG_ERROR,
		    "fileset_define: Can't malloc fileset");
		return (NULL);
	}

	filebench_log(LOG_DEBUG_IMPL, "Defining file %s", name);

	(void) ipc_mutex_lock(&filebench_shm->fileset_lock);

	fileset->fs_dirgamma = integer_alloc(1500);
	fileset->fs_sizegamma = integer_alloc(1500);

	/* Add fileset to global list */
	if (filebench_shm->filesetlist == NULL) {
		filebench_shm->filesetlist = fileset;
		fileset->fs_next = NULL;
	} else {
		fileset->fs_next = filebench_shm->filesetlist;
		filebench_shm->filesetlist = fileset;
	}

	(void) ipc_mutex_unlock(&filebench_shm->fileset_lock);

	(void) strcpy(fileset->fs_name, name);

	return (fileset);
}
Example #10
0
/*
 * Allocates a flowop entity and initializes it with inherited
 * contents from the "inherit" flowop, if it is supplied, or
 * with zeros otherwise. In either case the fo_next and fo_exec_next
 * pointers are set to NULL, and fo_thread is set to point to
 * the owning threadflow. The initialized flowop is placed at
 * the head of the global flowop list, and also placed on the
 * tail of the supplied local flowop list, which will either
 * be a threadflow's tf_thrd_fops list or a composite flowop's
 * fo_comp_fops list. The routine locks the flowop's fo_lock and
 * leaves it held on return. If successful, it returns a pointer
 * to the allocated and initialized flowop, otherwise it returns NULL.
 *
 * filebench_shm->shm_flowop_lock must be held by caller.
 */
static flowop_t *
flowop_define_common(threadflow_t *threadflow, char *name, flowop_t *inherit,
    flowop_t **flowoplist_hdp, int instance, int type)
{
	flowop_t *flowop;

	if (name == NULL)
		return (NULL);

	if ((flowop = (flowop_t *)ipc_malloc(FILEBENCH_FLOWOP)) == NULL) {
		filebench_log(LOG_ERROR,
		    "flowop_define: Can't malloc flowop");
		return (NULL);
	}

	filebench_log(LOG_DEBUG_IMPL, "defining flowops %s-%d, addr %zx",
	    name, instance, flowop);

	if (flowop == NULL)
		return (NULL);

	if (inherit) {
		(void) memcpy(flowop, inherit, sizeof (flowop_t));
		(void) pthread_mutex_init(&flowop->fo_lock,
		    ipc_mutexattr(IPC_MUTEX_PRI_ROB));
		(void) ipc_mutex_lock(&flowop->fo_lock);
		flowop->fo_next = NULL;
		flowop->fo_exec_next = NULL;
		filebench_log(LOG_DEBUG_IMPL,
		    "flowop %s-%d calling init", name, instance);
	} else {
		(void) memset(flowop, 0, sizeof (flowop_t));
		flowop->fo_iters = avd_int_alloc(1);
		flowop->fo_type = type;
		(void) pthread_mutex_init(&flowop->fo_lock,
		    ipc_mutexattr(IPC_MUTEX_PRI_ROB));
		(void) ipc_mutex_lock(&flowop->fo_lock);
	}

	/* Create backpointer to thread */
	flowop->fo_thread = threadflow;

	/* Add flowop to global list */
	if (filebench_shm->shm_flowoplist == NULL) {
		filebench_shm->shm_flowoplist = flowop;
		flowop->fo_next = NULL;
	} else {
		flowop->fo_next = filebench_shm->shm_flowoplist;
		filebench_shm->shm_flowoplist = flowop;
	}

	(void) strcpy(flowop->fo_name, name);
	flowop->fo_instance = instance;

	if (flowoplist_hdp == NULL)
		return (flowop);

	/* Add flowop to thread op list */
	if (*flowoplist_hdp == NULL) {
		*flowoplist_hdp = flowop;
		flowop->fo_exec_next = NULL;
	} else {
		flowop_t *flowend;

		/* Find the end of the thread list */
		flowend = *flowoplist_hdp;
		while (flowend->fo_exec_next != NULL)
			flowend = flowend->fo_exec_next;
		flowend->fo_exec_next = flowop;
		flowop->fo_exec_next = NULL;
	}

	return (flowop);
}
Example #11
0
/*
 * Creates a directory node in a fileset, by obtaining a
 * filesetentry entity for the node and initializing it
 * according to parameters of the fileset. It determines a
 * directory tree depth and directory width, optionally using
 * a gamma distribution. If its calculated depth is less then
 * its actual depth in the directory tree, it becomes a leaf
 * node and files itself with "width" number of file type
 * filesetentries, otherwise it files itself with "width"
 * number of directory type filesetentries, using recursive
 * calls to fileset_populate_subdir. The end result of the
 * initial call to this routine is a tree of directories of
 * random width and varying depth with sufficient leaf
 * directories to contain all required files.
 * Returns 0 on success. Returns -1 if ipc path string memory
 * cannot be allocated and returns an error code (currently
 * also -1) from calls to fileset_populate_file or recursive
 * calls to fileset_populate_subdir.
 */
static int
fileset_populate_subdir(fileset_t *fileset, filesetentry_t *parent,
    int serial, double depth)
{
	double randepth, drand, ranwidth, gamma;
	int isleaf = 0;
	char tmpname[16];
	filesetentry_t *entry;
	int i;

	depth += 1;

	/* Create dir node */
	if ((entry = (filesetentry_t *)ipc_malloc(FILEBENCH_FILESETENTRY))
	    == NULL) {
		filebench_log(LOG_ERROR,
		    "fileset_populate_subdir: Can't malloc filesetentry");
		return (-1);
	}

	(void) pthread_mutex_init(&entry->fse_lock, ipc_mutexattr());

	(void) snprintf(tmpname, sizeof (tmpname), "%08d", serial);
	if ((entry->fse_path = (char *)ipc_pathalloc(tmpname)) == NULL) {
		filebench_log(LOG_ERROR,
		    "fileset_populate_subdir: Can't alloc path string");
		return (-1);
	}

	entry->fse_parent = parent;
	entry->fse_flags |= FSE_DIR | FSE_FREE;
	fileset_insdirlist(fileset, entry);

	gamma = *(fileset->fs_dirgamma) / 1000.0;
	if (gamma > 0) {
		drand = gamma_dist_knuth(gamma, fileset->fs_meandepth / gamma);
		randepth = (int)drand;
	} else {
		randepth = (int)fileset->fs_meandepth;
	}

	gamma = *(fileset->fs_sizegamma) / 1000.0;

	if (gamma > 0) {
		drand = gamma_dist_knuth(gamma, fileset->fs_meanwidth / gamma);
		ranwidth = drand;
	} else {
		ranwidth = fileset->fs_meanwidth;
	}

	if (randepth == 0)
		randepth = 1;
	if (ranwidth == 0)
		ranwidth = 1;
	if (depth >= randepth)
		isleaf = 1;

	/*
	 * Create directory of random width according to distribution, or
	 * if root directory, continue until #files required
	 */
	for (i = 1;
	    ((parent == NULL) || (i < ranwidth + 1)) &&
	    (fileset->fs_realfiles < *(fileset->fs_entries)); i++) {
		int ret = 0;

		if (parent && isleaf)
			ret = fileset_populate_file(fileset, entry, i);
		else
			ret = fileset_populate_subdir(fileset, entry, i, depth);

		if (ret != 0)
			return (ret);
	}
	return (0);
}
Example #12
0
/*
 * Obtaines a filesetentry entity for a file to be placed in a
 * (sub)directory of a fileset. The size of the file may be
 * specified by fs_meansize, or calculated from a gamma
 * distribution of parameter fs_sizegamma and of mean size
 * fs_meansize. The filesetentry entity is placed on the file
 * list in the specified parent filesetentry entity, which may
 * be a directory filesetentry, or the root filesetentry in the
 * fileset. It is also placed on the fileset's list of all
 * contained files. Returns 0 if successful or -1 if ipc memory
 * for the path string cannot be allocated, or if a RAW device
 * cannot be located.
 */
static int
fileset_populate_file(fileset_t *fileset, filesetentry_t *parent, 
	char *path, int serial)
{
	char tmpname[16];
	filesetentry_t *entry;
	double drand;
	double gamma;
	struct stat64 sb;
	int fd;
	

	if ((entry = (filesetentry_t *)ipc_malloc(FILEBENCH_FILESETENTRY))
	    == NULL) {
		filebench_log(LOG_ERROR,
		    "fileset_populate_file: Can't malloc filesetentry");
		return (-1);
	}

	(void) pthread_mutex_init(&entry->fse_lock, ipc_mutexattr());
	entry->fse_parent = parent;
	entry->fse_fileset = fileset;
	entry->fse_flags |= FSE_FREE;


	/* RAW File name */
	if (path) {
	        /* check for raw device */
		fd = open(path, O_RDONLY);
       	 	if ((fstat64(fd, &sb) == 0) &&
       	     	((sb.st_mode & S_IFMT) == S_IFBLK) && sb.st_rdev) {
			entry->fse_size = lseek64(fd, 0, SEEK_END);
			close(fd);
                	fileset->fs_attrs |= FILESET_IS_RAW_DEV;
			filebench_log(LOG_INFO,
		    	"RAW device for %s on %s size %lld",
			fileset->fs_name, path, entry->fse_size);
		} else {
			filebench_log(LOG_ERROR,
		    		"fileset_populate_file: Cannot open RAW device %s",
				path);
			close(fd);
                	return (-1);
		}
		
		entry->fse_flags &= FSE_FREE;
		entry->fse_flags |= FSE_EXISTS;
		if ((entry->fse_path = (char *)ipc_pathalloc(path)) == NULL) {
			filebench_log(LOG_ERROR,
			    "fileset_populate_file: Can't alloc path string");
			return (-1);
		}
	} else {
		(void) snprintf(tmpname, sizeof (tmpname), "%08d", serial);
		gamma = *(fileset->fs_sizegamma) / 1000.0;

		if (gamma > 0) {
			drand = gamma_dist_knuth(gamma, fileset->fs_meansize / gamma);
			entry->fse_size = (off64_t)drand;
		} else {
			entry->fse_size = (off64_t)fileset->fs_meansize;
		}
		if ((entry->fse_path = (char *)ipc_pathalloc(tmpname)) == NULL) {
			filebench_log(LOG_ERROR,
			    "fileset_populate_file: Can't alloc path string");
			return (-1);
		}
	}

	fileset_insfilelist(fileset, entry);


	fileset->fs_bytes += entry->fse_size;

	fileset->fs_realfiles++;
	return (0);
}
Example #13
0
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;
}