Beispiel #1
0
void DB_ViewPut(int vol, struct GBD *ptr)		// que block for write
{ short s;						// for funcs

  volnum = vol;						// for ron
  writing = 0;						// clear this
  s = SemOp(SEM_GLOBAL, WRITE);				// write lock
  if (s < 0)						// check error
  { return;						// quit if so
  }
  ptr->last_accessed = MTIME(0);			// reset access
  if (ptr->mem->type)					// if used
  { Used_block(ptr->block);				// mark it so
  }
  else 							// trying to free it
  { Free_block(ptr->block);				// do so
    bzero(ptr->mem, systab->vol[(volnum)-1]->vollab->block_size); // clear it
  }
  level = 0;						// for Queit
  if (ptr->dirty == NULL)				// check dirty ptr
  { ptr->dirty = ptr;					// set if reqd
    blk[level] = ptr;					// ditto
    Queit();						// do this
  }
  if (curr_lock)
  { SemOp(SEM_GLOBAL, -curr_lock);			// release lock
  }
  return;						// and exit
}
Beispiel #2
0
void DB_ViewRel(int vol, struct GBD *ptr)	      	// release block, gbd
{ short s;						// for functions

  writing = 0;						// clear this
  ptr->last_accessed = MTIME(0);			// reset access
  if (ptr->dirty != NULL)				// not owned elsewhere
  { s = SemOp(SEM_GLOBAL, WRITE);			// write lock
    if (s < 0)						// check error
    { return;						// quit if so
// PROBABLY SHOULD PERSIST HERE
    }
    Free_GBD(ptr);					// free it
    SemOp(SEM_GLOBAL, -curr_lock);			// release lock
  }
  return;						// and exit
}
Beispiel #3
0
struct GBD *DB_ViewGet(int vol, int block)		// return gbd for blk
{ short s;						// for func
  if ((block < 1) || (block > systab->vol[vol-1]->vollab->max_block))
  { return NULL;					// validate
  }
  level = 0;						// where it goes
  volnum = vol;						// need this
  writing = 0;						// clear this
  s = SemOp(SEM_GLOBAL, READ);				// write lock
  if (s < 0)						// check error
  { return NULL;					// quit if so
  }
  s = Get_block(block);					// get it
  if (s >= 0)
  { blk[level]->last_accessed = MTIME(0)+86400;		// push last access
  }
  if (curr_lock)
  { SemOp( SEM_GLOBAL, -curr_lock);			// unlock the globals
  }
  return (s < 0) ? NULL : blk[level];			// return whatever
}
Beispiel #4
0
int
update_goal_chain (struct dep *goals)
{
  int t = touch_flag, q = question_flag, n = just_print_flag;
  int status = -1;

#define	MTIME(file) (rebuilding_makefiles ? file_mtime_no_search (file) \
		     : file_mtime (file))

  /* Duplicate the chain so we can remove things from it.  */

  goals = copy_dep_chain (goals);

  {
    /* Clear the 'changed' flag of each goal in the chain.
       We will use the flag below to notice when any commands
       have actually been run for a target.  When no commands
       have been run, we give an "up to date" diagnostic.  */

    struct dep *g;
    for (g = goals; g != 0; g = g->next)
      g->changed = 0;
  }

  /* All files start with the considered bit 0, so the global value is 1.  */
  considered = 1;

  /* Update all the goals until they are all finished.  */

  while (goals != 0)
    {
      register struct dep *g, *lastgoal;

      /* Start jobs that are waiting for the load to go down.  */

      start_waiting_jobs ();

      /* Wait for a child to die.  */

      reap_children (1, 0);

      lastgoal = 0;
      g = goals;
      while (g != 0)
	{
	  /* Iterate over all double-colon entries for this file.  */
	  struct file *file;
	  int stop = 0, any_not_updated = 0;

	  for (file = g->file->double_colon ? g->file->double_colon : g->file;
	       file != NULL;
	       file = file->prev)
	    {
	      unsigned int ocommands_started;
	      int x;

              file->dontcare = g->dontcare;

	      check_renamed (file);
	      if (rebuilding_makefiles)
		{
		  if (file->cmd_target)
		    {
		      touch_flag = t;
		      question_flag = q;
		      just_print_flag = n;
		    }
		  else
		    touch_flag = question_flag = just_print_flag = 0;
		}

	      /* Save the old value of 'commands_started' so we can compare
		 later.  It will be incremented when any commands are
		 actually run.  */
	      ocommands_started = commands_started;

	      x = update_file (file, rebuilding_makefiles ? 1 : 0);
	      check_renamed (file);

	      /* Set the goal's 'changed' flag if any commands were started
		 by calling update_file above.  We check this flag below to
		 decide when to give an "up to date" diagnostic.  */
              if (commands_started > ocommands_started)
                g->changed = 1;

              /* If we updated a file and STATUS was not already 1, set it to
                 1 if updating failed, or to 0 if updating succeeded.  Leave
                 STATUS as it is if no updating was done.  */

	      stop = 0;
	      if ((x != 0 || file->updated) && status < 1)
                {
                  if (file->update_status != 0)
                    {
                      /* Updating failed, or -q triggered.  The STATUS value
                         tells our caller which.  */
                      status = file->update_status;
                      /* If -q just triggered, stop immediately.  It doesn't
                         matter how much more we run, since we already know
                         the answer to return.  */
                      stop = (question_flag && !keep_going_flag
                              && !rebuilding_makefiles);
                    }
                  else
                    {
                      FILE_TIMESTAMP mtime = MTIME (file);
                      check_renamed (file);

                      if (file->updated && g->changed &&
                           mtime != file->mtime_before_update)
                        {
                          /* Updating was done.  If this is a makefile and
                             just_print_flag or question_flag is set (meaning
                             -n or -q was given and this file was specified
                             as a command-line target), don't change STATUS.
                             If STATUS is changed, we will get re-exec'd, and
                             enter an infinite loop.  */
                          if (!rebuilding_makefiles
                              || (!just_print_flag && !question_flag))
                            status = 0;
                          if (rebuilding_makefiles && file->dontcare)
                            /* This is a default makefile; stop remaking.  */
                            stop = 1;
                        }
                    }
                }

	      /* Keep track if any double-colon entry is not finished.
                 When they are all finished, the goal is finished.  */
	      any_not_updated |= !file->updated;

              file->dontcare = 0;

	      if (stop)
		break;
	    }

	  /* Reset FILE since it is null at the end of the loop.  */
	  file = g->file;

	  if (stop || !any_not_updated)
	    {
	      /* If we have found nothing whatever to do for the goal,
		 print a message saying nothing needs doing.  */

	      if (!rebuilding_makefiles
		  /* If the update_status is zero, we updated successfully
		     or not at all.  G->changed will have been set above if
		     any commands were actually started for this goal.  */
		  && file->update_status == 0 && !g->changed
		  /* Never give a message under -s or -q.  */
		  && !silent_flag && !question_flag)
		message (1, ((file->phony || file->cmds == 0)
			     ? _("Nothing to be done for '%s'.")
			     : _("'%s' is up to date.")),
			 file->name);

	      /* This goal is finished.  Remove it from the chain.  */
	      if (lastgoal == 0)
		goals = g->next;
	      else
		lastgoal->next = g->next;

	      /* Free the storage.  */
	      free (g);

	      g = lastgoal == 0 ? goals : lastgoal->next;

	      if (stop)
		break;
	    }
	  else
	    {
	      lastgoal = g;
	      g = g->next;
	    }
	}

      /* If we reached the end of the dependency graph toggle the considered
         flag for the next pass.  */
      if (g == 0)
        considered = !considered;
    }

  if (rebuilding_makefiles)
    {
      touch_flag = t;
      question_flag = q;
      just_print_flag = n;
    }

  return status;
}