Example #1
0
/* transform a list of values (with coordinates) into a list of blocks that are easily processed into BCSR */
static tmp_block_t * mm_to_blocks(int nz, unsigned *I, unsigned *J, float *val, unsigned c, unsigned r)
{
	int elem;

	/* at first, the list of block is empty */
	tmp_block_t *block_list = NULL;

	for (elem = 0; elem < nz; elem++)
	{
		insert_elem(&block_list, I[elem], J[elem], val[elem], c, r);
	}

	return block_list;
}
Example #2
0
void *productor(void *params) {
	prod_param *parg = (prod_param *) params;
	int err;
	
	//3 cas : on est un blur, on est avant un blur ou bien le cas normal. Si on est avant un blur, il faut lancer la copie de l'image quand, dans mat_blur, on a, pour l'image, le nombre de paquet
	//en lesquels elle a été divisée. Pour cela, il faut un tableau global npackim[NIMAGE] qui donne, pr chaque image, en combien de paquet elle a été divisée ou bien, on divise chaque image en
	//NPACK/NIMAGE de paquet (on divise chacune des images avec le ppcm du nombre de thread), ce qui fait qu'on a le nombre de paquet dans une image avec le nombre de paquet total
	//ces 3 cas sont dans le while
	while(1) {

		err = pthread_mutex_lock(&(to_pass_mutex[parg->num_filter]));
		if (err!=0)
			error(err,"pthread_mutex_lock pour to_pass_mutex dans producteur");
		if(to_pass[parg->num_filter]>=NPACK){
			err = pthread_mutex_unlock(&(to_pass_mutex[parg->num_filter]));
			if (err!=0)
				error(err,"pthread_mutex_unlock pour to_pass_mutex dans producteur");
			pthread_exit(NULL);
		}
		to_pass[parg->num_filter]++;
		err = pthread_mutex_unlock(&(to_pass_mutex[parg->num_filter]));
		if (err!=0)
			error(err,"pthread_mutex_unlock pour to_pass_mutex dans producteur");

		printf(".");
		fflush(stdout);
		//cas du filtre blur
		if((parg->isblur)!=0) {
			
			//1e étape : vérifer qu'il y a un des éléments de matblur en la ligne isblur-1
			//printf("Je suis dans le cas blur\n");
			//err = pthread_mutex_lock(&(check_for_c_mutex[(parg->isblur)-1])); //deux threads ne peuvent rechercher un c en même temps sinon ils copieront la même image

			err = sem_wait(&(can_copi[(parg->isblur)-1])); 
			if (err!=0)
				error(err,"sem_wait sur can_copi dans productor");

			err = pthread_mutex_lock(&(can_i_take_c_mutex[(parg->isblur)-1]));//ce lock est nécessaire car la sémaphore ne fait des wait que pour empêcher des thread d'entrer quand il n'y a pas d'image prête pour la copie. Mais la sémaphore  peut être incrémentée par le fait que deux images différentes peuvent être prête presque en même temps pour la copie. Alors, il faut faire un lock sur le can_i_take_c_mutex pour éviter qu'il n'y ait deux threads qui entrent en même temps dans le check_lmat_blur, ce qui poserait des problème vu qu'une des threads pourraient lire dans can_i_take_c pendant que l'autre écrit dedans.
			if (err!=0)
				error(err,"pthread_mutex_lock pour can_i_take_c_mutex dans producteur du cas blur");

			int c = check_lmat_blur((parg->isblur)-1);
			if(c==-1) {
				error(-1,"check_lmat_blur a renvoyé -1");
			}
			
			if (can_i_take_c[(parg->isblur)-1][c] < NPACK/NIMAGE) {
				err = sem_post(&(can_copi[(parg->isblur)-1])); 
				if (err!=0)
					error(err,"sem_post sur can_copi dans productor");
			}
			
			err = pthread_mutex_unlock(&(can_i_take_c_mutex[(parg->isblur)-1]));
			if (err!=0)
				error(err,"pthread_mutex_unlock pour can_i_take_c_mutex dans producteur du cas blur");

			//	error(err,"pthread_mutex_unlock pour check_for_c_mutex dans producteur du cas blur");

			//2e étape : on a une image dont le précédent a été appliquer sur toutes les parties. On la copie

			err = pthread_mutex_lock(&(copi_is_done_mutex[(parg->isblur)-1][c]));
			if (err!=0)
				error(err,"pthread_mutex_lock pour copi_is_done_mutex dans producteur du cas blur pour image_copi");

			if(copi_is_done[(parg->isblur)-1][c]==0) {

				err = image_copi(c,parg->num_filter); //on donne le numéro correspondant à l'image et le numéro de la ligne dans le mat_buf où les parties de cette image se trouve. Il faut mettre à jour les éléments read-only des pointeur vers des elem_buf dans cette ligne (note, il est nécessaire d'avoir une structure copie par image mais pas plus ! Car quand on fait une 2e copie pour un 2e blur, alors on peut écraser l'ancienne copie !)
				if (err!=0) {
					error(err,"Erreur de image_copi");
				}
				copi_is_done[(parg->isblur)-1][c]++;				
			}
			err = pthread_mutex_unlock(&(copi_is_done_mutex[(parg->isblur)-1][c]));
			if (err!=0)
				error(err,"pthread_mutex_unlock pour copi_is_done_mutex dans producteur du cas blur pour image_copi");

			//3e étape : on a fait les copies. Mnt, on doit appeler le consommateur en lui-disant de consommer un elem-buffer mais dont l'image est c
			elem_buf *paquet = consommator(parg->num_filter,c);//mettre c en 2e argument permet de dire que tous les elem_buf sont bons, quelque soit l'image
			apply_filter(paquet,parg->num_filter);
			
			err = sem_wait(&(empty[(parg->num_filter)+1])); //amélioration possible du code : ce sem_wait ne sert pas vraiment, vu que on sait de toute façon que les buffer ne vont pas être rempli
			if (err!=0)
				error(err,"sem_wait sur empty dans productor");
			
			err = pthread_mutex_lock(&(buf_mutex[(parg->num_filter)+1]));
			if (err!=0)
				error(err,"pthread_mutex_lock pour buf_mutex dans producteur");
			
			insert_elem(&paquet,(parg->num_filter)+1);
			
			err = pthread_mutex_lock(&(choosen_c_mutex[(parg->isblur)-1][c]));
			if (err!=0)
				error(err,"pthread_mutex_lock pour choosen_c_mutex dans producteur, check_lmat_blur");

			choosen_c[(parg->isblur)-1][c]++;

			if((choosen_c[(parg->isblur)-1][c]==NPACK/NIMAGE)) {
				err = image_copi_destroy(c,parg->num_filter+1);

				if (err!=0)
					error(err,"Erreur de image_copi_destroy");
			}

			err = pthread_mutex_unlock(&(choosen_c_mutex[(parg->isblur)-1][c]));
			if (err!=0)
				error(err,"pthread_mutex_unlock pour choosen_c_mutex dans producteur");
			
			err = pthread_mutex_unlock(&(buf_mutex[(parg->num_filter)+1]));
			if (err!=0)
				error(err,"pthread_mutex_unlock pour buf_mutex dans producteur");
			
			err = sem_post(&(full[(parg->num_filter)+1])); //amélioration possible du code : ce sem_wait ne sert pas vraiment, vu que on sait de toute façon que les buffer ne vont pas être rempli
			if (err!=0)
				error(err,"sem_post sur full dans productor");
			
			//on est avant un filtre blur
			if((parg->beforeblur)!=0) {//parg_beforeblur contient 1 si c'est le premier blur, 2 si c'est le deuxième, ...

				err = pthread_mutex_lock(&(blur_mutex[(parg->beforeblur)-1][(paquet)->num_img]));
				if (err!=0)
					error(err,"pthread_mutex_lock pour blur_mutex dans producteur");
				
				(mat_blur[(parg->beforeblur)-1][(paquet)->num_img])++;

				if ((mat_blur[(parg->beforeblur)-1][(paquet)->num_img])==NPACK/NIMAGE) {
					err = sem_post(&(can_copi[(parg->beforeblur)-1])); 
					if (err!=0)
						error(err,"sem_post sur can_copi dans productor, before_blur");
				}
				
				err = pthread_mutex_unlock(&(blur_mutex[(parg->beforeblur)-1][(paquet)->num_img]));
				if (err!=0)
					error(err,"pthread_mutex_unlock pour blur_mutex dans producteur");
			}
			
		} else {
		//cas normal

			elem_buf *paquet = consommator(parg->num_filter,-1);//mettre -1 en 2e argument permet de dire que tous les elem_buf sont bons, quelque soit l'image
			apply_filter(paquet,parg->num_filter);
			err = sem_wait(&(empty[(parg->num_filter)+1])); //amélioration possible du code : ce sem_wait ne sert pas vraiment, vu que on sait de toute façon que les buffer ne vont pas être rempli
			if (err!=0)
				error(err,"sem_wait sur empty dans productor");
			err = pthread_mutex_lock(&(buf_mutex[(parg->num_filter)+1]));
			if (err!=0)
				error(err,"pthread_mutex_lock pour buf_mutex dans producteur");
			insert_elem(&paquet,(parg->num_filter)+1);
			err = pthread_mutex_unlock(&(buf_mutex[(parg->num_filter)+1]));
			if (err!=0)
				error(err,"pthread_mutex_unlock pour buf_mutex dans producteur");
			
			err = sem_post(&(full[(parg->num_filter)+1])); //amélioration possible du code : ce sem_wait ne sert pas vraiment, vu que on sait de toute façon que les buffer ne vont pas être rempli
			if (err!=0)
				error(err,"sem_post sur full dans productor");
			
			//on est avant un filtre blur
			if((parg->beforeblur)!=0) {//parg_beforeblur contient 1 si c'est le premier blur, 2 si c'est le deuxième, ...

				err = pthread_mutex_lock(&(blur_mutex[(parg->beforeblur)-1][(paquet)->num_img]));
				if (err!=0)
					error(err,"pthread_mutex_lock pour blur_mutex dans producteur");
				
				(mat_blur[(parg->beforeblur)-1][(paquet)->num_img])++;

				if ((mat_blur[(parg->beforeblur)-1][(paquet)->num_img])==NPACK/NIMAGE) {
					err = sem_post(&(can_copi[(parg->beforeblur)-1])); 
					if (err!=0)
						error(err,"sem_post sur can_copi dans productor, before_blur");
				}

				err = pthread_mutex_unlock(&(blur_mutex[(parg->beforeblur)-1][(paquet)->num_img]));
				if (err!=0)
					error(err,"pthread_mutex_unlock pour blur_mutex dans producteur");
			}
		}
	}
}