📄 rf_script.c
字号:
/* script.c * code from raidSim to generate accesses. * supports both synthetic and trace-driven workloads * * adapted from raidsim version (MCH). *//* * $Log: rf_script.c,v $ * Revision 1.42 1996/08/07 21:07:56 jimz * fix up cast of ent_list in non-alpha script reading code * * Revision 1.41 1996/07/28 20:33:06 jimz * i386netbsd port * true/false cleanup * * Revision 1.40 1996/07/27 23:35:53 jimz * Solaris simulator port * * Revision 1.39 1996/07/22 19:52:16 jimz * switched node params to RF_DagParam_t, a union of * a 64-bit int and a void *, for better portability * attempted hpux port, but failed partway through for * lack of a single C compiler capable of compiling all * source files * * Revision 1.38 1996/07/18 22:57:14 jimz * port simulator to AIX * * Revision 1.37 1996/07/15 17:22:18 jimz * nit-pick code cleanup * resolve stdlib problems on DEC OSF * * Revision 1.36 1996/06/09 02:36:46 jimz * lots of little crufty cleanup- fixup whitespace * issues, comment #ifdefs, improve typing in some * places (esp size-related) * * Revision 1.35 1996/06/07 21:33:04 jimz * begin using consistent types for sector numbers, * stripe numbers, row+col numbers, recon unit numbers * * Revision 1.34 1996/06/05 18:06:02 jimz * Major code cleanup. The Great Renaming is now done. * Better modularity. Better typing. Fixed a bunch of * synchronization bugs. Made a lot of global stuff * per-desc or per-array. Removed dead code. * * Revision 1.33 1996/06/03 23:28:26 jimz * more bugfixes * check in tree to sync for IPDS runs with current bugfixes * there still may be a problem with threads in the script test * getting I/Os stuck- not trivially reproducible (runs ~50 times * in a row without getting stuck) * * Revision 1.32 1996/05/30 23:22:16 jimz * bugfixes of serialization, timing problems * more cleanup * * Revision 1.31 1996/05/30 11:29:41 jimz * Numerous bug fixes. Stripe lock release code disagreed with the taking code * about when stripes should be locked (I made it consistent: no parity, no lock) * There was a lot of extra serialization of I/Os which I've removed- a lot of * it was to calculate values for the cache code, which is no longer with us. * More types, function, macro cleanup. Added code to properly quiesce the array * on shutdown. Made a lot of stuff array-specific which was (bogusly) general * before. Fixed memory allocation, freeing bugs. * * Revision 1.30 1996/05/27 18:56:37 jimz * more code cleanup * better typing * compiles in all 3 environments * * Revision 1.29 1996/05/24 22:17:04 jimz * continue code + namespace cleanup * typed a bunch of flags * * Revision 1.28 1996/05/23 21:46:35 jimz * checkpoint in code cleanup (release prep) * lots of types, function names have been fixed * * Revision 1.27 1996/05/23 00:33:23 jimz * code cleanup: move all debug decls to rf_options.c, all extern * debug decls to rf_options.h, all debug vars preceded by rf_ * * Revision 1.26 1996/05/20 16:15:37 jimz * switch to rf_{mutex,cond}_{init,destroy} * * Revision 1.25 1996/05/18 19:51:34 jimz * major code cleanup- fix syntax, make some types consistent, * add prototypes, clean out dead code, et cetera * * Revision 1.24 1995/12/12 18:10:06 jimz * MIN -> RF_MIN, MAX -> RF_MAX, ASSERT -> RF_ASSERT * fix 80-column brain damage in comments * * Revision 1.23 1995/10/09 21:38:18 jimz * enable trace delays on async IOs * * Revision 1.22 1995/10/04 18:29:29 wvcii * disabled printfs in read_traces * * Revision 1.21 1995/07/25 20:15:37 rachad * *** empty log message *** * * Revision 1.20 1995/07/10 15:47:53 rachad * *** empty log message *** * * Revision 1.19 1995/06/23 01:03:24 rachad * Added suport to make the code runnable multiple times * * Revision 1.18 1995/06/12 15:54:40 rachad * Added garbege collection for log structured storage * * Revision 1.17 1995/06/02 03:14:17 holland * size parameter fixed in free of tracebuf * * Revision 1.16 1995/06/02 01:24:20 rachad * Changed script interface, * ConvertActionToAccess will now compute seekLoc in sectors * and size in bytes -> traces with 1/2 k access can be used * * Revision 1.15 1995/06/01 21:52:37 holland * replaced NULL sizes in calls to Free() by -1, and caused this * to suppress the size-mismatch error * * Revision 1.14 1995/04/24 13:25:51 holland * rewrite to move disk queues, recon, & atomic RMW to kernel * * Revision 1.13 1995/04/06 14:47:56 rachad * merge completed * * Revision 1.11.10.2 1995/04/03 20:45:11 holland * misc changes related to distributed sparing * * Revision 1.11.10.1 1995/03/25 19:52:00 holland * initial checkin of on "mark.10" branch * * Revision 1.11 1995/03/09 19:56:08 rachad * Added suport for threadless simulator * * Revision 1.10 1995/03/03 18:36:16 rachad * Simulator mechanism added * * Revision 1.9 1995/02/17 19:39:56 holland * added size param to all calls to Free(). * this is ignored at user level, but necessary in the kernel. * * Revision 1.8 1995/02/17 13:36:48 holland * added bp to call to rf_DoAccess * * Revision 1.7 1995/02/10 18:08:07 holland * fixed a few things I broke during kernelization * * Revision 1.6 1995/02/03 22:31:36 holland * many changes related to kernelization * * Revision 1.5 1995/02/01 15:13:05 holland * moved #include of general.h out of raid.h and into each file * * Revision 1.4 1995/02/01 14:27:31 holland * began changes for kernelization: * changed all instances of mutex_t and cond_t to DECLARE macros * converted configuration code to use config structure * * Revision 1.3 1994/11/29 21:22:44 danner * Support for more of raidsim functionality. * */#include "rf_types.h"#include "rf_sys.h"#include "rf_threadstuff.h"#include <stdio.h>#include <fcntl.h>#include <sys/stat.h>#include <sys/types.h>#include <unistd.h>#include <math.h>#include "rf_raid.h"#include "rf_script.h"#include "rf_debugMem.h"#include "rf_alloclist.h"#include "rf_randmacros.h"#include "rf_dagflags.h"#include "rf_threadid.h"#include "rf_rst.h" /* raidSim trace header file */#include "rf_general.h"#include "rf_driver.h"#include "rf_testcode.h"#define MAX_SCRIPT 20#define MAX_TB_SIZE 1000/**************************************************************************************** * * Code from raidSim to create and manipulate access scripts or trace files * There have been a few adaptations so that this code will work in the driver. * ***************************************************************************************/static RF_AllocListElem_t *cleanupList;static RF_Script_t script[MAX_SCRIPT];static long numAction = 0;static long trace_pid = 0;RF_DECLARE_STATIC_MUTEX(trace_mutex)/* must be int (rather than long) to run on alpha since stored as 32 bits in trace file */static RF_int32 *trace_file_locations, *num_traces;static long local_num_procs, local_disk_size; /* local copies of some data */static long completionCount = 0;/* hash table to map driver thread IDs to trace PIDs. This is very simple & want * it to be very quick, so we don't use the hash.c stuff here. the file location * stuff needs to be an int rather than a long because it's 32 bits in the trace file. */typedef struct RF_ProcTable_s RF_ProcTable_t;struct RF_ProcTable_s { int raidSim_pid, trace_pid; int file_location, traces_used, num_traces; int traces_in_buffer, tracebuf_size; int completed; RF_ScriptTraceEntryList_t *trace_buffer, *trace_pointer; int tfd; /* trace file descriptor */ RF_ProcTable_t *next;};static RF_ProcTable_t **proc_table = NULL;static long proc_table_size;typedef struct RF_LastAccessTable_s RF_LastAccessTable_t;struct RF_LastAccessTable_s { long pid; long address, size; char op; RF_LastAccessTable_t *next;};static RF_LastAccessTable_t **last_access=NULL; /* per-process table used for sequential accesses */static RF_LastAccessTable_t *pid_hash();#define pid_hash_lookup(x) pid_hash((x), 1)#define pid_hash_install(x) pid_hash((x), 0)static int read_traces(int fd, RF_ProcTable_t *p);static void AsyncIOCallbackFunc(void *arg);static void DoAsyncIO(RF_Raid_t *raidPtr, RF_ScriptTraceEntry_t *tp, long diskSize);static void ConfigureRandNum(void);static int rand_int(void);static double Exp(double mean);/* extension on file name that tags it as a trace file */#define TRACE_EXT ".rst"int ShutdownScript(script)RF_Script_t *script;{ RF_LastAccessTable_t *l; RF_ProcTable_t *p; int i; if (script){ if (script[0].trace_fd >= 0) { close(script[0].trace_fd); } if (proc_table) { for (i=0; i<2*local_num_procs; i++) if (proc_table[i]) { for (p = proc_table[i]; p; p = proc_table[i]) { proc_table[i] = p->next; /*close(p->tfd);*/ RF_Free(p->trace_buffer, p->tracebuf_size * sizeof(RF_ScriptTraceEntryList_t)); RF_Free(p, sizeof(*p)); } } } if (last_access) { for (i=0; i<local_num_procs; i++) { for (l= last_access[i]; l; l=last_access[i]) { last_access[i] = l->next; RF_Free(l, sizeof(*l)); } } } if (cleanupList) rf_FreeAllocList(cleanupList); rf_mutex_destroy(&trace_mutex); } return(0);}char traceFileName[100];#define RF_REV32(_w_) { \ int _a, _b, _c, _d; \ _a = ((_w_) & 0xff000000) >> 24; \ _b = ((_w_) & 0x00ff0000) >> 16; \ _c = ((_w_) & 0x0000ff00) >> 8; \ _d = ((_w_) & 0x000000ff); \ (_w_) = (_d<<24)|(_c<<16)|(_b<<8)|_a; \} #define RF_REV16(_w_) { \ int _a, _b; \ _a = ((_w_) & 0xff00) >> 8; \ _b = ((_w_) & 0x00ff); \ (_w_) = (_b<<8)|_a; \} RF_Script_t *ConfigureScript(fileName, diskSize, numProc)char *fileName;RF_SectorCount_t diskSize;long *numProc;{ int fd; /* used for trace file */ FILE *fp; char buffer[120]; long pcheck, numScanned, i, seq_prob; RF_int32 numproc_int; int a, b; char cbuf[100]; int rc; rc = rf_mutex_init(&trace_mutex); if (rc) { RF_ERRORMSG3("Unable to init mutex file %s line %d rc=%d\n", __FILE__, __LINE__, rc); return(NULL); } ConfigureRandNum(); trace_pid = 0; completionCount = 0; numAction = 0; rf_MakeAllocList(cleanupList); strcpy(traceFileName, fileName); if (!strncmp(&fileName[strlen(fileName) - strlen(TRACE_EXT)],TRACE_EXT,strlen(TRACE_EXT))) { /* this is a trace file instead of a script file */ fd = open(fileName, O_RDONLY, 0); if (fd < 0) { fprintf(stderr,"Error: Can not open script or trace file, '%s'.\n", fileName); perror("ConfigureScript"); exit(1); } numAction = 1; script[0].trace_fd = fd; if ( read( fd, (char *) &numproc_int, sizeof(numproc_int) ) != sizeof(numproc_int)) { fprintf(stderr,"Can't read num processes from trace file %s\n",fileName); exit(1); } *numProc = (long) numproc_int;#if RF_IS_BIG_ENDIAN > 0 RF_REV32(*numProc);#endif /* RF_IS_BIG_ENDIAN > 0 */ RF_ASSERT(*numProc < 1000); /* sanity check */ local_num_procs = *numProc; local_disk_size = diskSize; RF_MallocAndAdd(trace_file_locations, *numProc * sizeof(RF_int32), (RF_int32 *), cleanupList); if ( read( fd, (char *) trace_file_locations, sizeof(RF_int32) * local_num_procs ) != sizeof(RF_int32) * local_num_procs) { fprintf(stderr,"Can't read file locations from trace file %s\n",fileName); exit(1); } RF_MallocAndAdd( num_traces, *numProc * sizeof(RF_int32), (int *), cleanupList); if ( read( fd, (char *) num_traces, sizeof(RF_int32) * local_num_procs ) != sizeof(RF_int32) * local_num_procs) { fprintf(stderr,"Can't read num traces from trace file %s\n",fileName); exit(1); }#if RF_IS_BIG_ENDIAN > 0 for(i=0;i<local_num_procs;i++) { RF_REV32(trace_file_locations[i]); RF_REV32(num_traces[i]); }#endif /* RF_IS_BIG_ENDIAN > 0 */ proc_table_size = 2 * (*numProc); /* twice as many entries as processes */ RF_CallocAndAdd( proc_table, proc_table_size, sizeof(RF_ProcTable_t *), (RF_ProcTable_t **), cleanupList ); /* zero it */ if (rf_traceDebug) { fprintf(stderr,"Num processes in trace: %ld\n",*numProc); fprintf(stderr,"File locations:\n"); for (i=0; i<*numProc; i++) { fprintf(stderr,"[%3d] %4d ",i,trace_file_locations[i]); if ( ((i+1)%4) == 0) fprintf(stderr,"\n"); } fprintf(stderr,"\n"); fprintf(stderr,"Traces per process:\n"); for (i=0; i<*numProc; i++) { fprintf(stderr,"[%3d] %4d ",i,num_traces[i]); if ( ((i+1)%4) == 0) fprintf(stderr,"\n"); } fprintf(stderr,"\n"); fflush(stderr); } return(script); } if ( (fp = fopen(fileName, "r")) == NULL) { fprintf(stderr,"Error: unable to open script file \"%s\"\n",fileName); perror("ConfigureScript"); exit(1); } pcheck = 0; fprintf(stderr,"How many parallel threads? "); fgets(cbuf, 100, stdin); local_num_procs = atoi(cbuf); *numProc=local_num_procs; local_num_procs = *numProc; local_disk_size = diskSize; while (fgets(buffer, 120, fp)) { if (buffer[0] == '#') continue; if (numAction >= MAX_SCRIPT) { printf("Error: Ran out of script space.\n"); exit(1); } /* these fields need not be present on the line, so initialize them here */ script[numAction].local_prob = 0; script[numAction].distribution = 'd'; numScanned = sscanf(buffer, "%ld %c %ld %ld %c %ld %ld %ld\n", &script[numAction].probability, &script[numAction].action, &script[numAction].reqSize, &script[numAction].alignment, &script[numAction].distribution, &script[numAction].local_prob, &script[numAction].local_size, &script[numAction].local_offset); if (numScanned != 0 && numScanned != 2 && numScanned != 4 && numScanned != 5 && numScanned != 8) { printf("Error in script file: there must be 2, 4, 5, or 8 fields on each line. Found %d\n",numScanned); printf("Script file format is:\n prob r/w reqSize(KB) alignSize(KB) [reqSizeDist [localProb localSize(%) localOffset(%)]]\n"); exit(1); } if (script[numAction].local_prob) { if ( (script[numAction].local_size + script[numAction].local_offset) > 100) { printf("Error in scriptFile: local_offset + local_size is > 100\n"); exit(1); } if (script[numAction].distribution != 'd') { printf("Warning: using non-deterministic access sizes and non-uniform access can skew the locality distribution\n"); } /* convert local_offset and local_size from percentages of the array to KB */ script[numAction].local_offset *= (diskSize/100); script[numAction].local_size *= (diskSize/100); } if (script[numAction].action == 's') { if (last_access) { fprintf(stderr,"Only one 's' line allowed per script file\n"); exit(1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -