From 0c9d712a77bbede4808142944776d35f502bffa7 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Mon, 6 Dec 2010 19:55:19 +0100 Subject: IPC implementiert MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hat noch einen Bug, sollte aber als Beispiel für die anderen Aufgaben gut genug sein. --- aufgabe4/queue.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 aufgabe4/queue.c (limited to 'aufgabe4/queue.c') diff --git a/aufgabe4/queue.c b/aufgabe4/queue.c new file mode 100644 index 0000000..62a888c --- /dev/null +++ b/aufgabe4/queue.c @@ -0,0 +1,138 @@ +/* + * vim:ts=4:sw=4:expandtab + * + * © 2010 Michael Stapelberg + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "queue.h" + +static const int queue_size = sizeof(struct queueheader) + (sizeof(struct msg) * 255); + +static int fd; +static uint8_t *shm; +static struct queueheader *shmheader; +static struct msg *shmdata; + +/* + * Sperrt den Semaphor: Nun kann im Shared Memory-Bereich geschrieben werden. + * + */ +static void lock() { + while (1) { + if (sem_wait(&(shmheader->sem)) == -1) { + if (errno == EINTR) + continue; + perror("sem_wait"); + exit(EXIT_FAILURE); + } + break; + } +} + +/* + * Entsperrt den Semaphor. + * + */ +static void unlock() { + sem_post(&(shmheader->sem)); +} + +/* + * Initialisiert das Shared Memory-Segment, bildet es in den Speicher ab und + * initialisiert den Semaphor. + * + */ +void queue_init() { + int flags = O_RDWR | O_CREAT | O_TRUNC; + if ((fd = shm_open("/bts-sem", flags, S_IREAD | S_IWRITE)) == -1) { + perror("shm_open"); + exit(EXIT_FAILURE); + } + + ftruncate(fd, queue_size); + + if ((shm = mmap(0, queue_size, (PROT_READ | PROT_WRITE), + MAP_SHARED, fd, 0)) == MAP_FAILED) { + perror("mmap"); + exit(EXIT_FAILURE); + } + + shmheader = (struct queueheader*)shm; + shmdata = (struct msg*)(shm + sizeof(struct queueheader)); + + shmheader->cur = 0; + shmdata->dir = D_INVALID; + + /* Semaphor initialisieren */ + if (sem_init(&(shmheader->sem), 1, 1) != 0) { + perror("sem_init"); + exit(EXIT_FAILURE); + } +} + +/* + * Hängt den übergebenen Wert in die Queue. + * + */ +struct msg *queue_write(uint8_t dir, uint8_t data) { + struct msg msg; + msg.dir = dir; + msg.data = data; + + uint8_t next; + if (shmheader->cur == 255) + next = 0; + else next = shmheader->cur + 1; + + lock(); + struct msg *curmsg = shmdata + (shmheader->cur * sizeof(struct msg)); + struct msg *nextmsg = shmdata + (next * sizeof(struct msg)); + memcpy(nextmsg, &msg, sizeof(struct msg)); + if (curmsg->dir == D_INVALID) + shmheader->cur = next; + unlock(); + + return nextmsg; +} + +/* + * Gibt die Quelle der derzeit zu verarbeitenden Nachricht zurück. + * + */ +uint8_t queue_get_dir() { + struct msg *curmsg = shmdata + (shmheader->cur * sizeof(struct msg)); + return curmsg->dir; +} + +/* + * Gibt den Wert der derzeit zu verarbeitenden Nachricht zurück und invalidiert + * diese. + * + */ +uint8_t queue_get_data() { + uint8_t data; + + struct msg *curmsg = shmdata + (shmheader->cur * sizeof(struct msg)); + data = curmsg->data; + + lock(); + curmsg->dir = D_INVALID; + if (shmheader->cur == 255) + shmheader->cur = 0; + else shmheader->cur++; + unlock(); + + return data; +} -- cgit v1.2.3-70-g09d2