Esempio n. 1
0
static void* thread_loop(void *arg) {
    threadpool_t *pool = (threadpool_t*)arg;
    task_t *t = NULL;
    struct timespec ts;
    struct timeval  tv;
    int ret;
    int tosignal;

    while (!pool->exit) {
        Pthread_mutex_lock(&pool->mutex);
        gettimeofday(&tv, NULL);
        ts.tv_sec = tv.tv_sec + POOL_MAX_IDLE;
        ts.tv_nsec = tv.tv_usec * 1000;

        while (pool->task_queue.len == 0) {
            ret = Pthread_cond_timedwait(&pool->cond, &pool->mutex, &ts);
            if (ret == 0) {
                if (pool->exit) {
                    goto EXIT;
                }
                break;
            } else if (ret == ETIMEDOUT) {
                goto EXIT;
            }
        }

        --pool->threads_idle;
        t = heap_remove(&pool->task_queue, 0);
        tosignal = (pool->task_queue.len == 0) ? 1 : 0;
        Pthread_mutex_unlock(&pool->mutex);

        if (tosignal) {
            Pthread_cond_broadcast(&pool->task_over_cond);
        }

        if (t) {
            t->func(t->arg);
            free(t);
        }

        Pthread_mutex_lock(&pool->mutex);
        ++pool->threads_idle;
        Pthread_mutex_unlock(&pool->mutex);
    }

    Pthread_mutex_lock(&pool->mutex);
EXIT:
    --pool->threads_idle;
    tosignal = --pool->threads_num ? 0 : 1;
    Pthread_mutex_unlock(&pool->mutex);
    if (tosignal) {
        Pthread_cond_broadcast(&pool->exit_cond);
    }
    return NULL;
}
Esempio n. 2
0
void *
Consumer(void *v)
{
	struct thread_data *data = (struct thread_data *)v;
	unsigned sum = 0;
	int n, item;
	int waits = 0;
	int l = maxbuflen - 1;
	
	for (n = 0; ; ++n) {
		Pthread_mutex_lock(&buf_mutex);
		while (buflen == 0) {
			if (eof) {
				Pthread_mutex_unlock(&buf_mutex);
				goto done;
			}
			++waits;
			Pthread_cond_wait(&empty_cond, &buf_mutex);
		}
		item = buf[--buflen];
		if (buflen == l)
			Pthread_cond_broadcast(&full_cond);
		Pthread_mutex_unlock(&buf_mutex);

		ConsumeItem(item, &sum);
	}

done:
	data->sum = sum;
	printf("Consumer %d exit, %d items received, %d waits\n", 
		data->no, n, waits);
	return data;
}
Esempio n. 3
0
int threadpool_add_task(threadpool_t *pool, 
        void (*func)(void*), void *arg, int priority) {
    int tosignal = 0;
    task_t *tq = (task_t *)calloc(1, sizeof(*tq));
    if (!tq) {
        return -1;
    }

    tq->func = func;
    tq->arg = arg;
    tq->priority = priority;

    Pthread_mutex_lock(&pool->mutex);
    if (pool->threads_idle == 0 && pool->threads_num < pool->threads_max) {
        threadpool_thread_create(pool);
        ++pool->threads_idle;
        ++pool->threads_num;
    }
    tosignal = (pool->task_queue.len == 0)  ? 1 : 0;
    if (heap_insert(&pool->task_queue, tq) != 0) {
        free(tq);
        Pthread_mutex_unlock(&pool->mutex);
        return -1;
    }
    Pthread_mutex_unlock(&pool->mutex);
    if (tosignal) {
        Pthread_cond_broadcast(&pool->cond);
    }
    return 0;
}
Esempio n. 4
0
void *
Producer(void *v)
{
	struct thread_data *data = (struct thread_data *)v;
	unsigned seed = data->seed;
	int n;
	unsigned item, sum;
	int waits = 0;

	data->sum = 0;
	for (n = 0; n < num_items; ++n) {
		pthread_testcancel();

		sum = 0;
		item = ProduceItem(&seed, &sum);
	
		pthread_cleanup_push(pthread_mutex_unlock, &buf_mutex);

		Pthread_mutex_lock(&buf_mutex);
		while (buflen == maxbuflen) {
			++waits;
			Pthread_cond_wait(&full_cond, &buf_mutex);
		}
		buf[buflen++] = item;
		data->sum += sum;
		if (buflen == 1)
			Pthread_cond_broadcast(&empty_cond);

		pthread_cleanup_pop(1);
	}

	printf("Producer %d exit, %d waits\n", data->no, waits);
	return data;
}
Esempio n. 5
0
void *
Producer(void *v)
{
	struct producer *p = (struct producer *)v;
	struct consumer *c;
	struct packet *pa, *old;
	unsigned seed = p->seed;
	int n, k, cons;
	unsigned sum = 0;
	int waits = 0;
	int more = 1;
	int item_cnt = 0;

	cons = seed % num_consumers;
	for (n = 0; more; ++n) {

		/* Hole Packet aus lokaler emptyPacketQueue */
		Pthread_mutex_lock(&p->queue_mutex);
		while (!p->emptyPacketQueue) {
			++waits;
			Pthread_cond_wait(&p->empty_cond, &p->queue_mutex);
		}
		pa = p->emptyPacketQueue;
		p->emptyPacketQueue = pa->next;
		Pthread_mutex_unlock(&p->queue_mutex);

		/* Fuelle Packet */
		for (k = 0; k < buflen; ++k) {
			pa->buf[k] = ProduceItem(&seed, &sum);
			if (++item_cnt == num_items) {
				more = 0;
				++k;
				break;
			}
		}
		pa->len = k;

		/* Versende Packet an Consumer cons */
		c = consumers + cons;
		Pthread_mutex_lock(&c->queue_mutex);
		old = pa->next = c->fullPacketQueue;
		c->fullPacketQueue = pa;
		Pthread_mutex_unlock(&c->queue_mutex);
		if (!old)
			Pthread_cond_broadcast(&c->empty_cond);

		if (++cons == num_consumers)
			cons = 0;
	}

	p->sum = sum;
	printf("Producer %d exit, %d waits, %d packets\n", p->no, waits, n);
	return NULL;
}
Esempio n. 6
0
void *
Consumer(void *v)
{
	struct consumer *c = (struct consumer *)v;
	struct producer *p;
	struct packet *pa, *old;
	unsigned sum = 0;
	int n, k;
	int waits = 0;
	int item_cnt = 0;
	
	for (n = 0; ; ++n) {
		/* Hole Packet aus lokaler fullPacketQueue */
		Pthread_mutex_lock(&c->queue_mutex);
		while (!c->fullPacketQueue) {
			if (c->eof) {
				Pthread_mutex_unlock(&c->queue_mutex);
				goto done;
			}
			++waits;
			Pthread_cond_wait(&c->empty_cond, &c->queue_mutex);
		}
		pa = c->fullPacketQueue;
		c->fullPacketQueue = pa->next;
		Pthread_mutex_unlock(&c->queue_mutex);

		/* Verarbeite Packet */
		for (k = 0; k < pa->len; ++k)
			ConsumeItem(pa->buf[k], &sum);
		item_cnt += pa->len;
		
		/* Stelle Packet zurueck in emptyPacketQueue des Owners */
		p = producers + pa->owner;
		Pthread_mutex_lock(&p->queue_mutex);
		old = pa->next = p->emptyPacketQueue;
		p->emptyPacketQueue = pa;
		Pthread_mutex_unlock(&p->queue_mutex);
		if (!old)
			Pthread_cond_broadcast(&p->empty_cond);
	}

done:
	c->sum = sum;
	printf("Consumer %d exit, %d items in %d packets received, %d waits\n", 
		c->no, item_cnt, n, waits);
	return NULL;
}
Esempio n. 7
0
void threadpool_exit(threadpool_t *pool) {
    Pthread_mutex_lock(&pool->mutex);
    pool->exit = 1;
    Pthread_mutex_unlock(&pool->mutex);
    Pthread_cond_broadcast(&pool->cond);
}
Esempio n. 8
0
	void wakeup() {
		Pthread_cond_broadcast(&c);
	}
