示例#1
0
文件: flowop.c 项目: blusjune/.bsrc
void
flowop_init(void)
{
	(void) pthread_mutex_init(&controlstats_lock,
	    ipc_mutexattr(IPC_MUTEX_NORMAL));
	flowoplib_flowinit();
}
示例#2
0
文件: fileset.c 项目: alhazred/onarm
/*
 * 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);
}
示例#3
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);
}
示例#4
0
文件: flowop.c 项目: blusjune/.bsrc
/*
 * 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);
}
示例#5
0
文件: ipc.c 项目: auristor/filebench
/*
 * 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(char *fsplug)
{
	int shmfd;
	char tmpbuf[MB] = {0};
	key_t key;
#ifdef HAVE_SEM_RMID
	int sys_semid;
#endif
	char *shmdir;

	shmdir = getenv("FB_SHM_DIR");
	if (shmdir == NULL)
	    shmdir = "/tmp";

	if (asprintf(&shmpath, "%s/filebench-shm-XXXXXX", shmdir) < 0) {
		filebench_log(LOG_FATAL, "Could not name shared memory file");
		exit(1);
	}

	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);

	/*
	 * Pass the name of the target filesystem, if not the local driver
	 */
	if (fsplug)
		fb_strlcpy(filebench_shm->shm_filesys_path,fsplug,
			   sizeof(filebench_shm->shm_filesys_path));

	/*
	 * 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_INFO;

	/* 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_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_dump_fd = -1;
	filebench_shm->shm_eventgen_hz = 0;
	filebench_shm->shm_id = -1;
}
示例#6
0
文件: fileset.c 项目: alhazred/onarm
/*
 * 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);
}
示例#7
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);
}
示例#8
0
文件: ipc.c 项目: alhazred/onarm
/*
 * 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);
}