int main(int argc, char *argv[]) { int dummy, dummysigalrm, foreground = 0; struct timeval tv, difftime, curtime, lasttime, *timeout; fd_set rfds, readers; int nfds, n, i, secs, ch; struct sigaction sa; time_t boottime; struct option long_options[] = { {"config", 1, 0, 'c'}, {"debug", 2, 0, 'd'}, {"foreground", 0, 0, 'f'}, {"disable-vifs", 0, 0, 'N'}, {"help", 0, 0, 'h'}, {"version", 0, 0, 'v'}, {"quit-daemon", 0, 0, 'q'}, {"reload-config", 0, 0, 'l'}, {"show-routes", 0, 0, 'r'}, /* {"show-cache", 0, 0, 'i'}, */ /* {"show-debug", 0, 0, 'p'}, */ {0, 0, 0, 0} }; snprintf(versionstring, sizeof (versionstring), "pimd version %s", todaysversion); while ((ch = getopt_long (argc, argv, "c:d::fhlNP::vqr", long_options, NULL)) != EOF) { switch (ch) { case 'c': configfilename = optarg; break; case 'd': if (!optarg) { debug = DEBUG_DEFAULT; } else { char *p,*q; size_t i, len; struct debugname *d; debug = 0; p = optarg; q = NULL; while (p) { q = strchr(p, ','); if (q) *q++ = '\0'; len = strlen(p); for (i = 0, d = debugnames; i < ARRAY_LEN(debugnames); i++, d++) if (len >= d->nchars && strncmp(d->name, p, len) == 0) break; if (i == ARRAY_LEN(debugnames)) return usage(); debug |= d->level; p = q; } } break; case 'f': foreground = 1; break; case 'h': return usage(); case 'l': killshow(SIGHUP, NULL); return 0; case 'N': disable_all_by_default = 1; break; case 'P': #ifdef SNMP if (!optarg) dest_port = DEFAULT_PORT; else { dest_port = strtonum(optarg, 1, 65535, &errstr); if (errstr) { warnx("destination port %s", errstr); dest_port = DEFAULT_PORT; } } #else warnx("SNMP support missing, please feel free to submit a patch."); #endif break; case 'v': printf("%s\n", versionstring); return 0; case 'q': killshow(SIGTERM, NULL); return 0; case 'r': killshow(SIGUSR1, _PATH_PIMD_DUMP); return 0; #if 0 /* XXX: TODO */ case 'i': killshow(SIGUSR2, _PATH_PIMD_CACHE); return 0; case 'p': killshow(SIGQUIT, NULL); return 0; #endif default: return usage(); } } argc -= optind; argv += optind; if (argc > 0) { return usage(); } if (geteuid() != 0) { fprintf(stderr, "%s: must be root\n", __progname); exit(1); } setlinebuf(stderr); if (debug != 0) { struct debugname *d; char c; int tmpd = debug; fprintf(stderr, "debug level 0x%lx ", debug); c = '('; for (d = debugnames; d < debugnames + ARRAY_LEN(debugnames); d++) { if ((tmpd & d->level) == d->level) { tmpd &= ~d->level; fprintf(stderr, "%c%s", c, d->name); c = ','; } } fprintf(stderr, ")\n"); } /* * Create directory for runtime files */ mkdir(_PATH_PIMD_RUNDIR, 0755); /* * Setup logging */ #ifdef LOG_DAEMON (void)openlog("pimd", LOG_PID, LOG_DAEMON); (void)setlogmask(LOG_UPTO(LOG_NOTICE)); #else (void)openlog("pimd", LOG_PID); #endif /* LOG_DAEMON */ logit(LOG_DEBUG, 0, "%s starting", versionstring); do_randomize(); time(&boottime); /* Start up the log rate-limiter */ resetlogging(NULL); callout_init(); init_igmp(); init_pim(); #ifdef HAVE_ROUTING_SOCKETS init_routesock(); #endif /* HAVE_ROUTING_SOCKETS */ init_pim_mrt(); init_timers(); /* TODO: check the kernel DVMRP/MROUTED/PIM support version */ #ifdef SNMP if (i = snmp_init()) return i; #endif /* SNMP */ init_vifs(); init_rp_and_bsr(); /* Must be after init_vifs() */ #ifdef RSRR rsrr_init(); #endif /* RSRR */ sa.sa_handler = handler; sa.sa_flags = 0; /* Interrupt system calls */ sigemptyset(&sa.sa_mask); sigaction(SIGALRM, &sa, NULL); sigaction(SIGHUP, &sa, NULL); sigaction(SIGTERM, &sa, NULL); sigaction(SIGINT, &sa, NULL); sigaction(SIGUSR1, &sa, NULL); sigaction(SIGUSR2, &sa, NULL); FD_ZERO(&readers); FD_SET(igmp_socket, &readers); nfds = igmp_socket + 1; for (i = 0; i < nhandlers; i++) { FD_SET(ihandlers[i].fd, &readers); if (ihandlers[i].fd >= nfds) nfds = ihandlers[i].fd + 1; } IF_DEBUG(DEBUG_IF) dump_vifs(stderr); IF_DEBUG(DEBUG_PIM_MRT) dump_pim_mrt(stderr); /* schedule first timer interrupt */ timer_setTimer(TIMER_INTERVAL, timer, NULL); if (!debug && !foreground) { /* Detach from the terminal */ haveterminal = 0; if (fork()) exit(0); (void)close(0); (void)close(1); (void)close(2); (void)open("/", 0); (void)dup2(0, 1); (void)dup2(0, 2); #ifdef SYSV (void)setpgrp(); #else #ifdef TIOCNOTTY n = open("/dev/tty", 2); if (n >= 0) { (void)ioctl(n, TIOCNOTTY, (char *)0); (void)close(n); } #else if (setsid() < 0) perror("setsid"); #endif /* TIOCNOTTY */ #endif /* SYSV */ } /* End of child process code */ if (pidfile(NULL)) { warn("Cannot create pidfile"); } /* * Main receive loop. */ dummy = 0; dummysigalrm = SIGALRM; difftime.tv_usec = 0; gettimeofday(&curtime, NULL); lasttime = curtime; while (1) { memcpy(&rfds, &readers, sizeof(rfds)); secs = timer_nextTimer(); if (secs == -1) timeout = NULL; else { timeout = &tv; timeout->tv_sec = secs; timeout->tv_usec = 0; } if (boottime) { time_t n; time(&n); if (n > boottime + 15) { struct rp_hold *rph = g_rp_hold; while(rph) { add_rp_grp_entry(&cand_rp_list, &grp_mask_list, rph->address, 1, (u_int16)0xffffff, rph->group, rph->mask, curr_bsr_hash_mask, curr_bsr_fragment_tag); rph = rph->next; } boottime = 0; } } if (sighandled) { if (sighandled & GOT_SIGINT) { sighandled &= ~GOT_SIGINT; break; } if (sighandled & GOT_SIGHUP) { sighandled &= ~GOT_SIGHUP; restart(SIGHUP); /* reconstruct readers and nfds */ FD_ZERO(&readers); FD_SET(igmp_socket, &readers); nfds = igmp_socket + 1; for (i = 0; i < nhandlers; i++) { FD_SET(ihandlers[i].fd, &readers); if (ihandlers[i].fd >= nfds) nfds = ihandlers[i].fd + 1; } memcpy(&rfds, &readers, sizeof(rfds)); } if (sighandled & GOT_SIGUSR1) { sighandled &= ~GOT_SIGUSR1; fdump(SIGUSR1); } if (sighandled & GOT_SIGUSR2) { sighandled &= ~GOT_SIGUSR2; cdump(SIGUSR2); } if (sighandled & GOT_SIGALRM) { sighandled &= ~GOT_SIGALRM; timer(&dummysigalrm); } } if ((n = select(nfds, &rfds, NULL, NULL, timeout)) < 0) { if (errno != EINTR) /* SIGALRM is expected */ logit(LOG_WARNING, errno, "select failed"); continue; } if (n > 0) { /* TODO: shall check first igmp_socket for better performance? */ for (i = 0; i < nhandlers; i++) { if (FD_ISSET(ihandlers[i].fd, &rfds)) { (*ihandlers[i].func)(ihandlers[i].fd, &rfds); } } } /* * Handle timeout queue. * * If select + packet processing took more than 1 second, * or if there is a timeout pending, age the timeout queue. * * If not, collect usec in difftime to make sure that the * time doesn't drift too badly. * * If the timeout handlers took more than 1 second, * age the timeout queue again. XXX This introduces the * potential for infinite loops! */ do { /* * If the select timed out, then there's no other * activity to account for and we don't need to * call gettimeofday. */ if (n == 0) { curtime.tv_sec = lasttime.tv_sec + secs; curtime.tv_usec = lasttime.tv_usec; n = -1; /* don't do this next time through the loop */ } else gettimeofday(&curtime, NULL); difftime.tv_sec = curtime.tv_sec - lasttime.tv_sec; difftime.tv_usec += curtime.tv_usec - lasttime.tv_usec; while (difftime.tv_usec >= 1000000) { difftime.tv_sec++; difftime.tv_usec -= 1000000; } if (difftime.tv_usec < 0) { difftime.tv_sec--; difftime.tv_usec += 1000000; } lasttime = curtime; if (secs == 0 || difftime.tv_sec > 0) age_callout_queue(difftime.tv_sec); secs = -1; } while (difftime.tv_sec > 0); } /* Main loop */ logit(LOG_NOTICE, 0, "%s exiting", versionstring); cleanup(); exit(0); }
int main(int argc, char *argv[]) { struct cache **cache; struct list_entry **access_list; char *filename; FILE *program; char buffer[33]; char operation; unsigned int address; int i, j; int opt; int tmp; int capacity; int way; int blocksize; int set; int words; int index_size; int cache_config_set = 0; int cache_dump_set = 0; int total_reads = 0; int total_writes = 0; int write_backs = 0; int reads_hits = 0; int write_hits = 0; int reads_misses = 0; int write_misses = 0; // Argument check if (argc < 2) { usage(argv[0]); } while ((opt = getopt(argc, argv, "c:x")) != -1) { switch (opt) { case 'c': cache_config_set = 1; if (sscanf(optarg, "%d:%d:%d", &capacity, &way, &blocksize) != 3) { usage(argv[0]); } if (capacity < 4 || capacity > 8192) { printf("Capacity should be between 4B and 8KB.\n"); exit(1); } if (way < 1 || way > 16) { printf("Associativity should be between 1 and 16.\n"); exit(1); } if (blocksize < 4 || blocksize > 32) { printf("Block size should be between 4B and 32B.\n"); exit(1); } set = capacity / way / blocksize; words = blocksize / BYTES_PER_WORD; tmp = set / 2; index_size = 0; while (tmp > 0) { index_size++; tmp >>= 1; } break; case 'x': cache_dump_set = 1; break; case '?': usage(argv[0]); } } if (!cache_config_set) { printf("The cache parameters are specified with \"-c\" option.\n"); exit(1); } if (argc == optind) { usage(argv[0]); } filename = argv[optind]; // allocate cache = (struct cache **) malloc(sizeof(struct cache *) * set); access_list = (struct list_entry **) malloc(sizeof(struct list_entry *) * set); for (i = 0; i < set; i++) { struct list_entry *entry; struct list_entry *prev_entry = NULL; cache[i] = (struct cache *) malloc(sizeof(struct cache) * way); for (j = 0; j < way; j++) { cache[i][j].valid = 0; cache[i][j].dirty = 0; cache[i][j].content = 0x0; } entry = (struct list_entry *) malloc(sizeof(struct list_entry)); entry->way = 0; entry->prev = prev_entry; access_list[i] = entry; for (j = 1; j < way; j++) { entry->next = (struct list_entry *) malloc(sizeof(struct list_entry)); prev_entry = entry; entry = entry->next; entry->way = j; entry->prev = prev_entry; } entry->next = NULL; } // Open program file. program = fopen(filename, "r"); if (program == NULL) { printf("Error: Can't open program file \"%s\"\n", filename); exit(-1); } while (fgets(buffer, 33, program) != NULL) { unsigned int entry; unsigned int index; int _way; struct cache *result_cache; struct list_entry *list_item; int hit; int invalid_exist; sscanf(buffer, "%c %x", &operation, &address); entry = address & ~(blocksize - 1); index = (address / blocksize) & ((1 << index_size) - 1); hit = 0; for (i = 0; i < way; i++) { if (cache[index][i].valid && cache[index][i].content == entry) { hit = 1; _way = i; result_cache = &cache[index][i]; list_item = access_list[index]; while (list_item->way != i) { list_item = list_item->next; } if (list_item->prev != NULL) { list_item->prev->next = list_item->next; if (list_item->next != NULL) { list_item->next->prev = list_item->prev; } access_list[index]->prev = list_item; list_item->prev = NULL; list_item->next = access_list[index]; access_list[index] = list_item; } break; } } if (!hit) { struct cache *evict_cache; list_item = access_list[index]; invalid_exist = 0; for (i = 0; i < way; i++) { if (!cache[index][i].valid) { invalid_exist = 1; evict_cache = &cache[index][i]; _way = i; while (list_item->way != i) { list_item = list_item->next; } break; } } if (!invalid_exist) { for (i = 1; i < way; i++) { list_item = list_item->next; } evict_cache = &cache[index][list_item->way]; _way = list_item->way; } if (evict_cache->dirty) { write_backs++; } evict_cache->valid = 1; evict_cache->dirty = 0; evict_cache->content = entry; result_cache = evict_cache; if (list_item->prev != NULL) { list_item->prev->next = list_item->next; if (list_item->next != NULL) { list_item->next->prev = list_item->prev; } access_list[index]->prev = list_item; list_item->prev = NULL; list_item->next = access_list[index]; access_list[index] = list_item; } } switch (operation) { case 'R': total_reads++; hit ? reads_hits++ : reads_misses++; break; case 'W': result_cache->dirty = 1; total_writes++; hit ? write_hits++ : write_misses++; break; } } cdump(capacity, way, blocksize); sdump(total_reads, total_writes, write_backs, reads_hits, write_hits, reads_misses, write_misses); if (cache_dump_set) { xdump(set, way, cache); } for (i = 0; i < set; i++) { free(cache[i]); } free(cache); return 0; }
void SplitTree::printTechnique( const SplitTechniqueDesc& inTechniqueDesc, std::ostream& inStream ) { // TIM: sanity check: for( size_t i = 0; i < _dagOrderNodeList.size(); i++ ) assert( _dagOrderNodeList[i]->getDagOrderIndex() == i ); // dumpFile.open( "dump.txt" ); // preRdsMagic(); timeSplitCounter = 0; timePrintingCounter = 0; timeCompilingCounter = 0; unsigned long splitStart = getTime(); {for( NodeList::iterator i = _outputList.begin(); i != _outputList.end(); ++i ) { (*i)->_isFinalOutput = true; }} #ifdef SPLIT_SEARCH_EXHAUSTIVE exhaustiveSearch(); #else rdsSearch(); #endif unsigned long splitStop = getTime(); timeSplitCounter += splitStop - splitStart; // TIM: we need to split somewhere for( size_t i = 0; i < _outputList.size(); i++ ) { assert( _outputList[i]->_splitHere ); } // assign "registers" to all split nodes {for( NodeList::iterator i = _dagOrderNodeList.begin(); i != _dagOrderNodeList.end(); ++i ) { (*i)->setTemporaryID( 0 ); }} int outputID = 0; {for( NodeList::iterator i = _outputList.begin(); i != _outputList.end(); ++i ) { (*i)->setTemporaryID( _outputArgumentIndices[outputID++] ); }} int temporaryID = 1; {for( NodeList::iterator i = _dagOrderNodeList.begin(); i != _dagOrderNodeList.end(); ++i ) { if( (*i)->isMarkedAsSplit() && ((*i)->getTemporaryID() == 0) ) (*i)->setTemporaryID( -(temporaryID++) ); }} int temporaryCount = temporaryID-1; // now we go through the passes and print them? inStream << "\t.technique( gpu_technique_desc()" << std::endl; if( temporaryCount ) { inStream << "\t\t.temporaries(" << temporaryCount << ")" << std::endl; } unmark( SplitNode::kMarkBit_Printed ); std::cout << "time split " << timeSplitCounter << std::endl; std::cout << "time compile " << timeCompilingCounter << std::endl; std::cout << "time print " << timePrintingCounter << std::endl; std::ofstream cdump("configuration.dump"); dumpPassConfiguration(cdump ); for( PassSet::iterator p = _passes.begin(); p != _passes.end(); ++p ) rdsPrintPass( *p, inStream ); inStream << "\t)"; // dumpFile.close(); }