User Tools

Site Tools


Sidebar


Start


Teaching:

Feedback


os_cp:semaphores:solutions

This is an old revision of the document!


#include <fcntl.h>
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
 
#define MAX_ELEMENTS 4
typedef char item_t[256];
 
struct ring_buffer {
  item_t data[MAX_ELEMENTS];
  size_t first;
  size_t last;
};
 
struct ring_buffer *buffer;
 
sem_t *storedItemsCount;
sem_t *emptyItemsCount;
sem_t *canModify;
 
void put(struct ring_buffer *buffer, const item_t *item) {
  sem_wait(emptyItemsCount);
  sem_wait(canModify);
  memcpy(&buffer->data[buffer->last], item, sizeof(*item));
  buffer->last = (buffer->last + 1) % MAX_ELEMENTS;
  sem_post(canModify);
  sem_post(storedItemsCount);
}
 
void get(struct ring_buffer *buffer, item_t *item) {
  sem_wait(storedItemsCount);
  sem_wait(canModify);
  memcpy(item, &buffer->data[buffer->first], sizeof(*item));
  buffer->first = (buffer->first + 1) % MAX_ELEMENTS;
  sem_post(canModify);
  sem_post(emptyItemsCount);
}
 
int main() {
  int fd = shm_open("/myRingBuffer", O_RDWR | O_CREAT, 0666);
  if (fd == -1) { perror("shm_open"); exit(1); }
  ftruncate(fd, sizeof(struct ring_buffer));
  buffer = mmap(NULL, sizeof(struct ring_buffer), PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);
 
  storedItemsCount = sem_open("myRingBuffer.storedItems", O_RDWR | O_CREAT, 0666, 0);
  emptyItemsCount  = sem_open("myRingBuffer.emptyItems",  O_RDWR | O_CREAT, 0666, 4);
  canModify        = sem_open("myRingBuffer.canModify",   O_RDWR | O_CREAT, 0666, 1);
 
  printf("g             gets data from buffer\n"
         "ptext...      puts 'text...' to buffer\n");
  while (1) {
    printf("> ");
    fflush(stdout);
    char cmd[2], c;
    item_t item = {0};
    scanf("%1[^\n]%255[^\n]", cmd, item);
    do { // this reads all remaining characters in this line including '\n'
      c = getchar();
      if (c == -1)
        return 0;
    } while (c != '\n');
    switch (cmd[0]) {
    case 'p':
      put(buffer, &item);
      break;
    case 'g':
      get(buffer, &item);
      printf("%s\n", item);
      break;
    }
  }
  return 0;
}

os_cp/semaphores/solutions.1683704319.txt.gz · Last modified: 2023/05/10 09:38 by jkonczak