Shmget error for shared memory of a matrix

441 views Asked by At

Context of the code: Hello, I am trying to create a program that can multiply two 2x2 matrixes using separate processes (child1 and child2). Specifically child1 processes row1 of the resulting matrix and child2 processes row2 of the resulting matrix. This resulting matrix is stored in shared memory.

Problem: shmget() returns -1, and errno is 22 = invalid argument.

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/shm.h>
#include <stdbool.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

#include "shm_com.h"

//signal handler should be void of return type
void sig_handler(int signo){
    printf("Inside handler function\n");
}

int main(){
    int PROCESS_COUNT = 0;
    bool display = false;
    int row, column, limit=2;
    int M[2][2] = {     {20, 20},
                    {10, 6}};
    int N[2][2] = {     {10, 30},
                    {1, 3}};
    int Matrix_Size1=sizeof(M)/sizeof(int);
    int Matrix_Size2=sizeof(N)/sizeof(int);
    if(Matrix_Size1==Matrix_Size2) printf("Matrixes are the same size\n");
    

    int shmid;
    void *shared_memory = (void *)0;
    struct shared_use_st *shared_stuff;
    //shmid = shmget((key_t)9998, sizeof(struct shared_use_st), 0666 | IPC_CREAT);
    shmid = shmget((key_t)9998, sizeof(int * 3 * (2*2)), 0666 | IPC_CREAT);
    //Creation of Shared Memory
    if (shmid == -1) {
        printf("Oh dear, something went wrong with shmget()! %d\n", errno);
        exit(EXIT_FAILURE);
    }
    
    pid_t pid1,pid2;
    pid1 = fork();
    PROCESS_COUNT = 1;
    if(pid1!=0){
        pid2 = fork();
        PROCESS_COUNT = 2;
    }
    //Warning code after this point will be included into child unless in if statement

    if ((PROCESS_COUNT == 1 && pid1==0) || (PROCESS_COUNT == 2 && pid2 == 0)){
        /* child1 ------------------------------------------------------------*/
        if(PROCESS_COUNT == 1){
            printf("Child 1 Process: working with Q's 1 row\n");
            //sleep(10);
            //Get access to shared memory
            shared_memory = shmat(shmid, (void *)0, 0);
            if (shared_memory == (void *)-1) {
                fprintf(stderr, "shmat failed\n");
                exit(EXIT_FAILURE);
            }
            if(display){printf("Child Memory attached at %X\n", (int)shared_memory);}
            shared_stuff = (struct shared_use_st *)shared_memory;
            for(column=0; column<limit; column++){
                for (row=0; row<limit; row++){
                
                    shared_stuff->Q_matrix[0][column] += M[0][column]*N[row][column];
                    printf("check %d   ",shared_stuff->Q_matrix[0][column]);
                    //printf("check Row:%d,Column: %d   ",row,column);
                }
                if(display){printf("Row1_Q_matrix \n");}
                printf("\n");
                
            }
        //kill(pid1, SIGALRM);
        exit(1);
        }
        /*-------------------------------------------------------------------*/
        /* child2 */
        else if(PROCESS_COUNT == 2){
            printf("Child 2 Process: working with Q's 2 row\n");
            //Get access to shared memory
            shared_memory = shmat(shmid, (void *)0, 0);
            if (shared_memory == (void *)-1) {
                fprintf(stderr, "shmat failed\n");
                exit(EXIT_FAILURE);
            }
            if(display){printf("Child Memory attached at %X\n", (int)shared_memory);}
            shared_stuff = (struct shared_use_st *)shared_memory;
    
        }
    } else {
        /* parent ------------------------------------------------------------*/    
        if(display){printf("Parent pid: %i PROCESS_COUNT: %i \n  ", getpid(),PROCESS_COUNT);}

        //Get access to shared memory
        shared_memory = shmat(shmid, (void *)0, 0);
        if (shared_memory == (void *)-1) {
            fprintf(stderr, "shmat failed\n");
            exit(EXIT_FAILURE);
        }
        if(display){printf("Parent Memory attached at %X\n", (int)shared_memory);}
        shared_stuff = (struct shared_use_st *)shared_memory;

        //Write number to shared memory------------------------------------------------*/
        
        
        
        //Write and Display M matrix
        for (row=0; row<limit; row++)
        {
            for(column=0; column<limit; column++){
                shared_stuff->M_matrix[row][column] = M[row][column];
                if(display){printf("%d     ", (shared_stuff->M_matrix[row][column]));}
            }
            if(display){printf("M_matrix \n");}
            printf("\n");
            
        }
        //Write and Display N matrix
        for (row=0; row<limit; row++)
        {
            for(column=0; column<limit; column++){
                shared_stuff->N_matrix[row][column] = N[row][column];
                if(display){printf("%d     ", (shared_stuff->N_matrix[row][column]));}
            }
            if(display){printf("N_matrix \n");}
            printf("\n");
         }
        //Write and Display Q matric
        printf("Written Matrix\n");
        for (row=0; row<limit; row++)
        {
            for(column=0; column<limit; column++){
                shared_stuff->Q_matrix[row][column] = 0;
                printf("%d     mem:%p \n", (shared_stuff->Q_matrix[row][column]),& (shared_stuff->Q_matrix[row][column]));
            }
            if(display){printf("Q_matrix");}
            printf("\n");
         }
        wait(NULL);
        sleep(10);
        printf("Resulting Matrix2\n");
        printf("%d     Mem: %p \n", (shared_stuff->Q_matrix[0][0]),& shared_stuff->Q_matrix[0][0]);
        printf("%d     Mem:%p\n", (shared_stuff->Q_matrix[0][1]),& shared_stuff->Q_matrix[0][1]);
        printf("%d     Mem:%p\n", (shared_stuff->Q_matrix[1][0]),& shared_stuff->Q_matrix[1][0]);
        printf("%d     Mem:%p\n", (shared_stuff->Q_matrix[1][1]),& shared_stuff->Q_matrix[1][1]);
        /*for (row=0; row<limit; row++){
            for(column=0; column<limit; column++){
                printf("%d     mem:%p \n", (shared_stuff->Q_matrix[row][column]),& shared_stuff->Q_matrix[row][column]);
            }
            if(display){printf("Q_matrix");}
            printf("\n");
         }*/
    exit(EXIT_SUCCESS);
    printf("done\n");
    }
    
}

Here is my structure of shared memory:

#define TEXT_SZ 2048
struct shared_use_st {
    int M_matrix[2][2];
    int N_matrix[2][2];
    int Q_matrix[2][2];
};

Can someone explain what I am doing wrong with shmget()?

To note, I have commented out the first try of shmget().

1

There are 1 answers

0
Rachid K. On

Make some cleanup as you may have an existing segment for the given key but the size does not match. You may have increased the structure meanwhile. Do ipcrm -M 9998 before launching your program as the manual specifies that EINVAL is raised in the following conditions:

ERRORS
[...]
EINVAL A new segment was to be created and size is less than SHMMIN or greater than SHMMAX.
EINVAL A segment for the given key exists, but size is greater than the size of that segment.