Advertisement
Guest User

neverMind

a guest
Nov 20th, 2010
148
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.45 KB | None | 0 0
  1.  
  2. //###################################### INVERTER.C (main) #########################################
  3. #include <semaphore.h>
  4. #include <sys/types.h>
  5. #include <sys/ipc.h>
  6. #include <sys/shm.h>
  7. #include <sys/wait.h>
  8. #include <sys/time.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <time.h>
  13. #include <math.h>
  14. #include <errno.h>
  15. #include <unistd.h>
  16.  
  17. //#include "timeprofiler.h"
  18. #include "ppmtools.h"
  19.  
  20. //Global vars:
  21. int shmids[4], shmPixelId, *total_lines, *processed_lines, *next_line, *buf_vars;
  22. //To share unnamed semaphores between processes, they must be allocated in a shared memory.
  23. mem_struct *sh_mm;
  24. //unnamed semaphores
  25. sem_t *mutex1, *mutex2, *mutex3, *sem_remaining_lines;
  26. //struct that will hold the image in shared memory
  27. image_struct *image;
  28. pid_t *workersPID;
  29. header *h;
  30.  
  31. int main(int argc, char *argv[]) {
  32.     int i, j, k, cur = 0, id;
  33.     pixel *row;
  34.     double start, stop, startms, stopms;
  35.  
  36.     if (argc < 3) {
  37.         printf("Incorrect usage.\nPlease use \"./invert input_filename.ppm output_filename.ppm\"\n");
  38.         return -1;
  39.     }
  40.  
  41.     printf("Opening input file [%s]\n", argv[1]);
  42.     FILE *fpin = fopen(argv[1], "r");
  43.     if (fpin == NULL) {
  44.         printf("Could not open input file\n");
  45.         return -1;
  46.     }
  47.  
  48.     printf("Opening output file [%s]\n", argv[2]);
  49.     FILE *fpout = fopen(argv[2], "w");
  50.     if (fpout == NULL) {
  51.         printf("Could not open output file\n");
  52.         return -1;
  53.     }
  54.  
  55.     printf("Getting header\n");
  56.     h = getImageHeader(fpin);
  57.     if (h == NULL) {
  58.         printf("Error getting header from file\n");
  59.         return -1;
  60.     }
  61.     printf("Got file Header: %s - %u x %u - %u\n", h->type, h->width, h->height, h->depth);
  62.  
  63.     printf("Saving header to output file\n");
  64.     if (writeImageHeader(h, fpout) == -1) {
  65.         printf("Could not write to output file\n");
  66.         return -1;
  67.     }
  68.  
  69.     init();
  70.     printf("After init...\n");
  71.     //alloc mem space for one row (width * size of one pixel struct)
  72.     row = (pixel *) malloc(h->width * sizeof (pixel));
  73.  
  74.     printf("Starting work\n");
  75.     for (i = 0; i < h->height; i++) {
  76.         printf("Reading row... \n");
  77.         if (getImageRow(h->width, row, fpin) == -1) {
  78.             printf("Error while reading row\n");
  79.         }
  80.         printf("Got row %d || \n", (i + 1));
  81.         for (j = cur, k = 0; j < cur + h->width; j++, k++) {
  82.             image->pixel_data[j].red = row[k].red;
  83.             image->pixel_data[j].blue = row[k].blue;
  84.             image->pixel_data[j].green = row[k].green;
  85.         }
  86.         cur += h->width;
  87.     }    
  88.     sem_wait(mutex1);
  89.     *total_lines = h->height;
  90.     sem_post(mutex1);
  91.  
  92.     /*Creates workers*/
  93.     workersPID = (pid_t*) malloc(sizeof (pid_t) *((NUM_WORKERS)));
  94.     for (i = 0; i < NUM_WORKERS; i++) {
  95.         id = fork();
  96.         if (id == -1) {
  97.             printf("Error creating worker no %d\n", i);
  98.             return (EXIT_FAILURE);
  99.         } else if (id == 0) {
  100.             workersPID[i] = getpid();
  101.             worker();
  102.         }
  103.     }
  104.     cur = 0;
  105.     sem_wait(mutex2);
  106.    
  107.     /*Writes the invert image on the output file*/
  108.     for (i = 0; i < h->height; i++) {
  109.         for (j = cur, k = 0; j < cur + h->width; j++, k++) {
  110.             row[k].red = image->pixel_data[j].red;
  111.             row[k].blue = image->pixel_data[j].blue;
  112.             row[k].green = image->pixel_data[j].green;
  113.         }
  114.         cur += h->width;
  115.         printf("Saving row... \n");
  116.         if (writeRow(h->width, row, fpout) == -1) {
  117.             printf("Error while writing row\n");
  118.         }
  119.         printf("Done\n");
  120.     }
  121.  
  122.     printf("Cleaning up...\n");
  123.     //clean up row
  124.     free(row);
  125.     //clean up header
  126.     free(h);
  127.  
  128.     printf("Closing file pointers.\n");
  129.     fclose(fpin);
  130.     fclose(fpout);
  131.  
  132.     for (i = 0; i < NUM_WORKERS; i++) {
  133.         if (workersPID[i]) {
  134.             kill(workersPID[i], SIGKILL); //TODO: sigkill ou sigterm?
  135.             waitpid(workersPID[i], NULL, 0);
  136.         }
  137.     }
  138.     terminate();
  139.  
  140.     exit(0);
  141. }
  142.  
  143. void init() {
  144.  
  145.     if ((shmids[3] = shmget(IPC_PRIVATE, sizeof (mem_struct), IPC_CREAT | 0700)) == -1) {
  146.         printf("shmget to allocate mem_Struct for semaphores failed. Errno returned %s\n", strerror(errno));
  147.         exit(EXIT_FAILURE);
  148.     }
  149.     sh_mm = (mem_struct*) shmat(shmids[3], NULL, 0);
  150.     if(sem_init(&sh_mm->mutex1, 1, 1)== -1){
  151.         printf("Error initializing semaphore mutex1.Errno returned: %s\n",strerror(errno));
  152.         exit(EXIT_FAILURE);
  153.     }
  154.     mutex1 = &sh_mm->mutex1;
  155.  
  156.     if(sem_init(&sh_mm->mutex2, 1, 0)== -1){
  157.         printf("Error initializing semaphore mutex2.Errno returned: %s\n",strerror(errno));
  158.         exit(EXIT_FAILURE);
  159.     }
  160.     mutex2 = &sh_mm->mutex2;
  161.  
  162.     if(sem_init(&sh_mm->mutex3, 1, 1)== -1){
  163.         printf("Error initializing semaphore mutex3.Errno returned: %s\n",strerror(errno));
  164.         exit(EXIT_FAILURE);
  165.     }
  166.     mutex3 = &sh_mm->mutex3;
  167.  
  168.     if(sem_init(&sh_mm->sem_remaining_lines, 1, h->height)== -1){
  169.         printf("Error initializing semaphore sem_remaining_lines.Errno returned: %s\n",strerror(errno));
  170.         exit(EXIT_FAILURE);
  171.     }
  172.     sem_remaining_lines = &sh_mm->sem_remaining_lines;
  173.     //create shared memory to hold the source image:
  174.     if ((shmids[0] = shmget(IPC_PRIVATE, sizeof (image_struct), IPC_CREAT | 0700)) == -1) {
  175.         printf("shmget to allocate image struct failed. Errno returned:  %s\n", strerror(errno));
  176.         exit(EXIT_FAILURE);
  177.     }
  178.     image = (image_struct*) shmat(shmids[0], NULL, 0);
  179.  
  180.     //shared memory to allocate the pointer to pointer pixel_data
  181.     if ((shmids[1] = shmget(IPC_PRIVATE, h->width * h->height * sizeof (pixel), IPC_CREAT | 0700)) == -1) {
  182.         printf("shmget to allocate pixel_data array failed. Errno returned: %s\n", strerror(errno));
  183.         exit(EXIT_FAILURE);
  184.     }
  185.     image->pixel_data = (pixel*) shmat(shmids[1], NULL, 0);
  186.  
  187.     /*Shared Memory segment for 3 integers*/
  188.     if ((shmids[2] = shmget(IPC_PRIVATE, 3 * sizeof (int), IPC_CREAT | 0700)) == -1) {
  189.         printf("shmget to allocate the 3 integers failed. Errno returned;  %s\n", strerror(errno));
  190.         exit(EXIT_FAILURE);
  191.     }
  192.     buf_vars = (int*) shmat(shmids[2], NULL, 0);
  193.     total_lines = &buf_vars[0];
  194.     processed_lines = &buf_vars[1];
  195.     next_line = &buf_vars[2];
  196.  
  197.     *total_lines = *processed_lines = *next_line = 0;  
  198. }
  199.  
  200. /*Worker process*/
  201. void worker() {
  202.     int i,k, cur = 0;
  203.     pixel *row;
  204.     //Block all signals, except SIGINT and SIGKILL which are handled
  205.     sigset_t block_ctrlc;
  206.     sigfillset(&block_ctrlc);
  207.     sigdelset(&block_ctrlc, SIGINT);
  208.     sigdelset(&block_ctrlc, SIGKILL);
  209.     sigprocmask(SIG_BLOCK, &block_ctrlc, NULL);
  210.     signal(SIGINT, handle_signal);
  211.     signal(SIGKILL, handle_signal);
  212.     while (sem_trywait(sem_remaining_lines)!=-1){ //if there are still lines to read, go on
  213.         sem_wait(mutex3);
  214.         cur = *next_line; //current image's line
  215.         *next_line += h->width; //refreshs line for the next worker
  216.         sem_post(mutex3);
  217.         row = (pixel *) malloc(h->width * sizeof (pixel));
  218.         for (i = cur, k = 0; i < cur + h->width; i++, k++) {
  219.             row[k].red = image->pixel_data[i].red;
  220.             row[k].blue = image->pixel_data[i].blue;
  221.             row[k].green = image->pixel_data[i].green;
  222.         }
  223.         printf("Inverting row... \n");
  224.         invertRow(h->width, row); //inverte
  225.         printf("Done || \n");
  226.         for (i = cur, k = 0; i < cur + h->width; i++, k++) {
  227.             image->pixel_data[i].red = row[k].red;
  228.             image->pixel_data[i].blue = row[k].blue;
  229.             image->pixel_data[i].green = row[k].green;
  230.         }
  231.         sem_wait(mutex1);
  232.         *processed_lines += 1; //increases the number of inverted lines
  233.         if (*processed_lines == *total_lines) { //check if it reaches last line
  234.             sem_post(mutex2); //if so, wakes the master telling that is ready
  235.         }
  236.         sem_post(mutex1);
  237.     }
  238. }
  239.  
  240. void handle_signal(int signum) {
  241.     if (signum == SIGINT)
  242.         signal(SIGINT, handle_signal);
  243.     else
  244.         signal(SIGKILL, handle_signal);
  245.     exit(0);
  246. }
  247.  
  248. void terminate() {
  249.     int i;
  250.     //close semaphores
  251.     sem_destroy(mutex1);
  252.     sem_destroy(mutex2);
  253.     sem_destroy(mutex3);
  254.     sem_destroy(sem_remaining_lines);
  255.  
  256.     //cleans up shared memory = removes shared memory segments
  257.     for (i = 0; i < 4; i++) {
  258.         shmctl(shmids[i], IPC_RMID, NULL);
  259.     }
  260.  
  261. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement