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)
Ring Buffer Module: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;
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; }



LinkBack URL
About LinkBacks


