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 }
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 }
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 }
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; }