CIS 307: Hints for Homework 4

The big change in this homework with respect to the previous homework is that now the client programs operate directly on the shared store. You need to use a memory segment to be shared by the client processes. Stevens and my notes give examples of how we can created shared segments.

Here is the content of a file that defines N locks. See if it can help you.

  /* filelock.c  -- Defines mutexes in terms of locks on files. 
   *                filelock, filelockCreate, filelockDelete,
   *                filelockLock, filelockUnlock
   */

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


  typedef struct {
    int fd;
    int n;} filelock;

  /* Create N locks and returns the id of this cluster of locks. */
  filelock * filelockCreate(char *filename, int n) {

   filelock *fl = (filelock *)malloc(sizeof(filelock));

   if (((fl->fd) = open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IWUSR)) < 0)   {
      perror("open");
      exit(1);}
   fl->n = n;
   return fl;
   }

  /* Delete the cluster of locks associated with fl. */
  int filelockDelete(filelock *fl) {

   if (close(fl->fd) < 0) {
     perror("close");
     exit(1);}
   return free(fl);
   }


  /* Given the lock cluster fl, lock its ith element */
  int filelockLock(filelock *fl, int i) {

   if ((i < 0) | (i >= fl->n)) {
     printf("filelockLock needs i in range 0 .. %d\n", (fl->n)-1);
     exit(0);}
   if (lseek(fl->fd, i, SEEK_SET) < 0) {
     perror("lseek");
     exit(1);}
   if (lockf(fl->fd, F_LOCK, 1) < 0) {
     perror("lockf");
     exit(1);}
   }

  /* Given the lock cluster fl, unlock its ith element */
  int filelockUnlock(filelock *fl, int i){

   if ((i < 0) | (i >= fl->n)) {
     printf("filelockUnlock needs i in range 0 .. %d\n", (fl->n)-1);
     exit(0);}
   if (lseek(fl->fd,i, SEEK_SET) < 0) {
     perror("lseek");
     exit(1);}
   if (lockf(fl->fd, F_ULOCK, 1) < 0) {
     perror("lockf");
     exit(1);}
   }

Here is a program that tests if the locks are working:

  /* lockfmain.c -                                                           */
  /* This is just a driver to test the filelock objects defined in lockf.c   */
  /* MAXCHILD processes are forked. They take turns in using LOCKSSIZE locks.*/
  /* I compiled the progarm as follows                                       */
  /*      cc lockfmain.c lockf.c -o lockmain                                 */
  /* and then run the image lockmain.                                        */
  /* Notice that after the program has run I find the file "mylock" in my    */
  /* directory. Not very desirable. Perhaps there is a way to avoid that?    */

  #include <stdio.h>
  #include <sys/types.h>
  #include "lockf.h"

  #define LOCKFILE "mylock"
  #define LOCKSSIZE 3
  #define MAXCHILD 4

  void child (int self);

  pid_t cldrn[4];
  filelock *fl;

  int 
  main(void){
    int i;

    fl = filelockCreate(LOCKFILE, LOCKSSIZE);
    for (i=0;i

where the file lockf.h is just:

  /* lockf.h  -- Defines mutexes in terms of locks on files. 
   *                filelock, filelockCreate, filelockDelete,
   *                filelockLock, filelockUnlock
   */

  typedef struct {
    int fd;
    int n;} filelock;

  /* Create N locks and returns the id of this cluster of locks. */
  extern filelock * filelockCreate(char *filename, int n);

  /* Delete the cluster of locks associated with fl. */
  extern int filelockDelete(filelock *fl);


  /* Given the lock cluster fl, lock its ith element */
  extern int filelockLock(filelock *fl, int i);

  /* Given the lock cluster fl, unlock its ith element */
  extern int filelockUnlock(filelock *fl, int i);

ingargiola@cis.temple.edu