1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #ifndef _FB_IPC_H
27 #define	_FB_IPC_H
28 
29 #include "filebench.h"
30 
31 /* Mutex Priority Inheritance and Robustness flags */
32 #define	IPC_MUTEX_NORMAL	0x0
33 #define	IPC_MUTEX_PRIORITY	0x1
34 #define	IPC_MUTEX_ROBUST	0x2
35 #define	IPC_MUTEX_PRI_ROB	0x3
36 #define	IPC_NUM_MUTEX_ATTRS	4
37 
38 #define	FILEBENCH_NSEMS 128
39 
40 #define	FILEBENCH_ABORT_ERROR  	1
41 #define	FILEBENCH_ABORT_DONE   	2
42 #define	FILEBENCH_ABORT_RSRC	3
43 #define	FILEBENCH_ABORT_FINI	4
44 
45 	/* run modes */
46 #define	FILEBENCH_MODE_TIMEOUT	0x0
47 #define	FILEBENCH_MODE_Q1STDONE	0x1
48 #define	FILEBENCH_MODE_QALLDONE	0x2
49 
50 	/* misc. modes */
51 #define	FILEBENCH_MODE_NOUSAGE	0x01
52 
53 /*
54  * Types of IPC shared memory pools we have.
55  * ipc_malloc() gets the type as an argument and
56  * allocates a slot from the appropriate pool.
57  * */
58 #define	FILEBENCH_FILESET		0
59 #define	FILEBENCH_FILESETENTRY		1
60 #define	FILEBENCH_PROCFLOW		2
61 #define	FILEBENCH_THREADFLOW		3
62 #define	FILEBENCH_FLOWOP		4
63 #define	FILEBENCH_VARIABLE		5
64 #define	FILEBENCH_AVD			6
65 #define	FILEBENCH_RANDDIST		7
66 #define FILEBENCH_CVAR			8
67 #define FILEBENCH_CVAR_LIB_INFO		9
68 #define	FILEBENCH_MAXTYPE		(FILEBENCH_CVAR_LIB_INFO + 1)
69 
70 /*
71  * The values below are selected by intuition: these limits
72  * seem to be reasonable for medium-scale workloads. If
73  * one needs more processes, threads, flowops, etc., one
74  * has to increase these values
75  */
76 #define	FILEBENCH_NFILESETS		(16)
77 #define	FILEBENCH_NFILESETENTRIES	(1024 * 1024)
78 #define	FILEBENCH_NPROCFLOWS		(1024)
79 #define	FILEBENCH_NTHREADFLOWS 		(1024)
80 /* 16 flowops per threadflow seems reasonable */
81 #define	FILEBENCH_NFLOWOPS 		(16 * 1024)
82 /* variables are not the only one that are specified
83    explicitly in the .f file. Some special
84    variables are used within FB itself. So, let's
85    put this value to some save large value */
86 #define	FILEBENCH_NVARIABLES		(1024)
87 #define	FILEBENCH_NAVDS			(4096)
88 #define	FILEBENCH_NRANDDISTS		(16)
89 #define FILEBENCH_NCVARS		(16)
90 #define FILEBENCH_NCVAR_LIB_INFO	(32)
91 #define	FILEBENCH_MAXBITMAP		FILEBENCH_NFILESETENTRIES
92 
93 /* these below are not regular pools and are allocated separately from ipc_malloc() */
94 #define	FILEBENCH_FILESETPATHMEMORY	(FILEBENCH_NFILESETENTRIES * FSE_MAXPATHLEN)
95 #define	FILEBENCH_STRINGMEMORY		(FILEBENCH_NVARIABLES * 128)
96 #define FILEBENCH_CVAR_HEAPSIZE		(FILEBENCH_NCVARS * 4096)
97 
98 typedef struct filebench_shm {
99 	/*
100 	 * All fields down to shm_marker are set to zero during
101 	 * filebench initialization in ipc_init() function.
102 	 */
103 
104 	/*
105 	 * Global lists and locks for main Filebench objects:
106 	 * filesets, procflows, threaflows, and flowops.
107 	 */
108 	fileset_t	*shm_filesetlist;
109 	pthread_mutex_t shm_fileset_lock;
110 	procflow_t	*shm_procflowlist;
111 	pthread_mutex_t shm_procflow_lock;
112 	/* threadflow_t	*shm_threadflowlist; (this one is per procflow) */
113 	pthread_mutex_t shm_threadflow_lock;
114 	flowop_t	*shm_flowoplist;
115 	pthread_mutex_t shm_flowop_lock;
116 
117 	/*
118 	 * parallel file allocation  control. Restricts number of spawned
119 	 * allocation threads and allows waiting for allocation to finish.
120 	 */
121 	pthread_cond_t	shm_fsparalloc_cv;    /* cv to wait for alloc threads */
122 	int		shm_fsparalloc_count; /* active alloc thread count */
123 	pthread_mutex_t	shm_fsparalloc_lock;  /* lock to protect count */
124 
125 	/*
126 	 * Procflow and process state
127 	 */
128 	int		shm_procs_running; /* count of running processes */
129 	pthread_mutex_t shm_procs_running_lock;	/* protects shm_procs_running */
130 	int		shm_f_abort;	/* stop the run NOW! */
131 	pthread_rwlock_t shm_run_lock;	/* used as barrier to sync run */
132 	flag_t          shm_procflows_defined_flag;  /* indicates that process
133 						creator thread has defined all
134 						the procflows */
135 	/*
136 	 * flowop state
137 	 */
138 	pthread_rwlock_t shm_flowop_find_lock;	/* prevents flowop_find() */
139 					    /* during initial flowop creation */
140 
141 
142 	/*
143 	 * Variable lits.
144 	 */
145 	var_t		*shm_var_list;		/* normal variables */
146 	var_t		*shm_var_loc_list;	/* variables local to composite flowops */
147 
148 	/* List of randdist instances (randdist for every random variable) */
149 	randdist_t	*shm_rand_list;
150 	cvar_t		*shm_cvar_list;    /* custom variables */
151 	cvar_library_info_t *shm_cvar_lib_info_list;
152 
153 	/*
154 	 * log and statistics dumping controls and state
155 	 */
156 	int		shm_debug_level;
157 	int		shm_bequiet;	/* pause run while collecting stats */
158 	int		shm_dump_fd;	/* dump file descriptor */
159 	char		shm_dump_filename[MAXPATHLEN];
160 
161 	/*
162 	 * Event generator state
163 	 */
164 	int		shm_eventgen_enabled; /* event gen in operation */
165 	avd_t		shm_eventgen_hz;   /* number of events per sec. */
166 	uint64_t	shm_eventgen_q;    /* count of unclaimed events */
167 	pthread_mutex_t	shm_eventgen_lock; /* lock protecting count */
168 	pthread_cond_t	shm_eventgen_cv;   /* cv to wait on for more events */
169 
170 	/*
171 	 * System 5 semaphore state
172 	 */
173 	key_t		shm_semkey;
174 	int		shm_sys_semid;
175 	char		shm_semids[FILEBENCH_NSEMS];
176 
177 	/*
178 	 * Misc. pointers and state
179 	 */
180 	char		shm_fscriptname[1024];
181 	int		shm_id;
182 	int		shm_rmode;	/* run mode settings */
183 	int		shm_mmode;	/* misc. mode settings */
184 	int		shm_1st_err;
185 	pthread_mutex_t shm_msg_lock;
186 	pthread_mutexattr_t shm_mutexattr[IPC_NUM_MUTEX_ATTRS];
187 	char		*shm_string_ptr;
188 	char		*shm_path_ptr;
189 	hrtime_t	shm_epoch;
190 	hrtime_t	shm_starttime;
191 	int		shm_utid;
192 	int		lathist_enabled;
193 	int		shm_cvar_heapsize;
194 
195 	/*
196 	 * Shared memory allocation control
197 	 */
198 	pthread_mutex_t shm_ism_lock;
199 	size_t		shm_required;
200 	size_t		shm_allocated;
201 	caddr_t		shm_addr;
202 	char		*shm_ptr;
203 
204 	/*
205 	 * Type of plug-in file system client to use. Defaults to
206 	 * local file system, which is type "0".
207 	 */
208 	fb_plugin_type_t shm_filesys_type;
209 
210 	/*
211 	 * IPC shared memory pools allocation/deallocation control:
212 	 *	- bitmap (if fact, bit is an integer here)
213 	 * 	- last allocated index
214 	 *	- lock for the operations on the pool
215 	 */
216 	int		shm_bitmap[FILEBENCH_MAXTYPE][FILEBENCH_MAXBITMAP];
217 	int		shm_lastbitmapindex[FILEBENCH_MAXTYPE];
218 	pthread_mutex_t shm_malloc_lock;
219 
220 	/*
221 	 * end of pre-zeroed data. We do not bzero pools, because
222 	 * otherwise we will touch every page in the pools and
223 	 * consequently use a lot of physical memory, while
224 	 * in fact, we might not need so much memory later.
225 	 */
226 	int		shm_marker[0];
227 
228 	/*
229 	 * IPC shared memory pools. Allocated to users
230 	 * when ipc_malloc() is called. Not zeroed, but
231 	 * ipc_malloc() will bzero each allocated slot.
232 	 */
233 	fileset_t	shm_fileset[FILEBENCH_NFILESETS];
234 	filesetentry_t	shm_filesetentry[FILEBENCH_NFILESETENTRIES];
235 	procflow_t	shm_procflow[FILEBENCH_NPROCFLOWS];
236 	threadflow_t	shm_threadflow[FILEBENCH_NTHREADFLOWS];
237 	flowop_t	shm_flowop[FILEBENCH_NFLOWOPS];
238 	var_t		shm_var[FILEBENCH_NVARIABLES];
239 	struct avd	shm_avd_ptrs[FILEBENCH_NAVDS];
240 	randdist_t	shm_randdist[FILEBENCH_NRANDDISTS];
241 	cvar_t		shm_cvar[FILEBENCH_NCVARS];
242 	cvar_library_info_t shm_cvar_lib_info[FILEBENCH_NCVAR_LIB_INFO];
243 
244 	/* these below are not regular pools and are allocated separately from ipc_malloc() */
245 	char		shm_strings[FILEBENCH_STRINGMEMORY];
246 	char		shm_filesetpaths[FILEBENCH_FILESETPATHMEMORY];
247 	char		shm_cvar_heap[FILEBENCH_CVAR_HEAPSIZE];
248 
249 } filebench_shm_t;
250 
251 extern char shmpath[128];
252 
253 extern void ipc_init(void);
254 extern int ipc_attach(void *shmaddr, char *shmpath);
255 
256 void *ipc_malloc(int type);
257 void ipc_free(int type, char *addr);
258 
259 pthread_mutexattr_t *ipc_mutexattr(int);
260 pthread_condattr_t *ipc_condattr(void);
261 int ipc_semidalloc(void);
262 void ipc_semidfree(int semid);
263 char *ipc_stralloc(const char *string);
264 char *ipc_pathalloc(char *string);
265 void *ipc_cvar_heapalloc(size_t size);
266 void ipc_cvar_heapfree(void *ptr);
267 int ipc_mutex_lock(pthread_mutex_t *mutex);
268 int ipc_mutex_unlock(pthread_mutex_t *mutex);
269 void ipc_seminit(void);
270 char *ipc_ismmalloc(size_t size);
271 int ipc_ismcreate(size_t size);
272 void ipc_ismdelete(void);
273 void ipc_fini(void);
274 
275 extern filebench_shm_t *filebench_shm;
276 
277 #endif	/* _FB_IPC_H */
278