maui/contrib/fairness/JobLength.c

282 lines
6.6 KiB
C
Raw Normal View History

/* CONTRIB: JobLength.c */
/* code to be included in LocalCheckFairnessPolicy() in Local.c */
# define MAX_LOCAL_JOB_POLICIES 12
/* uses global BQS and Job */
int ContribJobLengthFairnessPolicy(
job_t *J,
long StartTime,
char *Message)
{
int jindex;
int index;
char *buf;
char *ptr;
char FileName[MAX_NAME];
int count;
int SC;
char TimeString[MAX_LINE];
char ParameterName[MAX_NAME];
static struct {
long MinLength;
long MaxLength;
int MaxCount;
int Count;
} JobLengthPolicy[MAX_LOCAL_JOB_POLICIES];
static int LocalPoliciesLoaded = bFALSE;
static int MaxSmallJobCount;
static int MaxSmallJobProcs;
static int MaxSmallJobNodes;
static int SmallJobCount;
if (LocalPoliciesLoaded == bFALSE)
{
/* initialize policies */
memset(JobLengthPolicy,0,sizeof(JobLengthPolicy));
MaxSmallJobCount = 0;
MaxSmallJobProcs = 0;
MaxSmallJobNodes = 0;
LocalPoliciesLoaded = bTRUE;
/* load local config policy configuration */
if (!strstr(BQS.ConfigFile,BQS.HomeDir))
{
if (BQS.HomeDir[strlen(BQS.HomeDir) - 1] == '/')
sprintf(FileName,"%s%s",
BQS.HomeDir,
BQS.ConfigFile);
else
sprintf(FileName,"%s/%s",
BQS.HomeDir,
BQS.ConfigFile);
}
else
{
strcpy(FileName,BQS.ConfigFile);
}
if ((buf = LoadFile(FileName,1,FILEREAD,&count,&SC)) == NULL)
{
DBG(2,fCONFIG) DPrint("WARNING: cannot open configuration file '%s' (using internal defaults)\n",
FileName);
return(FAILURE);
}
AdjustConfigBuffer(buf);
ptr = buf;
ConfigGetIntValue(buf,&ptr,"MAXSMALLJOBCOUNT",NULL,NULL,&MaxSmallJobCount,NULL);
ConfigGetIntValue(buf,&ptr,"MAXSMALLJOBPROCS",NULL,NULL,&MaxSmallJobProcs,NULL);
for (index = 0;index < MAX_LOCAL_JOB_POLICIES;index++)
{
sprintf(ParameterName,"MAXJOB%dCOUNT",
index + 1);
if (ConfigGetIntValue(
buf,
&ptr,
ParameterName,
NULL,
NULL,
&JobLengthPolicy[index].MaxCount,
NULL) == FAILURE)
{
continue;
}
sprintf(ParameterName,"JOB%dMINLENGTH",
index + 1);
if (ConfigGetStringValue(
buf,
&ptr,
ParameterName,
NULL,
NULL,
TimeString,
NULL) == FAILURE)
{
continue;
}
JobLengthPolicy[index].MinLength = TimeS2I(TimeString);
sprintf(ParameterName,"JOB%dMAXLENGTH",
index + 1);
if (ConfigGetStringValue(
buf,
&ptr,
ParameterName,
NULL,
NULL,
TimeString,
NULL) == FAILURE)
{
continue;
}
JobLengthPolicy[index].MaxLength = TimeS2I(TimeString);
DBG(4,fSCHED) DPrint("INFO: local policy joblength[%d] specified: MaxCount %d (%ld -> %ld)\n",
index + 1,
JobLengthPolicy[index].MaxCount,
JobLengthPolicy[index].MinLength,
JobLengthPolicy[index].MaxLength);
} /* END for (index) */
} /* END if (LocalPoliciesLoaded == bFALSE) */
if (J == NULL)
{
/* initialize local policy counts */
SmallJobCount = 0;
for (index = 0;index < MAX_LOCAL_JOB_POLICIES;index++)
{
JobLengthPolicy[index].Count = 0;
}
/* incorporate active job information */
for (jindex = Job[0].Next;jindex != 0;jindex = Job[jindex].Next)
{
if ((Job[jindex].State != jStarting) &&
(Job[jindex].State != jRunning))
continue;
if ((Job[jindex].TasksRequested * Job[jindex].Req[0]->DRes.Procs) <= MaxSmallJobProcs)
{
SmallJobCount++;
}
for (index = 0;index < MAX_LOCAL_JOB_POLICIES;index++)
{
if (JobLengthPolicy[index].MaxCount <= 0)
continue;
if (JobLengthPolicy[index].MinLength <= 0)
continue;
if (JobLengthPolicy[index].MaxLength <= 0)
continue;
if (Job[jindex].SpecWCLimit[0] < JobLengthPolicy[index].MinLength)
continue;
if (Job[jindex].SpecWCLimit[0] > JobLengthPolicy[index].MaxLength)
continue;
JobLengthPolicy[index].Count++;
} /* END for (index) */
} /* END for (jindex) */
DBG(8,fSCHED) DPrint("INFO: local policies initialized\n");
for (index = 0;index < MAX_LOCAL_JOB_POLICIES;index++)
{
DBG(4,fSCHED) DPrint("INFO: local policy joblength[%d] initialized: %d of %d jobs%s (%ld -> %ld)\n",
index + 1,
JobLengthPolicy[index].Count,
JobLengthPolicy[index].MaxCount,
(JobLengthPolicy[index].Count >= JobLengthPolicy[index].MaxCount) ? "*" : "",
JobLengthPolicy[index].MinLength,
JobLengthPolicy[index].MaxLength);
}
return(SUCCESS);
} /* END if (J == NULL) */
TRAPJOB(J,"LocalCheckFairnessPolicies");
if ((MaxSmallJobCount > 0) && (MaxSmallJobProcs > 0))
{
/* count active small jobs */
if (SmallJobCount >= MaxSmallJobCount)
{
DBG(3,fSCHED) DPrint("INFO: local policy 'MaxSmallJob' would be violated, rejecting job %s\n",
J->Name);
if (Message != NULL)
{
}
return(FAILURE);
}
}
else
{
DBG(8,fSCHED) DPrint("INFO: local policy 'MaxSmallJob' disabled (MaxCount: %d MaxProcs: %d/MaxNodes: %d)\n",
MaxSmallJobCount,
MaxSmallJobProcs,
MaxSmallJobNodes);
}
for (index = 0;index < MAX_LOCAL_JOB_POLICIES;index++)
{
if (JobLengthPolicy[index].MaxCount <= 0)
continue;
if (JobLengthPolicy[index].MinLength <= 0)
continue;
if (JobLengthPolicy[index].MaxLength <= 0)
continue;
if (J->SpecWCLimit[0] < JobLengthPolicy[index].MinLength)
continue;
if (J->SpecWCLimit[0] > JobLengthPolicy[index].MaxLength)
continue;
if (JobLengthPolicy[index].Count < JobLengthPolicy[index].MaxCount)
{
JobLengthPolicy[index].Count++;
break;
}
else
{
DBG(4,fSCHED) DPrint("INFO: job %s would violate local policy 'JobLength' (%ld <= %ld <= %ld) MaxCount: %d)\n",
J->Name,
JobLengthPolicy[index].MinLength,
J->SpecWCLimit[0],
JobLengthPolicy[index].MaxLength,
JobLengthPolicy[index].MaxCount);
if (Message != NULL)
{
}
return(FAILURE);
}
} /* END for (index) */
/* all local policies passed */
return(SUCCESS);
} /* END ContribJobLengthFairnessPolicy() */
/* END JobLength.c */