I am currently implementing a Shared Memory ring buffer program for an assignment that writes several values in, from several processes, and then reads them out. Standard producer/consumer model. I have it working, except when the value gets over 255, it reads it as zero. I am sure this has to do with the value type of an int being 8 bits, but I can't figure out how to get around it. Here is some code;
HEADer (just the struct definitions)
Code:
typedef int value_type;
typedef struct ringbuf {
int size; /* # of valid elements in the buffer */
int capacity; /*maximum # of elemenets in buffer*/
int refcount;
sem_t get;
sem_t put;
sem_t mtx;
char *shm;
char *head;
char *tail;
} ringbuf_desc_t;
typedef struct ringbuf_instance {
int shmid;
size_t size;
char *pc;
char name[MAX_PATH_LEN];
} ringbuf_instance_t;
Ring Buffer Module:
Code:
ringbuf_instance_t /*creates the shared memory*/
*ringbuf_create(const char *name, int remove_existing, size_t num_elements)
{
int fd;
int flags = O_RDWR | O_CREAT;
int mode = 0666;
char sname[MAX_PATH_LEN]="/";
if(remove_existing){ /*to be filled in with code for removing ringbuffer*/
}
ringbuf_instance_t *rbi =(ringbuf_instance_t *)malloc(sizeof *rbi);
strcat(sname, name);
if ((fd = shm_open(sname, flags, mode)) <0)
syserr("shm_open");
if(ftruncate(fd,num_elements) < 0)
syserr("ftrruncate");
if((int)(rbi->pc=mmap(0,num_elements, PROT_READ | PROT_WRITE, MAP_SHARED, fd,0)) == -1)
syserr("mmap");
rbi->size=num_elements;
rbi->shmid=fd;
strcpy(rbi->name, sname);
return rbi;
}
ringbuf_desc_t t /*associates the ringbuffer with the shared memory*/
*ringbuf_attach(ringbuf_instance_t *rbi)
{
int mode = 0666;
ringbuf_desc_t *p =(ringbuf_desc_t *)malloc(sizeof *p);
if(sem_init(&p->mtx,0,1)<0)
syserr("sem_init 0");
if(sem_init(&p->get,0,0)<0)
syserr("sem_init 1");
if(sem_init(&p->put,0,rbi->size/sizeof(value_type))<0)
syserr("sem_init 2");
p->capacity = rbi->size;
p->size = 0;
p->refcount=0;
p->shm=shmat(rbi->shmid, NULL, 0);
p->shm=rbi->pc;
p->head=rbi->pc;
p->tail=rbi->pc;
if(sem_wait(&p->mtx)<0)
syserr("Producer sem_wait");
p->refcount++;
if(sem_post(&p->mtx)<0)
syserr("Producer sem_post");
return p;
}void
ringbuf_put(ringbuf_desc_t *rb,value_type y)
{
char *s;
if(sem_wait(&rb->put)<0)
syserr("Producer sem_wait");
if(sem_wait(&rb->mtx)<0)
syserr("Producer Mutex");
if(rb->head==rb->shm+12)
rb->head=rb->shm;
s=rb->head;
*s=y;
printf("s= %u y = %d, %\n", rb->head, y, *s);
rb->head++;
rb->size++;
if(sem_post(&rb->mtx)<0)
syserr("Producer Mutex");
if(sem_post(&rb->get)<0)
syserr("Producer sem_post1");
return;
}
value_type
ringbuf_get(ringbuf_desc_t *rb)
{
unsigned char y;
char *s;
if(sem_wait(&rb->get)<0)
syserr("Producer sem_wait");
if(sem_wait(&rb->mtx)<0)
syserr("Producer Mutex");
if(rb->tail==rb->shm+12)
rb->tail=rb->shm;
s=rb->tail;
y=*s;
printf("tail %u %d\n", rb->tail,y);
rb->size--;
rb->tail++;
if(sem_post(&rb->mtx)<0)
syserr("Producer Mutex");
if(sem_post(&rb->put)<0)
syserr("Producer sem_post1");
return y;
}