Пример #1
0
void *run_thread(void *args)
{
	arg_t *run_args = (arg_t *)args;
	
	while(1)
	{
		if (queue_size(run_args->ready_r) == 0 && 
			queue_size(run_args->rest_r) == 0)
		{
			return NULL;	
		}
		sem_wait(run_args->ready_sem);
		while(queue_size(run_args->ready_r) == 0)
		{
			if (queue_size(run_args->ready_r) == 0 && 
				queue_size(run_args->rest_r) == 0)
			{
				sem_post(run_args->ready_sem);
				return NULL;	
			}
			sem_wait(run_args->ready_sem);
		}
		rule_t *rule;
		pthread_mutex_lock(run_args->m);
		rule = queue_dequeue(run_args->ready_r);
		pthread_mutex_unlock(run_args->m);

		while(queue_size(rule->commands))
		{
			char *command = queue_dequeue(rule->commands);
			if (system(command) != 0)
			{
				exit(1);	
			}
			free(command);
		}

		char *temp = rule->target;
		while(queue_size(rule->deps))
		{
			char *dep = queue_dequeue(rule->deps);
			free(dep);
		}
		rule_destroy(rule);
		free(rule);
		
		pthread_mutex_lock(run_args->m);
		int pSize = queue_size(run_args->ready_r);
		queue_enqueue(run_args->complete_t, temp);
		process_queues(run_args->rest_r, run_args->ready_r, run_args->complete_t);
		int cSize = queue_size(run_args->ready_r);
		pthread_mutex_unlock(run_args->m);
		int i;
		for(i = 0; i < cSize - pSize; i++)
		{
			sem_post(run_args->ready_sem);
		}
		sem_post(run_args->ready_sem);
	}
}
Пример #2
0
/**
 * Connects queue_iterate interface to free with rule_destroy call.
 *
 * @param arg Address to be freed.
 * @param trash do NOT use.
 * @return Void.
 */
static void rule_free_adapter(void *arg, void *trash){
	rule_t *rule = arg;
	queue_iterate(rule->deps, free_adapter, 0);
	queue_iterate(rule->commands, free_adapter, 0);
	
	free(rule->target);

	rule_destroy(arg);
	free(arg);
}
Пример #3
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;
}
Пример #4
0
void process_queues(queue_t *rest_r, queue_t *ready_r, queue_t *complete_t)
{
	int i = 0;
	while(i < queue_size(rest_r))
	{
		int satify = 1;
		int dependR = 0; 
		rule_t *rule = queue_at(rest_r, i);
		int j;
		
		for (j = 0; j < queue_size(rule->deps); j++)
		{
			char *dep = queue_at(rule->deps, j);

			int complete = 0;
			if (isRule(dep))
			{
				int k;
				for (k = 0; k < queue_size(complete_t); k++)
				{
					char *target = queue_at(complete_t, k);
					if (strcmp(dep, target) == 0)
					{
						dependR = 1;
						complete = 1;
						break;
					}
				}
			}
			else
			{
				if (access(dep, R_OK) == 0)
				{
					complete = 1;		
				}
				else 
				{
					fprintf(stderr,"dependency file does not exist!");
					exit(1);	
				}
			}

			if (!complete)
			{
				satify = 0;	
				break;
			}
			
		}
		
		if (satify)
		{
			if (dependR)
			{
				queue_enqueue(ready_r, rule);	
				queue_remove_at(rest_r, i);
			}
			else 
			{
				if (access(rule->target, R_OK) == -1)
				{
					queue_enqueue(ready_r, rule);	
					queue_remove_at(rest_r, i);
				}
				else 
				{
					struct stat statbuf;
					stat(rule->target, &statbuf);
					time_t rule_time = statbuf.st_mtime; 	
					
					int run = 0;
					int j;
					for (j = 0; j < queue_size(rule->deps); j++)
					{
						char *dep = queue_at(rule->deps, j);
						stat(dep, &statbuf);
						time_t dep_time = statbuf.st_mtime;
						if (dep_time > rule_time)
						{
							run = 1;
							queue_enqueue(ready_r, rule);	
							queue_remove_at(rest_r, i);
							break;
						}
					}
					
					if (!run)
					{
						queue_remove_at(rest_r, i);
						queue_enqueue(complete_t, rule->target);
						
						while(queue_size(rule->deps))
						{
							char *dep = queue_dequeue(rule->deps);
							free(dep);
						}
						while(queue_size(rule->commands))
						{
							char *command = queue_dequeue(rule->commands);
							free(command);
						}
						rule_destroy(rule);
						free(rule);
					}
				}
			}
		}
		else
		{
			i++;	
		}
	}
}
Пример #5
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;  
}