buffer cache reader-writer problem in 2.4.18



I've no idea what's wrong in my mind.
When I finished reading the code about the buffer cache machine in
2.4.18, I think the kernel
doesn't promise that two concurrent processes get a consitent result
when at every execution time. To test my idea, I wrote the code below,
but there maybe something wrong in my code,
anyone would offer any help? Thanks a lot.

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>

#include <linux/sem.h>

#include <signal.h>

int fp;

int sem_setval(int sem_set_id, unsigned short index, int val)
{
union semun option;
option.val = val;
return semctl(sem_set_id, index, SETVAL, option);
}

void sem_wait(int sem_set_id, unsigned short index)
{
struct sembuf sem_op;
sem_op.sem_num = index;
sem_op.sem_op = -1;
sem_op.sem_flg = 0;
semop(sem_set_id, &sem_op, 1);
}

void sem_signal(int sem_set_id, unsigned short index)
{
struct sembuf sem_op;
sem_op.sem_num = index;
sem_op.sem_op = 1;
sem_op.sem_flg = 0;
semop(sem_set_id, &sem_op, 1);
}

void SIGCHLD_handler(int n)
{
int child_status;
wait(&child_status);
printf("status = %d, child really exited.\n", child_status);
}

void reader()
{
unsigned char *buf;
buf = (unsigned char*)malloc(256);
lseek(fp, 0, SEEK_SET);
read(fp, buf, 256);
printf("buf[0]=%d\n", buf[0]);
if(buf[0] == 0xAA)
printf("got the writer\n");
else if(buf[0] == 0x55)
printf("got the orignal\n");
close(fp);
free(buf);
}

void writer()
{
unsigned char *buf;
buf = (unsigned char*)malloc(256);
memset(buf, 0xAA, 256);
lseek(fp, 0, SEEK_SET);
write(fp, buf, 256);
fsync(fp);
close(fp);
free(buf);
}

int main()
{
pid_t pid_read,pid_write;
int sem_set_id;
unsigned char *buf;

//create the semaphone set
sem_set_id = semget(IPC_PRIVATE, 1, 0666);
if(sem_set_id == -1)
{
perror("main: semget\n");
exit(1);
}

while(1) {
char ch;
//inititialize the semaphore
sem_setval(sem_set_id, 0, 0);

fp = open("./try.txt", O_SYNC|O_RDWR);
if(!fp)
{
perror("main: fileopen error\n");
exit(1);
}
buf = (unsigned char*)malloc(1024);
memset(buf, 0x55, 1024);
write(fp, buf, 1024);
fsync(fp);
close(fp);
fp = open("./try.txt", O_SYNC|O_RDWR);
if(!fp)
{
perror("main: fileopen error\n");
exit(1);
}

signal(SIGCHLD, SIGCHLD_handler);

//create read process
pid_read = fork();
if(pid_read<0)
{
perror("fork");
exit(1);
}
else if(pid_read == 0)
{
printf("reader is waiting\n");
sem_wait(sem_set_id, 0);
printf("entering reader\n");
reader();
sem_signal(sem_set_id, 0);
exit(1);
}

//create write process
pid_write = fork();
if(pid_write<0)
{
perror("fork");
exit(1);
}
else if(pid_write == 0)
{
printf("writer is waiting\n");
sem_wait(sem_set_id, 0);
printf("entering writer\n");
writer();
sem_signal(sem_set_id, 0);
printf("exiting writer\n");
exit(1);
}

//continue the main process
{
char c;
while((c=getchar()) != 'q')
{
if(c=='c') {
sem_setval(sem_set_id, 0, 2);
}
}
close(fp);

//kill all the children
kill(pid_read, SIGABRT);
kill(pid_write, SIGABRT);
sleep(1);
}

// printf("waiting for next step\n");
// printf("fflush returns %d\n", fflush(0));
// fflush(stdout);
// scanf("%c", &ch);
// printf("ch = %c\n", ch);
// if(ch == 'q')
// break;
break;
printf("have the test again\n");
}
semctl(sem_set_id, 0, IPC_RMID, 0);
printf("exiting the main\n");
return 0;
}

.



Relevant Pages