Skip to content

Instantly share code, notes, and snippets.

@ikrabbe
Last active March 30, 2016 12:32
Show Gist options
  • Save ikrabbe/3202bf469669b0ad02fdb7b42a3ea90d to your computer and use it in GitHub Desktop.
Save ikrabbe/3202bf469669b0ad02fdb7b42a3ea90d to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
// select TEST 1 or 2. TEST=0 reads from stdin
#ifndef DO_TEST
#define DO_TEST 1
#endif
#if DO_TEST > 0
const char *test_input1[] = {
"2", // n
"1", "2", // A
"3", "4",
"1", "2", // B
"3", "4",
};
const char *test_input2[] = {
"2", // n
"1", "0", // A
"0", "1",
"1", "0", // B
"0", "1",
};
#define INP(F, D) do { sscanf(*line, F, D); line++; } while (0)
#else
#define INP(F, D) scanf(F, D)
#endif
// Program Structure
enum program_constants { max_dimension = 10 };
struct context {
int max;
int pfd[2]; // pipe
pid_t pid[max_dimension]; // subprocesses
int A[max_dimension][max_dimension];
int B[max_dimension][max_dimension];
int C[max_dimension][max_dimension];
};
static int init_context(struct context* C);
static int start_jobs(struct context* C);
static int read_result(struct context* C);
// Program main
int main(int argc, char* argv[])
{
struct context C;
int err;
if (0 != (err = init_context(&C))) {
return err;
} else if (0 != (err = start_jobs(&C))) {
return err;
} else if(0 != (err = read_result(&C))) {
return err;
} else {
return 0;
}
}
// Functions
int init_context(struct context* C)
{
int i,j;
#if DO_TEST == 1
const char** line = test_input1;
#elif DO_TEST == 2
const char** line = test_input2;
#endif
printf("Enter the size (%d)", getpid() );
INP("%d", &C->max);
if (0 < C->max && C->max < max_dimension) {
for(i = 0;i < C->max; i++)
{
printf("Enter row %d of your matrix A: ", i);
for(j=0;j<C->max;j++)
{
INP("%d",&C->A[i][j]);
}
}
// Get input for the first matrix
for(i = 0; i < C->max; i++)
{
printf("Enter row %d of your matrix B: ", i);
for(j=0;j<C->max;j++)
{
INP("%d",&C->B[i][j]);
}
}
// Get input for the second matrix
printf("\n");
return 0;
} else {
return -1; // dimension must be in [1,max_dimension[
}
}
int start_jobs(struct context* C)
{
int i;
int comm[2];
if(pipe(C->pfd)==-1)
{
fprintf(stderr,"Error\n");
exit(1);
}
for(i = 0; i < C->max; i++)
{
C->pid[i]=fork();
if((C->pid[i])==0)
{
int j, prod, c;
printf("CHLD %i %d\n", i, getpid());
close(C->pfd[0]);
for(j = 0; j < C->max; j++)
{
prod=0;
for(c = 0; c < C->max; c++)
{
//printf("A: %d, B: %d\n", C->A[i][c], C->B[c][j]);
prod += C->A[i][c]*C->B[c][j];
}
printf("A_%d_S * B_S_%d = %d\n", i, j,prod);
comm[0] = i; comm[1] = prod;
write(C->pfd[1], comm, sizeof comm);
}
exit(0);
} else if (C->pid[i] < 0) {
return -1; // a fork failed
}
}
return 0; // all processes started.
}
int read_result(struct context* C)
{
int i, j, _k, k[max_dimension], finalprod;
int status;
int comm[2];
memset(k, 0, sizeof k);
for(j = 0; j < C->max; j++)
{
if(C->pid[j] != 0)
{
for(_k = 0; _k < C->max; _k++)
{
read(C->pfd[0], comm, sizeof comm);
i = comm[0]; finalprod = comm[1];
C->C[k[i]][i] = finalprod;
printf("C[%d][%d] = %d\n", k[i], i, C->C[k[i]][i]);
++k[i];
}
}
}
for(j = 0; j < C->max; j++) {
waitpid(C->pid[j],&status,0);
}
return 0;
}
@ikrabbe
Copy link
Author

ikrabbe commented Mar 30, 2016

I used the INP define here to switch between test input and standard input.

@ikrabbe
Copy link
Author

ikrabbe commented Mar 30, 2016

Update with order of output.

@ikrabbe
Copy link
Author

ikrabbe commented Mar 30, 2016

we need to move the k index in a row ordered way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment