Saturday, June 23, 2012

SIGPWR

Its been quite a long time since i came out here. Yeah i've been busy with some other work and couldn't really focus on posting anything here.

But i am here aren't I and yeah ive got something new.

Its about linux system calls and signal handling. This simple piece of code was originally a part of a assignment that i was supposed to do.

Basically what it does it prompts the user to create a file by entering a filename at the beginning. And then the the program goes about finding the sum of 1 to 1000. Yes this doesn't take up much time but ive slowed it down using the sleep command. And this program will ensure that whenever the program receives a SIGPWR interrupt the program will write the the proceeds of the summation to the above created file.

To make stuff more interesting here the summation is handled by 10 threads running simultaneously. Each thread sums up 100 mumbers and finally those subtotals are added up to form the final answer.

Interesting enough?

here's the code for the magic.


#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <signal.h>

#define ARRAYSIZE 1000
#define THREADS 10

void *slave(void *myid);

/* shared data */
int data[ARRAYSIZE]; /* Array of numbers to sum */
int sum = 0;
pthread_mutex_t mutex; /* mutually exclusive lock variable */
int wsize;          /* size of work for each thread */ 
int low0,low1,low2,low3,low4,low5,low6,low7,low8,low9;
int i0,i1,i2,i3,i4,i5,i6,i7,i8,i9;
int myresult=0,myresult0=0,myresult1=0,myresult2=0,myresult3=0,myresult4=0,myresult5=0,myresult6=0,myresult7=0,myresult8=0,myresult9=0;
FILE *file;
char fname[100];
/* end of shared data */

void *slave(void *myid){

  int high;
switch((int)myid){
    case 0 :
      low0 = (int) myid * wsize;
      high = low0 + wsize;
      for (i0=low0;i0<high;i0++){
        myresult0 += data[i0];
            sleep(2);}
        myresult=myresult0;
        break;
    case 1 :
      low1 = (int) myid * wsize;
      high = low1 + wsize;
      for (i1=low1;i1<high;i1++){
        myresult1 += data[i1];
            sleep(2);}
        myresult=myresult1;
        break;
    case 2 :
      low2 = (int) myid * wsize;
      high = low2 + wsize;
      for (i2=low2;i2<high;i2++){
        myresult2 += data[i2];
            sleep(2);}   
        myresult=myresult2;   
        break;
    case 3 :
      low3 = (int) myid * wsize;
      high = low3 + wsize;
      for (i3=low3;i3<high;i3++){
        myresult3 += data[i3];
            sleep(2);}
        myresult=myresult3;
        break;
    case 4 :
      low4 = (int) myid * wsize;
      high = low4 + wsize;
      for (i4=low4;i4<high;i4++){
        myresult4 += data[i4];
            sleep(2);}
        myresult=myresult4;
        break;
    case 5 :
      low5 = (int) myid * wsize;
      high = low5 + wsize;
      for (i5=low5;i5<high;i5++){
        myresult5 += data[i5];
            sleep(2);}
        myresult=myresult5;
        break;
    case 6 :
      low6 = (int) myid * wsize;
      high = low6 + wsize;
      for (i6=low6;i6<high;i6++){
        myresult6 += data[i6];
            sleep(2);}
        myresult=myresult6;
        break;
    case 7 :
      low7 = (int) myid * wsize;
      high = low7 + wsize;
      for (i7=low7;i7<high;i7++){
        myresult7 += data[i7];
            sleep(2);}
        myresult=myresult7;
        break;
    case 8 :
      low8 = (int) myid * wsize;
      high = low8 + wsize;
      for (i8=low8;i8<high;i8++){
        myresult8 += data[i8];
            sleep(2);}
        myresult=myresult8;
        break;
    case 9 :
      low9 = (int) myid * wsize;
      high = low9 + wsize;
      for (i9=low9;i9<high;i9++){
        myresult9 += data[i9];
            sleep(2);}
        myresult=myresult9;
        break;
}

  /*printf("I am thread:%d low=%d high=%d myresult=%d \n",(int)myid, low,high,myresult);*/

  pthread_mutex_lock(&mutex);
  sum += myresult;  /* add partial sum to local sum */
    pthread_mutex_unlock(&mutex);
  return;
}

void write(){
    printf(" ***Interrupt system call received. \n Will write computational data into %s\n",fname);
    fprintf(file,"The sum from %d to %d is %d\n",low0,i0,myresult0);
    fprintf(file,"The sum from %d to %d is %d\n",low1,i1,myresult1);
    fprintf(file,"The sum from %d to %d is %d\n",low2,i2,myresult2);
    fprintf(file,"The sum from %d to %d is %d\n",low3,i3,myresult3);
    fprintf(file,"The sum from %d to %d is %d\n",low4,i4,myresult4);
    fprintf(file,"The sum from %d to %d is %d\n",low5,i5,myresult5);
    fprintf(file,"The sum from %d to %d is %d\n",low6,i6,myresult6);
    fprintf(file,"The sum from %d to %d is %d\n",low7,i7,myresult7);
    fprintf(file,"The sum from %d to %d is %d\n",low8,i8,myresult8);
    fprintf(file,"The sum from %d to %d is %d\n",low9,i9,myresult9);
 /*writes*/
  fclose(file); /*finished writing*/
   
}

main(){

  int i;
  pthread_t tid[THREADS];

  pthread_mutex_init(&mutex,NULL); /* initialize mutex */

  wsize = ARRAYSIZE/THREADS;       /* wsize must be an integer */

  for (i=0;i<ARRAYSIZE;i++)        /* initialize data[] */
    data[i] = i+1;

  /* Create file */
 
  printf(" Enter file name here : ");
  fgets(fname, sizeof fname, stdin);
  file = fopen(fname,"w+"); /* apend file (add text to a file or create a file if it does not exist.*/

    pid_t main = getpid();
    printf(" The process id of the main process is %d \n",main);

    signal(SIGPWR,write);

  for (i=0;i<THREADS;i++) /* create threads */
    if (pthread_create(&tid[i],NULL,slave,(void *)i) != 0)
      perror("Pthread_create fails");

  for (i=0;i<THREADS;i++) /* join threads */
    if (pthread_join(tid[i],NULL) != 0)
      perror("Pthread_join fails");

  printf(" The sum from 1 to %i is %d\n",ARRAYSIZE,sum);
}



As you can see theres no magic involved. Its just simple threads and signal handling.

Enjoy !!!

No comments:

Post a Comment