//Enqueue d into the FIFO, blocking until the FIFO has room to accept it. void fifo_wr(struct fifo *f,unsigned long d){ sem_wait(&f->wr_sem); //wait for an available slot to write sem_wait(&f->mutex); //obtain the mutex f->buf[f->next_write++]=d; //perform the write f->next_write%=MYFIFO_BUFSIZ; sem_inc(&f->mutex); //release the mutex sem_inc(&f->rd_sem); //increment the number of available reading slots }
void fifo_wr(struct fifo *f, unsigned long d) { sem_wait(&f->s_wk); sem_wait(&f->s_w); f->queue[*f->end % MYFIFO_BUFSIZ] = d; (*f->end)++; sem_inc(&f->s_wk); sem_inc(&f->s_r); }
unsigned long fifo_rd(struct fifo *f) { sem_wait(&f->s_rk); sem_wait(&f->s_r); unsigned long result = f->queue[*(f->start) % MYFIFO_BUFSIZ]; (*f->start)++; sem_inc(&f->s_rk); sem_inc(&f->s_w); return result; }
//Dequeue and return the next data word, blocking until there are available words. unsigned long fifo_rd(struct fifo *f){ unsigned long d; sem_wait(&f->rd_sem); //wait for an available slot to read sem_wait(&f->mutex); //obtain the mutex d=f->buf[f->next_read++]; //perform the read f->next_read%=MYFIFO_BUFSIZ; sem_inc(&f->mutex); //release the mutex sem_inc(&f->wr_sem); //increment the number of available writing slots return d; }
void fifo_wr(struct fifo *f, unsigned long d) { while(1) { sem_wait(&f->wr_sem); if (mutex_trylock(&f->wr_lock)) { f->arr[f->wr_pos] = d; f->wr_pos = (f->wr_pos + 1)%MYFIFO_BUFSIZ; mutex_unlock(&f->wr_lock); sem_inc(&f->rd_sem); return; } else sem_inc(&f->wr_sem); } }
unsigned long fifo_rd(struct fifo *f) { unsigned long retval; while(1) { sem_wait(&f->rd_sem); if (mutex_trylock(&f->rd_lock)) { retval = f->arr[f->rd_pos]; f->rd_pos = (f->rd_pos + 1)%MYFIFO_BUFSIZ; mutex_unlock(&f->rd_lock); sem_inc(&f->wr_sem); return retval; } else sem_inc(&f->rd_sem); } }
int main(int argc, char** argv) { int procs[NUMPROC]; int *mapped; s = mmap(0,(sizeof (struct sem)),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0); sem_init(s, 1); mapped = mmap(0,(sizeof (int)),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0); mapped[0] = 0; int curr_proc; int i; for (i = 1; i < NUMPROC; i++) { curr_proc = fork(); procs[i] = curr_proc; if (curr_proc == 0) break; else if (curr_proc == -1){ perror("couldn't fork\n"); exit(1); } my_procnum = i; } int initial; int end; int j; for (j = 0; j < 1e6; j++){ sem_wait(s); fprintf(stderr," locked for process %d\n",my_procnum); initial = mapped[0]; end = ++mapped[0]; if (end != initial+1){ fprintf(stderr,"size mismatch! process %d started with %d and ended with %d\n",i,initial,end); for(j = 0; j < NUMPROC; j++) { if (j != my_procnum && s->pids[j]) { kill(s->pids[j], SIGINT); } } exit (1); } else{ fprintf(stderr,"process %d started with %d and ended with %d\n",my_procnum,initial,end); } fprintf(stderr,"unlocked for process %d\n",my_procnum); sem_inc(s); } return 0; }