version 1.82, 2007/09/23 09:41:11 |
version 1.83, 2007/09/23 09:44:39 |
|
|
short flags; /* Flags to control treatment of job */ |
short flags; /* Flags to control treatment of job */ |
#define JOB_IGNERR 0x001 /* Ignore non-zero exits */ |
#define JOB_IGNERR 0x001 /* Ignore non-zero exits */ |
#define JOB_SILENT 0x002 /* no output */ |
#define JOB_SILENT 0x002 /* no output */ |
#define JOB_SPECIAL 0x004 /* Target is a special one. i.e. run it locally |
#define JOB_SPECIAL 0x004 /* Target is a special one. */ |
* if we can't export it and maxLocal is 0 */ |
|
#define JOB_IGNDOTS 0x008 /* Ignore "..." lines when processing |
#define JOB_IGNDOTS 0x008 /* Ignore "..." lines when processing |
* commands */ |
* commands */ |
#define JOB_FIRST 0x020 /* Job is first job for the node */ |
#define JOB_FIRST 0x020 /* Job is first job for the node */ |
|
|
|
|
|
|
static int maxJobs; /* The most children we can run at once */ |
static int maxJobs; /* The most children we can run at once */ |
static int maxLocal; /* The most local ones we can have */ |
static int nJobs; /* The number of children currently running */ |
static int nJobs = 0; /* The number of children currently running */ |
|
static int nLocal; /* The number of local children */ |
|
static LIST jobs; /* The structures that describe them */ |
static LIST jobs; /* The structures that describe them */ |
static bool jobFull; /* Flag to tell when the job table is full. It |
static bool jobFull; /* Flag to tell when the job table is full. It |
* is set true when (1) the total number of |
* is set true when nJobs equals maxJobs */ |
* running jobs equals the maximum allowed or |
|
* (2) a job can only be run locally, but |
|
* nLocal equals maxLocal */ |
|
static fd_set *outputsp; /* Set of descriptors of pipes connected to |
static fd_set *outputsp; /* Set of descriptors of pipes connected to |
* the output channels of children */ |
* the output channels of children */ |
static int outputsn; |
static int outputsn; |
|
|
(long)job->pid); |
(long)job->pid); |
(void)fflush(stdout); |
(void)fflush(stdout); |
} |
} |
nLocal++; |
|
if (nJobs == maxJobs) { |
if (nJobs == maxJobs) { |
jobFull = true; |
jobFull = true; |
if (DEBUG(JOB)) { |
if (DEBUG(JOB)) { |
|
|
} |
} |
} |
} |
|
|
nLocal += 1; |
|
/* |
/* |
* Now the job is actually running, add it to the table. |
* Now the job is actually running, add it to the table. |
*/ |
*/ |
|
|
job->node->name); |
job->node->name); |
(void)fflush(stdout); |
(void)fflush(stdout); |
} |
} |
if (nLocal >= maxLocal && !(job->flags & JOB_SPECIAL)) { |
if (nJobs >= maxJobs && !(job->flags & JOB_SPECIAL)) { |
/* |
/* |
* Can't be exported and not allowed to run locally -- |
* Can't be exported and not allowed to run locally -- |
* put it back on the hold queue and mark the table |
* put it back on the hold queue and mark the table |
|
|
(void)fprintf(stdout, "Resuming %s...", job->node->name); |
(void)fprintf(stdout, "Resuming %s...", job->node->name); |
(void)fflush(stdout); |
(void)fflush(stdout); |
} |
} |
if ((nLocal < maxLocal || ((job->flags & JOB_SPECIAL) && |
if ((nJobs < maxJobs || ((job->flags & JOB_SPECIAL) && |
maxLocal == 0)) && nJobs != maxJobs) { |
maxJobs == 0)) && nJobs != maxJobs) { |
/* |
/* |
* If we haven't reached the concurrency limit already |
* If we haven't reached the concurrency limit already |
* (or maxLocal is 0), it's ok to resume the job. |
* (or maxJobs is 0), it's ok to resume the job. |
*/ |
*/ |
bool error; |
bool error; |
int status; |
int status; |
|
|
Job *job; /* new job descriptor */ |
Job *job; /* new job descriptor */ |
char *argv[4]; /* Argument vector to shell */ |
char *argv[4]; /* Argument vector to shell */ |
bool cmdsOK; /* true if the nodes commands were all right */ |
bool cmdsOK; /* true if the nodes commands were all right */ |
bool local; /* Set true if the job was run locally */ |
|
bool noExec; /* Set true if we decide not to run the job */ |
bool noExec; /* Set true if we decide not to run the job */ |
|
|
if (previous != NULL) { |
if (previous != NULL) { |
|
|
(void)fcntl(job->outPipe, F_SETFD, 1); |
(void)fcntl(job->outPipe, F_SETFD, 1); |
} |
} |
|
|
local = true; |
if (nJobs >= maxJobs && !(job->flags & JOB_SPECIAL) && |
|
maxJobs != 0) { |
if (local && nLocal >= maxLocal && !(job->flags & JOB_SPECIAL) && |
|
maxLocal != 0) { |
|
/* |
/* |
* The job can only be run locally, but we've hit the limit of |
* The job can only be run locally, but we've hit the limit of |
* local concurrency, so put the job on hold until some other |
* local concurrency, so put the job on hold until some other |
* job finishes. Note that the special jobs (.BEGIN, .INTERRUPT |
* job finishes. Note that the special jobs (.BEGIN, .INTERRUPT |
* and .END) may be run locally even when the local limit has |
* and .END) may be run locally even when the local limit has |
* been reached (e.g. when maxLocal == 0), though they will be |
* been reached (e.g. when maxJobs == 0), though they will be |
* exported if at all possible. In addition, any target marked |
* exported if at all possible. In addition, any target marked |
* with .NOEXPORT will be run locally if maxLocal is 0. |
* with .NOEXPORT will be run locally if maxJobs is 0. |
*/ |
*/ |
jobFull = true; |
jobFull = true; |
|
|
|
|
job->flags |= JOB_RESTART; |
job->flags |= JOB_RESTART; |
Lst_AtEnd(&stoppedJobs, job); |
Lst_AtEnd(&stoppedJobs, job); |
} else { |
} else { |
if (nLocal >= maxLocal && local) { |
if (nJobs >= maxJobs) { |
/* |
/* |
* If we're running this job locally as a special case |
* If we're running this job locally as a special case |
* (see above), at least say the table is full. |
* (see above), at least say the table is full. |
|
|
/* |
/* |
* Don't even bother if we know there's no one around. |
* Don't even bother if we know there's no one around. |
*/ |
*/ |
if (nLocal == 0) { |
if (nJobs == 0) { |
return; |
return; |
} |
} |
|
|
|
|
(void)fflush(stdout); |
(void)fflush(stdout); |
} |
} |
jobFull = false; |
jobFull = false; |
nLocal--; |
|
} |
} |
|
|
JobFinish(job, &status); |
JobFinish(job, &status); |
|
|
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
void |
void |
Job_Init(int maxproc, int maxlocal) |
Job_Init(int maxproc) |
{ |
{ |
int tfd; |
int tfd; |
|
|
|
|
Static_Lst_Init(&jobs); |
Static_Lst_Init(&jobs); |
Static_Lst_Init(&stoppedJobs); |
Static_Lst_Init(&stoppedJobs); |
maxJobs = maxproc; |
maxJobs = maxproc; |
maxLocal = maxlocal; |
|
nJobs = 0; |
nJobs = 0; |
nLocal = 0; |
|
jobFull = false; |
jobFull = false; |
|
|
aborting = 0; |
aborting = 0; |