//thread calculator void createCalc(argsOfThreadClac *args) { int routersCount = args->dvCount;//for checking that all routers send and gets their DV printf("Wait while calculate own DV\nIt may take a few seconds...\n"); while(1) { pthread_mutex_lock(&mutexLock); pthread_cond_wait(&calcCond, &mutexLock);//wait until reciever wakes me up int i,j,tmpIndex = 0, k; //check if dv did not changed - got '0' from all int finish = 1; for (i = 0; i < args->neighbors; ++i) { if(args->neighborsDv[i][0] != 0) finish = 0; } dvIsChaneged = 0; if(finish == 1)//if got '0' from all - calc finish { calc = 1; for(i = 0; i < args->neighbors; ++i) { pthread_cond_signal(&senderCond);//waking up senders } pthread_mutex_unlock(&mutexLock); //prints the DV table and exit printDV(args->name, args->routerDV, args->pi, args->dvCount, args->routers); pthread_exit(NULL); } else { //Relax for (i = 0; i < args->dvCount; ++i) { if(i != args->index) { for (j = 0; j < args->neighbors; ++j) { //finds neighbor index for (k = 1; k < args->dvCount + 1; ++k) { if(args->neighborsDv[j][k] == 0) { tmpIndex = k; break; } } if(args->routerDV[i] > args->neighborsDv[j][i+1] + args->routerDV[tmpIndex-1]) { args->routerDV[i] = args->neighborsDv[j][i+1] + args->routerDV[tmpIndex-1]; args->pi[i] = tmpIndex-1;//who found me dvIsChaneged = 1;//tells that DV is changed routersCount = args->dvCount; } } } } //check if all calculations are done if(dvIsChaneged == 0) { routersCount--; if(routersCount > 0) dvIsChaneged = 1; } for(i = 0; i < args->neighbors; ++i) { pthread_cond_signal(&senderCond);//waking up senders } pthread_mutex_unlock(&mutexLock); } } }
int main(int argc, char* argv[]) { FILE *fp; Graph *graph = NULL; int V = 0,E = 0; int lines = 0; char ch[256]; char temp; char* buf; int i, j, index; //Variables for reading file char* line = NULL; size_t len = 0; ssize_t read; char* inputRouter = argv[2]; if(argc != 4) { printf("Error, there are missing arguments or to much arguments.\n"); printf("You should enter the command in the following format: ./<Executable name> <File name> <source vertex> <num of connect loops>\n"); return 0; } else { fp = fopen(argv[1],"r"); // read mode //If the file does not open properly if( fp == NULL ) { perror("Error while opening the file.\n"); exit(EXIT_FAILURE); } } //Initializes the number of vertices in the graph if(fgets(ch,sizeof(ch),fp) != NULL) V = atoi(ch); //Counts the number of lines in the file while ((temp = fgetc(fp)) != EOF) { if (temp == '\n') lines++; } E = (lines - V) * 2;//Initialize num og edges fseek(fp,2L,SEEK_SET);//Go to beginning of file //Create Graph graph = createGraph(V, E); if(graph == NULL) { printf("Something went wrong - Graph is NULL\n"); exit(EXIT_FAILURE); } //Read file, intialized data structure for (i = 0; i < V; ++i) { //Allocated memory for DV if((graph->routers[i].DV = malloc(sizeof(int) * V)) == NULL) exit(EXIT_FAILURE); for (j = 0; j < V; ++j) { graph->routers[i].DV[j] = INT_MAX; } //Allocated memory for pi if((graph->routers[i].pi = malloc(sizeof(int) * V)) == NULL) exit(EXIT_FAILURE); for (j = 0; j < V; ++j) { graph->routers[i].pi[j] = -1; } graph->routers[i].neighbors = 0;//initialize num of neighbors if((read = getline(&line,&len,fp)) != -1) { buf = strtok(line," "); graph->routers[i].routerName = malloc(strlen(buf) + 1); strcpy(graph->routers[i].routerName,buf); buf = strtok(NULL," "); graph->routers[i].ip = malloc(strlen(buf) + 1); strcpy(graph->routers[i].ip,buf); buf = strtok(NULL," "); graph->routers[i].port = atoi(buf); } } //Read from file and initialize data i = 0; while((read = getline(&line,&len,fp)) != -1) { buf = strtok(line," "); graph->edges[i].src = malloc(strlen(buf) + 1); graph->edges[i+1].dest = malloc(strlen(buf) + 1); strcpy(graph->edges[i].src, buf); strcpy(graph->edges[i+1].dest, buf); buf = strtok(NULL," "); graph->edges[i].dest = malloc(strlen(buf) + 1); graph->edges[i+1].src = malloc(strlen(buf) + 1); strcpy(graph->edges[i].dest, buf); strcpy(graph->edges[i+1].src, buf); buf = strtok(NULL," "); graph->edges[i].weight = atoi(buf); graph->edges[i+1].weight = atoi(buf); i = i+2; } //Initialize DV and pi for(i = 0; i < V; i++) { for(j = 0; j < E; ++j) { if(strcmp(graph->edges[j].src, graph->routers[i].routerName) == 0) { index = findIndex(graph, graph->edges[j].dest);//Find index in routeres graph->routers[i].DV[index] = graph->edges[j].weight;//intialize DV graph->routers[i].pi[index] = i;//initialize pi graph->routers[i].neighbors++; } } graph->routers[i].DV[i] = 0;//my dist to my self graph->routers[i].pi[i] = -2;//if found my self } index = findIndex(graph,inputRouter); //index of the router name argument //if no connection if(graph->routers[index].neighbors == 0) { printDV(graph->routers[index].routerName, graph->routers[index].DV, graph->routers[index].pi,graph->V, graph->routers); if(line) free(line); freeGraph(graph); fclose(fp); return 0; } //Initialize neighbors array graph->routers[index].myNeighbors = malloc(sizeof(char*)*graph->routers[index].neighbors); for (i = 0 ; i < graph->routers[index].neighbors ; ++i) graph->routers[index].myNeighbors[i] = NULL; //add neighbors to neighbors-list for (i = 0 ; i < graph->E ; ++i) { if (strcmp(inputRouter,graph->edges[i].src) == 0) { addToNeiArray(graph->edges[i].dest, &graph->routers[index]); } } int** neighborsDv; //Allocating for neighborsDv neighborsDv = malloc(sizeof(int*) * graph->routers[index].neighbors); for (i = 0; i < graph->routers[index].neighbors; ++i) { neighborsDv[i] = malloc(sizeof(int)*(graph->V + 1)); for (j = 0; j < graph->V + 1; ++j) { neighborsDv[i][j] = -1; } } //==========Creates Threads========== pthread_mutex_init(&mutexLock, NULL); pthread_t* threadsS = malloc(sizeof(pthread_t) * graph->V); pthread_t* threadsR = malloc(sizeof(pthread_t) * graph->V); pthread_t calculator; argsOfThreadSender* argsS = malloc(sizeof(argsOfThreadSender) * graph->V); argsOfThreadRecieve* argsR = malloc(sizeof(argsOfThreadRecieve) * graph->V); argsOfThreadClac argsC; for (i = 0; i < graph->V; ++i) { if(graph->routers[index].pi[i] == index) { //SENDER argsS[i].port = graph->routers[i].port; argsS[i].name = graph->routers[index].routerName; argsS[i].dvCount = graph->V; argsS[i].conLoop = atoi(argv[3]); argsS[i].ip = graph->routers[index].ip; argsS[i].routerDV = graph->routers[index].DV; argsS[i].neighbors = graph->routers[index].neighbors; argsS[i].neighborsDv = neighborsDv; pthread_create(&threadsS[i],NULL,(void *)&createSender, &argsS[i]); //RECIEVER argsR[i].port = graph->routers[index].port; argsR[i].name = graph->routers[i].routerName; argsR[i].dvCount = graph->V; argsR[i].neighbors = graph->routers[index].neighbors; argsR[i].ip = graph->routers[index].ip; argsR[i].mySelf = &graph->routers[index]; argsR[i].neighborsDv = neighborsDv; pthread_create(&threadsR[i],NULL,(void *)&createReciever, &argsR[i]); } } //CALCULATOR argsC.routers = graph->routers; argsC.dvCount = graph->V; argsC.routerDV = graph->routers[index].DV; argsC.index = index; argsC.neighbors = graph->routers[index].neighbors; argsC.pi = graph->routers[index].pi; argsC.name = graph->routers[index].routerName; argsC.neighborsDv = neighborsDv; pthread_create(&calculator, NULL, (void *)&createCalc, &argsC); //Join threads for (i = 0; i < graph->V; ++i) { if(graph->routers[index].pi[i] == index) { pthread_join(threadsS[i], NULL); pthread_join(threadsR[i], NULL); } } pthread_join(calculator, NULL); pthread_mutex_destroy(&mutexLock); //=========== Free allocated memory ========== fclose(fp); freeGlobalDv(neighborsDv, graph->routers[index].neighbors); if(line) free(line); for (i = 0; i < graph->routers[index].neighbors; ++i) { free(graph->routers[index].myNeighbors[i]); } free(graph->routers[index].myNeighbors); freeThreads(threadsR, threadsS, argsS, argsR); freeGraph(graph); return 0; }
void router::run() { printf("From %s: router::run called.\n",_name); pa3Map::iterator nt_it; unsigned long nbrIPprf; _dv_table.insert(pa3Map::value_type(toPrefix(_myIP), 0)); for (nt_it = _nbr_table.begin(); nt_it != _nbr_table.end(); nt_it++) { nbrIPprf = toPrefix((*nt_it).first); /* if ((nbrIP.S_un.S_addr>>8) != (_myIP.S_un.S_addr>>8))// from other AS? { // nbrIP.S_un.S_addr != 0x80000000; this may not work } */ _dv_table.insert(pa3Map::value_type(nbrIPprf, (*nt_it).second)); _fwd_table.insert(IFWMap::value_type(nbrIPprf, (*nt_it).first)); } printf("initial DV.."); printDV(); printFT("run"); propaganda_DV(); bool bRun = true; while (bRun) { size_t sz = _pcomm->readMsg(_inbuf, BUFF_SIZE); if (sz == 0) propaganda_DV(); else { switch (_inbuf[0]) { case MSGTYPE_HMSG: forwrdMsg(&_inbuf[1], sz); break; case MSGTYPE_RDV: updateDV(&_inbuf[1], (sz-1)); break; case MSGTYPE_CCHNG: changeCost(&_inbuf[1], (sz-1)); break; case MSGTYPE_CDN: downLink(&_inbuf[1], (sz-1)); break; case MSGTYPE_CASDN: ASdownLink(&_inbuf[1], (sz-1)); break; case MSGTYPE_CASUP: ASupink(&_inbuf[1], (sz-1)); break; case MSGTYPE_CPRNT: printFT("MSGTYPE_CPRNT"); break; case MSGTYPE_CQUIT: bRun = false; break; case MSGTYPE_CPRNT_DV: printDV(); break; case MSGTYPE_CPRNT_NT: printNT(); break; default: printf("From %s: unknown message type %d. The message is dropped.\n",_name,_inbuf[0]); } } } }