int main(int argc, char **argv) { int i = 0; int jobs = 0; pthread_t* thread = NULL; if(argc != 3) { fprintf(stderr, "Invalid usage.\nUsage: ./parmake -j# <make_file>\n"); return -1; } argv[1] += 2; /* Advance to integer */ threads = atoi(argv[1]); if(threads < 1) { fprintf(stderr, "Number of threads must be greater than 1.\n"); return -1; } pthread_mutex_init(&accessQueue, NULL); pthread_mutex_init(&accessProced, NULL); pthread_mutex_init(&killing, NULL); pthread_mutex_init(&waking, NULL); pthread_cond_init(&wakeupMain, NULL); pthread_cond_init(&killThreads, NULL); queue_init(&g_q); queue_init(&g_p); parser_parse_makefile(argv[2], parsed_command, parsed_new_key, parsed_dependency); //debug_view(); /* Temporary method to see how stuff is stored */ jobs = queue_size(&g_q); thread = (pthread_t*)malloc(threads*sizeof(pthread_t)); for(i = 0 ; i < threads; ++i) pthread_create(&thread[i], 0, processWork, (void*)&jobs); /* Wait for everything to signal back */ pthread_mutex_lock(&waking); while(sleeping != threads) pthread_cond_wait(&wakeupMain, &waking); pthread_mutex_unlock(&waking); pthread_mutex_lock(&killing); pthread_cond_broadcast(&killThreads); pthread_mutex_unlock(&killing); for(i = 0; i < threads; ++i) pthread_join(thread[i], (void*)0); /* All cleanup */ free(thread); cleanup_this(); pthread_mutex_destroy(&accessQueue); pthread_mutex_destroy(&accessProced); pthread_mutex_destroy(&killing); pthread_mutex_destroy(&waking); pthread_cond_destroy(&wakeupMain); pthread_cond_destroy(&killThreads); queue_destroy(&g_q); queue_destroy(&g_p); return 0; }
/** * Entry point to parmake. */ int main(int argc, char **argv) { pthread_cond_init(&cond, NULL); pthread_mutex_init(&mutex, NULL); queue_init(&allRules); queue_init(&rulesQueue); int arg; int numThreads= 1; //1 by default char * makeFile= NULL; char * make; char ** targets= malloc(sizeof(char *)); targets[0]= '\0'; while((arg=getopt(argc, argv, "j:f:"))!= -1){ if(arg == 'j'){ numThreads= atoi(optarg); } else if(arg == 'f') makeFile= optarg; } int size= argc - optind; if(optind < argc){ targets= realloc(targets, sizeof(char *) * (size + 1)); int i= 0; for( ; i < size; i++){ targets[i]= malloc(sizeof(char) * strlen(argv[optind]+1)); strcpy(targets[i], argv[optind]); optind++; } targets[i]= '\0'; } if(!makeFile){ if(access("./makefile", F_OK) == 0){ make= "makefile\0"; makeFile= make; } else if(access("./Makefile", F_OK) == 0){ make= "Makefile\0"; makeFile= make; } else return -1; } parser_parse_makefile(makeFile, targets, &new_target, &new_dependency, &new_command); /* int b= 0; for( ; b < queue_size(&rulesQueue); b++){ rule_struct * temp= queue_at(&rulesQueue, b); printf("%s ", temp->rule->target); }*/ pthread_t * threadsArray= malloc(sizeof(pthread_t) * numThreads); int i= 0; for( ; i < numThreads; i++) pthread_create(&threadsArray[i], NULL, start_routine, NULL); for(i= 0; i < numThreads; i++) pthread_join(threadsArray[i], NULL); pthread_mutex_destroy(&mutex); //Everything after this is for freeing free(threadsArray); rule_struct * currRule; char * currDep; char * currTar; int j, k; for(i= 0; i < queue_size(&allRules); i++){ currRule= queue_at(&allRules, i); for(j=0; j < queue_size(currRule->rule->deps); j++){ currDep= queue_at(currRule->rule->deps, j); free(currDep); //printf("freeing dep\n"); } for(k=0; k < queue_size(currRule->rule->commands); k++){ currTar= queue_at(currRule->rule->commands, k); free(currTar); //printf("freeing tar\n"); } queue_destroy(currRule->rule->deps); queue_destroy(currRule->rule->commands); free(currRule->rule->deps); free(currRule->rule->commands); free(currRule->rule->target); free(currRule->rule); free(currRule); } queue_destroy(&allRules); if(size != 0){ for(i=0; i < (size+1); i++) free(targets[i]); } free(targets); return 0; }
/** * Entry point to parmake. */ int main(int argc, char **argv) { int opt; int count = 0; char *fname = NULL; int nthreads = 1; char **targets = NULL; while ((opt = getopt(argc, argv, "f:j:")) != -1) { switch (opt) { case 'f': count++; fname = optarg; break; case 'j': count++; nthreads = atoi(optarg); break; } } if (fname == NULL) { //check if ./makefile exists if (access("./makefile", R_OK) == 0) { fname = "./makefile"; } else { //check if ./Makefile exists if (access("./Makefile", R_OK) == 0) { fname = "./Makefile"; } else { return -1; } } } else { //check if file exists if (access(fname, R_OK) == -1) { return -1; } } int tlength = argc - 2 * count; if (tlength > 1) { int temp = 1 + 2 * count; int i; targets = malloc(tlength * sizeof(char*)); for (i = 0; i < tlength-1; i++) { targets[i] = argv[temp + i]; } targets[i] = NULL; } //part 2 paser makefile all_rules = malloc(sizeof(queue_t)); all_targets = malloc(sizeof(queue_t)); queue_init(all_rules); queue_init(all_targets); parser_parse_makefile(fname, targets, parsed_new_targer, parsed_new_dependency, parsed_new_command); //part 3 run rules queue_t *ready_r = malloc(sizeof(queue_t)); queue_t *complete_t = malloc(sizeof(queue_t)); queue_init(ready_r); queue_init(complete_t); process_queues(all_rules, ready_r, complete_t); while (queue_size(ready_r) == 0) { process_queues(all_rules, ready_r, complete_t); } //part 4 parallel pthread_mutex_t m; pthread_mutex_init(&m, NULL); sem_t ready_sem; sem_init(&ready_sem, 0, queue_size(ready_r)); arg_t *run_args = malloc(sizeof(arg_t)); run_args->m = &m; run_args->ready_sem = &ready_sem; run_args->rest_r = all_rules; run_args->ready_r = ready_r; run_args->complete_t = complete_t; pthread_t threads[nthreads]; int i; for (i = 0; i < nthreads; i++) { pthread_create(&threads[i], NULL, run_thread, (void *)run_args); } for (i = 0; i < nthreads; i++) { pthread_join(threads[i], NULL); } //free memory while(queue_size(complete_t)) { char *target = queue_dequeue(complete_t); free(target); } queue_destroy(all_rules); queue_destroy(all_targets); queue_destroy(ready_r); queue_destroy(complete_t); free(targets); free(all_rules); free(all_targets); free(ready_r); free(complete_t); free(run_args); return 0; }
/** * Entry point to parmake. */ int main(int argc, char **argv) { int threads=1; //working threads, additional to main thread char *fname=0; //makefile name char temp=0; //used for whatever char **targets=NULL; //targets array int targetsGiven=0; //targets count queue_init(rules); //queue initialized queue_init(nextRule); //queue initialized queue_init(rulesDup); //queue initialized pthread_t *tid=NULL; //array of thread IDs int i; //loop iterator variable result_t *dummy=NULL; //dummy variable, just in case sem_init(&ruleAvailable, 0, 0); //semaphore initialized lock=PTHREAD_MUTEX_INITIALIZER; //mutex initialized /*threadAvailable*/ //semaphore initialized (later) //part1 while ((temp = getopt(argc, argv, "f:j:")) != -1) { if(temp=='f') { fname=optarg; } else if(temp=='j') { if(optarg!=0) threads=atoi(optarg); } else //Use of option other than f and j { return -1; //unspecified, so I just did same thing as no make file } //I hate having multiple returns, but its faster for now } if(fname==0) { if(access("./makefile", F_OK)==0) fname="./makefile"; else if(access("./Makefile", F_OK)==0) fname="./Makefile"; else return -1; //I hate having multiple returns, but its faster for now } targetsGiven=argc-optind; if(targetsGiven) { targets=malloc((targetsGiven+1)*sizeof(char*)); for(i=0; i<targetsGiven; i++) { targets[i]=argv[optind+i]; } targets[targetsGiven]=NULL; } //part 2 parser_parse_makefile(fname, targets, parsed_new_target, parsed_new_dependency, parsed_new_command); //part 3 and 4 tid=malloc(threads*sizeof(pthread_t)); sem_init(&threadAvailable, 0, threads); for(i=0; i<threads; i++) pthread_create(&tid[i], NULL, runRule, NULL); while(queue_size(rules)) { i=-1; int found=0; rule_t *temp=NULL; while(i<numRules && !found)//numRules is a formality, should always be found { i++; temp=queue_at(q, i); found=1; if(queue_size(temp->deps)!=0) { int j; int k; for(j=0; j<queue_size(rulesDup); j++) { for(k=0; k<queue_size(temp->deps); k++) { if(strcmp(queue_at(temp->deps, k), queue_at(rulesDup, j)->target)==0) { found=0; } } } } } sem_wait(&threadAvailable); pthread_mutex_lock(&lock); //CRITICAL SECTION queue_remove_at(rules, i); queue_enqueue(nextRule, temp); //END CRITICAL SECTION pthread_mutex_unlock(&lock); sem_post(&ruleAvailable); } //set up kickers for threads stuck in wait. Won't always be needed for(i=0; i<threads; i++) { pthread_mutex_lock(&lock); //CRITICAL SECTION queue_enqueue(nextRule, NULL); //END CRITICAL SECTION pthread_mutex_unlock(&lock); sem_post(&ruleAvailable);//waking up waiting threads to kick them } //wait for threads to finish for(i=0; i<threads; i++) { pthread_join(tid[i], (void**)&dummy); } while(queue_size(rulesDup)) { rule_t *temp=queue_dequeue(rulesDup); rule_destroy(temp); free(temp); } queue_destroy(rules); queue_destroy(nextRule); sem_destroy(&threadAvailable); sem_destroy(&ruleAvailable); pthread_mutex_destroy(&lock); if(targetsGiven) { free(targets); } free(tid); return 0; }
int main(int argc, char **argv) { remain_size =0; /** PART 1 STARTS **/ int opt; char *makefile= NULL; int num_threads=1; while ((opt = getopt(argc, argv, "f:j:")) != -1) { switch(opt){ case 'f' : makefile = optarg; break; case 'j' : num_threads = atoi( optarg ); break; default : return 0; } } int i ; int ind; int num = 0; char ** targets = malloc( (argc - optind +1 ) * sizeof( char* ) ); //not argc - optind + 1 if ( optind <= argc ){ for( i = 0,ind = optind ; i< argc -optind; i++ , ind++ ){ targets[i] = malloc( 100 ) ; strcpy ( targets[i] , argv[ind] ); num++; } targets[num] = NULL; } char * buffer = NULL; if( makefile == NULL ){ if (access("./makefile",F_OK) == 0 ){ strcpy(buffer, "./makefile"); makefile = buffer; } else if ( access("./Makefile",F_OK) == 0) { strcpy(buffer, "./Makefile"); makefile = buffer; } else return -1; } else{ if(access(makefile,F_OK) == -1) return -1; } /** PART 1 ENDS **/ /** PART 2 STARTS **/ queue_init(&q); parser_parse_makefile( makefile , targets , parsed_new_target, parsed_new_dependency, parsed_new_command ); /** PART 2 ENDS **/ /** PART 3 STARTS **/ /* int m,n; rule_t * hold3; char * hold4,hold5; printf("printing the queue of rules\n"); for(m=0;m<queue_size(&q);m++){ hold3 = queue_at (&q,m); printf("target %s : deps ",hold3->target); for(n=0;n<queue_size(hold3->deps);n++){ hold4 = queue_at(hold3->deps,n); printf ("%s ",hold4); } printf("commands "); for(n=0;n<queue_size(hold3->commands);n++){ hold4 = queue_at(hold3->commands,n); printf ("%s ",hold4); } printf("\n"); } exit(1);*/ queue_init(&has_ran); queue_init(&depend); add_deps(); int no_dep=0; for(i=0;i<queue_size(&q);i++) if(has_deps((rule_t*)queue_at(&q,i))==0) no_dep++; //printf("NUMBER of rules with no deps, initialy %d\n",no_dep); /** PARALELLIZATION **/ pthread_t* threads = malloc(sizeof(pthread_t)*num_threads); sem_init(&sem_mutex1, 0, no_dep); for(i=0;i<num_threads;i++) { pthread_create(&threads[i],NULL,start_run,NULL); } for(i=0;i<num_threads;i++) { pthread_join(threads[i],NULL); } sem_destroy(&sem_mutex1); /** FREEING STUFF **/ free(threads); // start_run(NULL); rule_t * rule_hold = NULL; int k; char * hold2 = NULL; for(i=0;i<queue_size(&q);i++){ rule_hold = queue_at(&q,i); for(k=0;k<queue_size(rule_hold->deps);k++) { hold2 = queue_at(rule_hold->deps,k); if(in_depend(hold2)==0) free(hold2); } for(k=0;k<queue_size(rule_hold->commands);k++) { hold2 = queue_at(rule_hold->commands,k); free(hold2); } free(rule_hold->target); rule_destroy(rule_hold); free(rule_hold) ; } queue_destroy(&q); for(i=0;i<queue_size(&depend);i++) { hold2 = queue_at(&depend,i); free(hold2); } queue_destroy(&depend); queue_destroy(&has_ran); for( i = 0; i< argc - optind; i++ ){ free(targets[i]); } free(targets); return 0; }