Code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#define NUM_THREADS 4
typedef struct
{
char idlength;
char colourmaptype;
char datatypecode;
short int colourmaporigin;
short int colourmaplength;
char colourmapdepth;
short int x_origin;
short int y_origin;
short width;
short height;
char bitsperpixel;
char imagedescriptor;
} HEADER;
typedef struct
{
unsigned char r;
unsigned char g;
unsigned char b;
} PIXEL;
void CreateHeader(HEADER, FILE *);
HEADER header;
FILE *fp, *fp2;
clock_t cl_diff[NUM_THREADS] = {0};
void *Gray(void *id)
{
clock_t cl_mid1, cl_mid2;
PIXEL pixel;
float gray;
int thread_id = *((int*)id);
int i;
printf("\n--START: THREAD %d--\n", thread_id);
int apo = thread_id * header.width * header.height / NUM_THREADS;
int ews = apo + header.width * header.height / NUM_THREADS;
for (i = apo; i < ews; i++)
{
pixel.b = fgetc(fp);
pixel.g = fgetc(fp);
pixel.r = fgetc(fp);
cl_mid1 = clock();
gray = 0.114 * pixel.b + 0.587 * pixel.g + 0.299 * pixel.r;
cl_mid2 = clock();
cl_diff[thread_id] += cl_mid2 - cl_mid1;
putc(gray,fp2);
putc(gray,fp2);
putc(gray,fp2);
}
printf("\n--END: THREAD %d--\n", thread_id);
}
main(int argc, char *argv[])
{
clock_t start = clock(), cl_totdiff;
int i, j;
char filename[25];
char graystr[] = "_gray.tga";
pthread_t thread[NUM_THREADS];
if (argc != 2)
{
printf("\nGive tga image - bye--\n");
exit(-1);
}
fp = fopen(argv[1],"r");
// Header filling
header.idlength = getc(fp);
header.colourmaptype = getc(fp);
header.datatypecode = getc(fp);
fread(&header.colourmaporigin,2,1,fp);
fread(&header.colourmaplength,2,1,fp);
header.colourmapdepth = fgetc(fp);
fread(&header.x_origin,2,1,fp);
fread(&header.y_origin,2,1,fp);
fread(&header.width,2,1,fp);
fread(&header.height,2,1,fp);
header.bitsperpixel = fgetc(fp);
header.imagedescriptor = fgetc(fp);
for (i = 0; argv[1][i] != '\0'; i++)
filename[i] = argv[1][i];
filename[i] = '\0';
for (j = 0; j < 10; j++)
filename[i-4+j] = graystr[j];
fp2 = fopen(filename,"w");
CreateHeader(header, fp2);
for (i = 0; i < NUM_THREADS; i++)
{
pthread_create(&thread[i], NULL, Gray, &i);
printf("\nthread:%d\n",i);
//pthread_join(thread[i], NULL);
}
for (i = 0; i < NUM_THREADS; i++)
pthread_join(thread[i], NULL);
printf("\n---GRAYSCALE PIC: SUCCESS---\n");
for (i = 0; i < NUM_THREADS; i++)
cl_totdiff += cl_diff[i];
printf("Time elapsed: %f sec\n", ((double)clock() - start) / CLOCKS_PER_SEC);
fclose(fp);
fclose(fp2);
}
void CreateHeader(HEADER header, FILE *ptr)
{
putc(0,ptr);
putc(0,ptr);
putc(2,ptr);
putc(0,ptr);
putc(0,ptr);
putc(0,ptr);
putc(0,ptr);
putc(0,ptr);
putc(0,ptr);
putc(0,ptr);
putc(0,ptr);
putc(0,ptr);
putc((header.width & 0x00FF),ptr);
putc((header.width & 0xFF00) / 256,ptr);
putc((header.height & 0x00FF),ptr);
putc((header.height & 0xFF00) / 256,ptr);
putc(24,ptr);
putc(0,ptr);
}
I know that my problem is around pthread_join(), but I can't solve it. If I use pthread_join() immediately after pthread_create() (not a parallel way of course, but to check), I can see the threads (thread numbers: 0, 1, 2, 3) create and end one after another normally, until the picture is completed.