00001
00040 #include "vmbo.h"
00041 #include "mmu.h"
00042 #include "proc.h"
00043 #include "io_device.h"
00044
00045 extern proc_t **proc_table;
00046 extern int max_proc;
00047 extern int anticipatory_paging;
00048 extern int reference_count;
00049 extern uint16_t *reference_string;
00050
00057 int debug;
00058
00063 static struct option longopts[] = {
00064 { "anticipatory", no_argument, NULL, 'a' },
00065 { "debug", no_argument, NULL, 'd' },
00066 { "help", no_argument, NULL, 'h' },
00067 { "locality", required_argument, NULL, 'L' },
00068 { "probabilities", required_argument, NULL, 'l' },
00069 { "all-memory", no_argument, NULL, 'M' },
00070 { "memory-read", required_argument, NULL, 'm' },
00071 { "processes", required_argument, NULL, 'p' },
00072 { "probability", required_argument, NULL, 'P' },
00073 { "reference", required_argument, NULL, 'r' },
00074 { "ram-size", required_argument, NULL, 'R' },
00075 { "frame-size", required_argument, NULL, 's' },
00076 { "Tmin", required_argument, NULL, 't' },
00077 { "Tmax", required_argument, NULL, 'T' },
00078 { "write-enabled", no_argument, NULL, 'w' },
00079 { "version", no_argument, NULL, 'v' },
00080 { NULL, 0, NULL, 0 }
00081 };
00082
00090 static void usage()
00091 {
00092 fprintf(stderr, "Utilizzo: vmbo [OPZIONI]...\n\n"
00093 "Opzioni generali:\n"
00094 " -h, --help Stampa questo help\n"
00095 " -v, --version Stampa la versione del programma ed esce\n"
00096 " -d, --debug Attiva il debug\n\n"
00097 "Opzioni MMU:\n"
00098 " -a, --anticipatory Disabilita l'anticipatory paging\n"
00099 " -m, --memory-read=NUM Numero massimo di accessi alla memoria\n"
00100 " -R, --ram-size=NUM Quantita di RAM disponibile\n"
00101 " -s, --frame-size=NUM Dimensione della pagina/frame\n"
00102 " -w, --write-enabled Abilita gli accessi in scrittura alla memoria\n\n"
00103 "Opzioni PROCESSO:\n"
00104 " -M, --all-memory Forza i processi ad allocare il massimo della memoria\n"
00105 " -p, --processes=NUM Numero di processi contemporanei\n"
00106 " -P, --probability=NUM Probabilita di accessi alla memoria\n"
00107 " -l, --probabilities=LIST Specifica la probabilta per ogni processo\n"
00108 " -L, --locality=NUM Specifica la percentuale di localita temporale\n"
00109 " -r, --reference=LIST Specifica la reference string da usare\n\n"
00110 "Opzioni DISPOSITIVO I/O:\n"
00111 " -t, --Tmin=NUM Tempo minimo d'attesa del dispositivo I/O\n"
00112 " -t, --Tmax=NUM Tempo massimo d'attesa del dispositivo I/O\n\n");
00113 fprintf(stderr, "Esempi d'utilizzo:\n"
00114 " - Esegue 7 processi contemporanei ed effettua 10 letture\n"
00115 " vmbo --max-read=10 --max-processes=7\n"
00116 " - Esegue 3 processi, specificando il ritardo per il dispositivo I/O\n"
00117 " vmbo --max-processes=3 --Tmin=2 --Tmax=30\n"
00118 " - Specifica la probabilita' di effettuare un accesso alla memoria\n"
00119 " vmbo --probability=30\n"
00120 " - Specifica una probabilita' diversa per ogni processo\n"
00121 " vmbo --probabilities=30:20:78:93:80\n"
00122 " - Specifica una reference string per determinare gli accessi\n"
00123 " vmbo --reference=1:2:3:4:1:2:5:1:2:3:4:5\n\n");
00124 }
00125
00126
00127 int
00128 main(int argc, char **argv)
00129 {
00130 pthread_t *tid_mmu, *tid_iodev;
00131 int i, time_seed, ch, error, _Tmin, _Tmax, _max_memory, _locality_prob,
00132 _prob, _max_read, _frame_size, _only_read, _ram_size, io_time_elapsed,
00133 option_index, allocated_pages, total_faults;
00134 char *prob_list, *_reference_string;
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 option_index = 0;
00145 error = 0;
00146 _max_read = 50;
00147 _prob = 80;
00148 max_proc = 5;
00149 _frame_size = 4096;
00150 _ram_size = 1048576;
00151 _only_read = 1;
00152 _Tmin = 1, _Tmax = 100;
00153 _max_memory = 0;
00154 _locality_prob = 30;
00155 _reference_string = prob_list = NULL;
00156 anticipatory_paging = 1;
00157 mmu.offset_bits = log2(_frame_size);
00158 mmu.page_bits = ADDRESS_LENGTH-mmu.offset_bits;
00159
00160 while ((ch = getopt_long(argc, argv, "hadl:L:Mm:r:R:s:t:T:p:P:wv",
00161 longopts, &option_index)) != -1) {
00162 switch (ch) {
00163 case 'a':
00164 anticipatory_paging = 0;
00165 break;
00166 case 'd':
00167 debug++;
00168 break;
00169 case 'L':
00170 if (optarg) {
00171 _locality_prob = atoi(optarg);
00172 if ((_locality_prob < 0) || (_locality_prob >100)) {
00173 fprintf(stderr, "La percentuale di localita' deve "
00174 "essere compresa tra 0 e 100.\n");
00175 error = 2;
00176 }
00177 } else
00178 error = 1;
00179 break;
00180 case 'l':
00181 if (optarg)
00182 prob_list = optarg;
00183 else
00184 error = 1;
00185 break;
00186 case 'M':
00187 _max_memory = 1;
00188 break;
00189 case 'm':
00190 if (optarg) {
00191 _max_read = atoi(optarg);
00192 if (_max_read <= 0) {
00193 fprintf(stderr, "Il numero di accessi alla memoria "
00194 "deve essere positivo.\n");
00195 error = 2;
00196 }
00197 } else
00198 error = 1;
00199 break;
00200 case 'p':
00201 if (optarg) {
00202 max_proc = atoi(optarg);
00203 if (max_proc == 0) {
00204 fprintf(stderr, "Il numero di processi deve essere "
00205 "positivo.\n");
00206 error = 2;
00207 }
00208 } else
00209 error = 1;
00210 break;
00211 case 'P':
00212 if (optarg) {
00213 _prob = atof(optarg)*100;
00214 if (_prob <= 0 || _prob > 100) {
00215 fprintf(stderr, "La probabilita' deve essere compresa"
00216 " tra 0.1 ed 1.\n");
00217 error = 2;
00218 }
00219 } else
00220 error = 1;
00221 break;
00222 case 'r':
00223 if (optarg)
00224 _reference_string = optarg;
00225 else
00226 error = 1;
00227 break;
00228 case 'R':
00229 if (optarg) {
00230 _ram_size = atoi(optarg);
00231 if (_ram_size > exp2(ADDRESS_LENGTH)) {
00232 fprintf(stderr, "La dimensione della RAM non puo' "
00233 " essere superiore a %d byte.\n",
00234 (int) exp2(ADDRESS_LENGTH));
00235 error = 2;
00236 }
00237 } else
00238 error = 1;
00239 break;
00240 case 's':
00241 if (optarg) {
00242 _frame_size = atoi(optarg);
00243 } else
00244 error = 1;
00245 break;
00246 case 't':
00247 if (optarg)
00248 _Tmin = atoi(optarg);
00249 else
00250 error = 1;
00251 break;
00252 case 'T':
00253 if (optarg)
00254 _Tmax = atoi(optarg);
00255 else
00256 error = 1;
00257 break;
00258 case 'w':
00259 _only_read = 0;
00260 break;
00261 case 'v':
00262 fprintf(stderr, "vmbo versione %d.%d.%d\n",
00263 VER_MAJOR, VER_MINOR, VER_REVISION);
00264 error = 2;
00265 break;
00266 case 'h':
00267 error = 1;
00268 break;
00269 case 0:
00270 break;
00271 }
00272 }
00273
00274 if (error) {
00275 if (error == 1)
00276 usage();
00277 return EXIT_FAILURE;
00278 }
00279
00280
00281
00282
00283
00284 mmu.offset_bits = log2(_frame_size);
00285 mmu.page_bits = ADDRESS_LENGTH-mmu.offset_bits;
00286 for (mmu.offset_mask=0, i=0; i<mmu.offset_bits; i++)
00287 mmu.offset_mask += (uint32_t) exp2(i);
00288 fprintf(stdout, "--> Simulatore inizializzato con indirizzi a %d bit\n",
00289 mmu.offset_bits+mmu.page_bits);
00290
00291
00292
00293
00294 time_seed = (int) time(0);
00295 srandom(time_seed);
00296
00297
00298
00299
00300
00301
00302 tid_mmu = mmu_init(_max_read, _ram_size, _frame_size);
00303
00304
00305
00306
00307
00308 reference_count = (uint16_t) -1;
00309 if (_reference_string) {
00310 char *ap, *prs;
00311 int j;
00312
00313 for (reference_count=j=0; j<strlen(_reference_string); j++)
00314 if (_reference_string[j] == ':')
00315 reference_count++;
00316 mmu.total_access = ++reference_count;
00317 anticipatory_paging = 0;
00318 _prob = 100;
00319 max_proc = 1;
00320 _only_read = 1;
00321 _max_memory = 1;
00322 reference_string = XMALLOC(uint16_t, reference_count);
00323 for (i=0, prs = _reference_string; (ap = strsep(&prs, ":")) != NULL; ) {
00324 if (*ap != '\0')
00325 reference_string[i++] = atoi(ap);
00326 }
00327 }
00328
00329 tid_iodev = io_device_init(_Tmin, _Tmax);
00330 proc_init(max_proc, _prob, _only_read, _max_memory, prob_list, _locality_prob);
00331
00332
00333
00334
00335
00336
00337 pthread_join(*tid_mmu, NULL);
00338 tell_io_device_to_exit();
00339 pthread_join(*tid_iodev, NULL);
00340 for (i = 0; i < max_proc; i++) {
00341 pthread_cond_signal(&proc_table[i]->io_cond);
00342 pthread_join(proc_table[i]->tid, NULL);
00343 fclose(LOG_FILE(i));
00344 }
00345
00346
00347
00348
00349 fprintf(stdout, "\n+==================================================================+\n"
00350 "| S T A T I S T I C H E |\n"
00351 "+==================================================================+\n"
00352 "| PID | NUM | PROB | ACCESSI | PAGE | FAULT | ACCESSI | TEMPO |\n"
00353 "| | PAG | | MEMORIA | FAULT | (%%) | I/O | MEDIO |\n"
00354 "+-----+------+------+---------+---------+-------+---------+--------+\n");
00355 for (total_faults = allocated_pages = io_time_elapsed = i = 0; i < max_proc; i++) {
00356 fprintf(stdout, "|% 4d |% 5d |% 4.0f%% | % 7d | % 7d | % 4.0f%% | % 7d | % 6.0f |\n",
00357 proc_table[i]->pid, proc_table[i]->page_count,
00358 proc_table[i]->percentile,
00359 proc_table[i]->stats.mem_accesses,
00360 proc_table[i]->stats.page_faults,
00361 proc_table[i]->stats.page_faults?
00362 ((float)proc_table[i]->stats.page_faults/
00363 (float)proc_table[i]->stats.mem_accesses)*100:0,
00364 proc_table[i]->stats.io_requests,
00365 proc_table[i]->stats.io_requests?
00366 ((float)proc_table[i]->stats.time_elapsed/
00367 (float)proc_table[i]->stats.io_requests):0);
00368 io_time_elapsed += proc_table[i]->stats.time_elapsed;
00369 allocated_pages += proc_table[i]->page_count;
00370 total_faults += proc_table[i]->stats.page_faults;
00371 }
00372 fprintf(stdout, "+-----+------+------+---------+---------"
00373 "+-------+---------+--------+\n"
00374 " | % 7d | % 7d | % 4.0f%% | % 7d | % 6.0f |\n"
00375 " +---------+---------+-------"
00376 "+---------+--------+\n\n", mmu.total_access, total_faults,
00377 ((float)mmu.page_faults/(float)mmu.total_access)*100,
00378 io_dev.req_count, io_dev.req_count?
00379 ((float)io_time_elapsed/io_dev.req_count):0);
00380
00381 fprintf(stdout, "Pagine virtuali allocate = % 12d\n"
00382 "Memoria virtuale allocata = %12lu (~ %.1f Mb)\n\n",
00383 allocated_pages, (unsigned long) allocated_pages*mmu.page_size,
00384 (float) allocated_pages*mmu.page_size/1048576);
00385
00386
00387
00388
00389
00390 for (i = 0; i < max_proc; i++) {
00391 XFREE(proc_table[i]->page_table);
00392 XFREE(proc_table[i]);
00393 }
00394 XFREE(proc_table);
00395 XFREE(tid_iodev);
00396 XFREE(tid_mmu);
00397 XFREE(reference_string);
00398
00399 return EXIT_SUCCESS;
00400 }
00401
00402
00411 void *
00412 xmalloc(size_t num)
00413 {
00414 void *p = (void *) malloc(num);
00415 if (!p) {
00416 printf("Memory exhausted");
00417 exit(EXIT_FAILURE);
00418 }
00419 return p;
00420 }