예제 #1
0
TASK_DLLEXPORT int
Task_wait_read(int fd, long msec)
{
   Task *tp;

   struct timeval tv;

   fd_set set;

   int r;

   if (!canSwitch)
   {

      FD_ZERO(&set);
      FD_SET(fd, &set);
      calcTv(&tv, msec);
      r = t_select(FD_SETSIZE, &set, 0, 0, &tv);
      if (r > 0)
	 return 0;
      else if (r == 0)
	 return 1;
      else
	 return r;
   }

   tp = currTask;

   FD_ZERO(&set);
   FD_SET(fd, &set);
   tv.tv_sec = tv.tv_usec = 0;
   r = t_select(FD_SETSIZE, &set, 0, 0, &tv);

   if (r != 0)
   {
      Task_yield();
      if (r > 0)
	 return 0;
      else
	 return r;
   }

   FD_ZERO(&tp->rfileset);
   FD_SET(fd, &tp->rfileset);

   tp->wakeUp = calcWakeup(msec);
   removeFromList(tp);
   tp->isRead = 1;
   addToWait(tp);
   tp->isTimed = 0;

   Task_yield();

   tp->isRead = 0;
   return tp->isTimed;
}
예제 #2
0
//call before moving to a new area
//called on a chef to check if other chefs
//are executing recipes that could cause a deadlock
//if a deadlock case could occur based on the order of the
//recipes on the other two chefs, the called on chef downs its
//own semaphore, which should be 0, going to sleep.
//To wake a chef, call clearAreas(Data *mychef)
void checkChefs(Data *mychef) {
    int i, j, semval;
    //loop through the array of data structs
    //protect shared list of data
    sem_wait(&s_list);
    for(i = 0; i < 3; i++) {
        sem_getvalue(&chefs[i].sem,&semval);
        if(mychef->step == -1) {
            if(mychef->recipe.tasks[0].a == chefs[i].recipe.tasks[chefs[i].step].a) {
                addToWait(mychef, &chefs[i]);
                //release data list and go to sleep
                sem_post(&s_list);
                sem_wait(&chefs[mychef->ID].sem);
            }
        }

        //check for deadlocks based on recipes
        //only loop through recipies of awake, executing chefs
        if((semval > -1)&&(chefs[i].ID != mychef->ID)) {
            for(j = chefs[i].recipe.numTasks; j > -1; j--) {
                //check a deadlock case in which my area is the next area of another chef
                //and my next area is currently occupied by that chef
                if((mychef->recipe.tasks[mychef->step].a == chefs[i].recipe.tasks[j+1].a) &&
                        (mychef->recipe.tasks[(mychef->step)+1].a == chefs[i].recipe.tasks[j].a)) {
                    addToWait(mychef, &chefs[i]);
                    //release data list and go to sleep
                    sem_post(&s_list);
                    sem_wait(&(chefs[mychef->ID].sem));
                    printf("Chef %d is going to sleep in %s area",mychef->ID, getAreaStr(mychef->recipe.tasks[mychef->step].a));
                }
            }
        }
        //check if mychef's next area is currently occupied by another chef
        if(mychef->recipe.tasks[(mychef->step)+1].a == chefs[i].recipe.tasks[chefs[i].step].a) {
            addToWait(mychef, &chefs[i]);
            //release data list and go to sleep
            sem_post(&s_list);
            sem_wait(&(chefs[mychef->ID].sem));
        }
    }
}