Esempio n. 9
0
int
main(int argc, char **argv)
{
	int n, e;
	unsigned prod_sum, cons_sum;
	struct thread_data *data;
	pthread_attr_t attr;
	int canceled = 0;
	pthread_t tid;

 	if (argc > 1 && !strcmp("-", argv[1]))
 		Error("usage: %s num_producers num_consumers "
			"num_items maxbuflen busy-loops", argv[0]);

	if (argc > 1) {
		num_producers = atoi(argv[1]);
		if (num_producers < 0)
			num_producers = 1;
		if (num_producers > MAXPRODUCERS)
			num_producers = MAXPRODUCERS;
	}
	if (argc > 2) {
		num_consumers = atoi(argv[2]);
		if (num_consumers < 0)
			num_consumers = 1;
		if (num_consumers > MAXCONSUMERS)
			num_consumers = MAXCONSUMERS;
	}
	if (argc > 3) {
		num_items = atoi(argv[3]);
		if (num_items < 0)
			num_items = 0;
	}
	if (argc > 4) {
		maxbuflen = atoi(argv[4]);
		if (maxbuflen < 0)
			maxbuflen = 1;
		if (maxbuflen > MAXBUFLEN)
			maxbuflen = MAXBUFLEN;
	}
	if (argc > 5)
		busy_loops = atoi(argv[5]);
	printf("num_producers %d num_consumers %d num_items %d "
		"maxbuflen %d busy-loops %d\n",
		num_producers, num_consumers, num_items, maxbuflen, busy_loops);
	num_items /= num_producers; /* items/producer */

	sigemptyset(&sigmask);
	sigaddset(&sigmask, SIGINT);
	Pthread_sigmask(SIG_BLOCK, &sigmask, NULL);

	Pthread_attr_init(&attr);
	Pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);

	/* Starte die Producer */
	for (n = 0; n < num_producers; ++n) {
		data = malloc(sizeof(struct thread_data));
		if (!data)
			Error("malloc");
		data->seed = n;
		data->no = n;
		producer_data[n] = data;
     		Pthread_create(&producers[n], &attr, Producer, data);
	}

	/* Starte die Consumer */
	for (n = 0; n < num_consumers; ++n) {
		data = malloc(sizeof(struct thread_data));
		if (!data)
			Error("malloc");
		data->no = n;
     		Pthread_create(&consumers[n], &attr, Consumer, data);
	}

     	Pthread_create(&tid, &attr, SigThread, NULL);

	/* Warte auf alle Producer */
	prod_sum = 0;
	for (n = 0; n < num_producers; ++n) {
		Pthread_join(producers[n], (void **)&data);
		if (data == PTHREAD_CANCELED)
			canceled = 1;

		prod_sum += producer_data[n]->sum;
	}
	if (canceled)
		printf("*** program was cancelled\n");

	/* setze eof und wecke consumer auf */
	Pthread_mutex_lock(&buf_mutex);
	eof = 1;
	Pthread_mutex_unlock(&buf_mutex);
	Pthread_cond_broadcast(&empty_cond);

	/* Warte auf alle Consumer */
	cons_sum = 0;
	for (n = 0; n < num_consumers; ++n) {
		Pthread_join(consumers[n], (void **)&data);

		cons_sum += data->sum;
	}

	printf("prot_sum %u cons_sum %u\n", prod_sum, cons_sum);
	if (cons_sum != prod_sum)
		printf("ERROR\n");

	return 0;
}
Esempio n. 10
0
void* work_loop(void* args){

    worker_p mine = (worker_p)args;
    crew_p crew = mine->crew;
    struct stat file_stat;
    struct dirent *entry;
    work_p  work;
    entry = (struct dirent*)malloc(sizeof(struct dirent)+name_max);
    Pthread_mutex_lock(&crew->mutex);
    while(crew->work_cnt==0){
        Pthread_cond_wait(&crew->go,&crew->mutex);
    }
    Pthread_mutex_unlock(&crew->mutex);
    while(1){
        Pthread_mutex_lock(&crew->mutex);
        while(crew->first_work==NULL)
            Pthread_cond_wait(&crew->go,&crew->mutex);
        printf("woker %d works on :#%lx ,conunt is %d\n", mine->index,crew->first_work,crew->work_cnt);
        work = crew->first_work;
        crew->first_work = work->next;
        if(crew->first_work==NULL)
            crew->last_work = NULL;
        printf("woker %d took #%lx ,leaave first is #%lx last is #%lx\n", mine->index,work,crew->first_work,crew->last_work);
        Pthread_mutex_unlock(&crew->mutex);

        if(lstat(work->path,&file_stat)<0){
            printf("%s error: %s\n",work->path,strerror(errno));
        }
        if(S_ISLNK(file_stat.st_mode)){
            printf("%s is a link\n", work->path);
        }
        else if (S_ISDIR(file_stat.st_mode)){
            DIR* directory = opendir(work->path);
            struct dirent* result;
            if(directory==NULL){
                fprintf(stderr, "open %s errro:%s\n", work->path,strerror(errno));
                continue;
            }
            while(1){
                int status = readdir_r(directory,entry,&result);
                if(status!=0){
                    fprintf(stderr, "unable to open %s,error:%s\n", work->path,strerror(status));
                    break;
                }
                if(result==NULL)
                    break;
                if(strcmp(entry->d_name,".")==0||strcmp(entry->d_name,"..")==0)
                    continue;
                work_p new_work= (work_p)malloc(sizeof(work_t));
                new_work->string = work->string;
                new_work->path = (char*) malloc(path_max);
                strcpy(new_work->path,work->path);
                strcat(new_work->path,"/");
                strcat(new_work->path,entry->d_name);
                new_work->next= NULL;
                Pthread_mutex_lock(&crew->mutex);
                if(crew->first_work==NULL){
                    crew->first_work=new_work;
                    crew->last_work = new_work;
                }else{
                    crew->last_work->next = new_work;
                    crew->last_work = new_work;
                }
                crew->work_cnt++;
                Pthread_cond_signal(&crew->go);
                Pthread_mutex_unlock(&crew->mutex);
            }
            closedir(directory);
        }
        else if (S_ISREG(file_stat.st_mode)){
            FILE* file;
            char buf[MAXLINE],*fbuf;
            if((file = fopen(work->path,"r"))==NULL){
                fprintf(stderr, "can not open %s:%s\n", work->path,strerror(errno));
                continue;
            }
            else{
                while(1){
                   if((fbuf= fgets(buf,MAXLINE,file))==NULL){
                        if(feof(file))
                            break;
                        else if(ferror(file)){
                            fprintf(stderr, "read %s error:%s\n", work->path,strerror(errno));
                            break;
                        }
                   }
                   if(strstr(buf,work->string)!=NULL){
                        printf("found %s in %s\n",work->string,work->path);
                        break;
                   }
                }
                fclose(file);

            }
        }
        else{
            fprintf(stderr, "%s's type is %s\n", work->path,S_ISFIFO(file_stat.st_mode)?"FIFO":
                                                            S_ISCHR(file_stat.st_mode)?"CHAR":
                                                            S_ISBLK(file_stat.st_mode)?"BLK":
                                                            S_ISSOCK(file_stat.st_mode)?"SOCK":"unknown");

        }
        free(work->path);
        free(work);
        Pthread_mutex_lock(&crew->mutex);
        crew->work_cnt--;
        if(crew->work_cnt<=0){
            Pthread_cond_broadcast(&crew->done);
            Pthread_mutex_unlock(&crew->mutex);
            break;
        }
        Pthread_mutex_unlock(&crew->mutex);

    }
    free(entry);
    return NULL;
}
Esempio n. 11
0
int
main(int argc, char **argv)
{
	int n, k, e;
	unsigned prod_sum, cons_sum;
	pthread_attr_t attr;
	struct packet *p;
	int packets_per_producer;

 	if (argc > 1 && !strcmp("-", argv[1]))
 		Error("usage: %s num_producers num_consumers "
			"num_items buflen busy-loops", argv[0]);

	if (argc > 1) {
		num_producers = atoi(argv[1]);
		if (num_producers < 0)
			num_producers = 1;
		if (num_producers > MAXPRODUCERS)
			num_producers = MAXPRODUCERS;
	}
	if (argc > 2) {
		num_consumers = atoi(argv[2]);
		if (num_consumers < 0)
			num_consumers = 1;
		if (num_consumers > MAXCONSUMERS)
			num_consumers = MAXCONSUMERS;
	}
	if (argc > 3) {
		num_items = atoi(argv[3]);
		if (num_items < 0)
			num_items = 0;
	}
	if (argc > 4) {
		buflen = atoi(argv[4]);
		if (buflen < 1)
			buflen = 1;
	}
	if (argc > 5)
		busy_loops = atoi(argv[5]);
	printf("num_producers %d num_consumers %d num_items %d "
		"buflen %d busy-loops %d\n",
		num_producers, num_consumers, num_items, buflen, busy_loops);
	num_items /= num_producers; /* items/producer */

	Pthread_attr_init(&attr);

	Pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);

	/* Producer Datenstruktur */
	packets_per_producer = (num_producers + num_consumers) * 2;
	for (n = 0; n < num_producers; ++n) {
		Pthread_mutex_init(&producers[n].queue_mutex, NULL);
		Pthread_cond_init(&producers[n].empty_cond, NULL);
		producers[n].seed = n;
		producers[n].no = n;
		producers[n].emptyPacketQueue = NULL;
		for (k = 0; k < packets_per_producer; ++k) {
			p = malloc(sizeof(struct packet) + 
				(buflen - 1) * sizeof(unsigned));
			if (!p)
				Error("malloc");

			p->owner = n;
			p->next = producers[n].emptyPacketQueue;
			producers[n].emptyPacketQueue = p;
		}
	}

	/* Consumer Datenstruktur */
	for (n = 0; n < num_consumers; ++n) {
		Pthread_mutex_init(&consumers[n].queue_mutex, NULL);
		Pthread_cond_init(&consumers[n].empty_cond, NULL);
		consumers[n].no = n;
		consumers[n].eof = 0;
		consumers[n].fullPacketQueue = NULL;
	}

	/* Starte die Producer */
	for (n = 0; n < num_producers; ++n)
     		Pthread_create(&producers[n].tid, &attr, 
						Producer, &producers[n]);

	/* Starte die Consumer */
	for (n = 0; n < num_consumers; ++n)
     		Pthread_create(&consumers[n].tid, &attr, 
						Consumer, &consumers[n]);

	/* Warte auf alle Producer */
	prod_sum = 0;
	for (n = 0; n < num_producers; ++n) {
		Pthread_join(producers[n].tid, NULL);

		prod_sum += producers[n].sum;
	}

	/* setze eof und wecke consumer auf */
	for (n = 0; n < num_consumers; ++n) {
		Pthread_mutex_lock(&consumers[n].queue_mutex);
		consumers[n].eof = 1;
		Pthread_mutex_unlock(&consumers[n].queue_mutex);
		Pthread_cond_broadcast(&consumers[n].empty_cond);
	}

	/* Warte auf alle Consumer */
	cons_sum = 0;
	for (n = 0; n < num_consumers; ++n) {
		Pthread_join(consumers[n].tid, NULL);

		cons_sum += consumers[n].sum;
	}

	printf("prot_sum %u cons_sum %u\n", prod_sum, cons_sum);
	if (cons_sum != prod_sum)
		printf("ERROR\n");

	return 0;
}