1

I have multiple processes operating on the same data. I want to keep the data inside shared memory. Problem is it seems I can't save into it (or retrieve).

My whole code for it is here: https://github.com/kasperekt/LLGame/blob/master/server_src/game_state.c#L74

but it seems that the problem is inside these functions:

typedef struct game_state {
  int resources;
  int wins;
  army_t *army;
} game_state_t;

...

static game_state_t *players[2] = { NULL, NULL };
static game_state_t **mem_state = NULL;

...

void attach_state() {
  mem_state = get_memory_data(0);
  players[0] = mem_state[0];
  players[1] = mem_state[1];
}

void save_state() {
  if (mem_state == NULL) {
    mem_state = get_memory_data(0);
  }

  mem_state[0] = players[0];
  mem_state[1] = players[1];
  detach_memory_data(mem_state);
}

And example function which works on this data:

void increment_resources(int player_id) {
  attach_state();
  const int workers_count = players[player_id]->army->workers;
  players[player_id]->resources += RESOURCES_STEP + (workers_count * 5);
  save_state();
}

How I should save it into memory? How does it work? I can't find answer for this.

Maybe this code will also help:

game_state_t **get_memory_data(char *shmaddr) {
  const int shmat_flag = 0;
  return shmat(memory_id, shmaddr, shmat_flag);
}

void detach_memory_data(game_state_t **data) {
  if (shmdt(data) == -1) {
    perror("Error detaching memory: ");
    exit(1);
  };
}
4
  • 1
    shmat returns a pointer to shared memory, not a pointer of pointer. Commented Feb 19, 2016 at 14:39
  • 2
    I think that the main problem in your code is that you are thinking to share pointer through a shared memory between processes. Your players array contains 2 pointer that are allocate by a single process. Those mallocated address are virtualized. You cannot share those "value" between process. Commented Feb 19, 2016 at 14:56
  • I will check that. You gave me an idea. Thanks Commented Feb 19, 2016 at 15:00
  • I'd also change implementation using mmap, on a modern platform, rather than System V functions, for the shared mem. Commented Feb 19, 2016 at 15:06

1 Answer 1

1

You have game_state_t variable. If you are storing multiple states, you only need single dimension array. Here is the sample.

game_state_t *memstate;
...
memstate = (game_state_t *) malloc( n * sizeof(game_state_t)); /* alloc memory for n states */

shmptr = shmat(...);

memcpy(shmptr, memstate, size);  /* size for example n * size of(game_state_t)); */

OR Simply use only the shared memory.

memstate = shmat(...);

As indicated in the comments, the pointer members of the structure need to point to the shared memory.

Example;

memstate.x = memstate + offset; /* use different offsets based on your usage */ 
Sign up to request clarification or add additional context in comments.

2 Comments

Conceptually right but game_state_t struct has a army_t *army member. This address cannot be shared between processes.
right. I agree. Thx. Some part of shared memory can be used. I think we don't need a heap allocation here. All can be stored in the shared memory itself.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.