#include #include #include #include int semID=0; struct sembuf sopList[3]; int mutex_init(){ /* free state */ sopList[0].sem_num=0; sopList[0].sem_op=0; sopList[0].sem_flg=SEM_UNDO|IPC_NOWAIT; /* lock it */ sopList[1].sem_num=0; sopList[1].sem_op=1; sopList[1].sem_flg=SEM_UNDO|IPC_NOWAIT; // Non blocking /* unlock it */ sopList[2].sem_num=0; sopList[2].sem_op=-1; sopList[2].sem_flg=SEM_UNDO|IPC_NOWAIT; if((semID=semget(IPC_PRIVATE,1,IPC_CREAT|0666))<0){ perror("mutex_init :: "); return 1; } return 0; } /* NOTE: I am not queuing the sem ops, because i dont want my processes blocked * hence causing a potential race, but this condition has been handled * */ int mutex_lock(){ if(semop(semID,&sopList[0],1)!=-1){ #ifdef DEBUG printf("mutex_lock :: process %i found it unlocked\n",getpid()); #endif if(semop(semID,&sopList[1],1)!=-1){ // perform the lock #ifdef DEBUG printf("mutex_lock :: process %i locked it\n",getpid()); #endif return 0; } } #ifdef DEBUG printf("mutex_lock %i :: return 1\n",getpid()); #endif return 1; } /* RETURN value: 0 if unlocked, else 1 */ int mutex_unlock(){ return(semop(semID,&sopList[2],1)); // perform the unlock } int main(void){ pid_t pid; int stat; mutex_init(); double slept=0; if((pid=fork())<0)return 1; if(pid==0)printf("Child %i created\n",getpid()); for(slept=0;slept<1;slept+=0.1){ if(!(stat=mutex_lock()))break; sleep(0.1); } if(stat){ printf("process %i, tried locking for 1 second but failed \n",getpid()); }else{ printf("process %i, locked it, and is sleeping\n",getpid()); sleep(2); for(slept=0;slept<1;slept+=0.1){ if(!(stat=mutex_unlock()))break; sleep(0.1); } if(stat){ printf("process %i, tried to UNlock for 1 second but failed \n",getpid()); }else{ printf("process %i, UNlocked it,\n",getpid()); } } if(pid>0){ printf("Parent is done and is waiting for child to die \n"); wait(&stat); } printf("process %i, has finished \n",getpid()); return 0; }