📄 qschedule.c
字号:
if (job->comment == NULL) { return (-1); } changed ++; continue; } /* Modified time attribute. */ if (!strcmp(attr->name, ATTR_mtime)) { /* When was the job last modified? */ job->mtime = atoi(attr->value); continue; } if (!strcmp(attr->name, ATTR_l)) { if (!strcmp(attr->resource,"arch")) { job->arch = schd_strdup(attr->value); changed ++; } else if (!strcmp(attr->resource,"mem")) { job->memory = schd_val2byte(attr->value); changed ++; } else if (!strcmp(attr->resource,"ncpus")) { job->ncpus = atoi(attr->value); changed ++; } else if (!strcmp(attr->resource, "walltime")) { job->walltime = schd_val2sec(attr->value); changed ++; } /* That's all for requested resources. */ continue; } if (!strcmp(attr->name, ATTR_used)) { if (!strcmp(attr->resource, "walltime")) { job->walltime_used = schd_val2sec(attr->value); changed ++; } /* No other interesting cases. */ continue; } } /* * If this job is "Running" compute how * many seconds remain until it is completed. */ if (job->state == 'R' || job->state == 'S') job->time_left = job->walltime - job->walltime_used; return (changed);}void create_job_schedule(Job *joblist){ char *id = "create_job_schedule"; Job *job_ptr, *this; int i; /* * Destroy any previously created list. */ if (JobSchedule) free(JobSchedule); JobSchedule = NULL; nJobSchedule = 0; /* * Walk the list of jobs, adding Start and End entries * to the global JobSchedule table along the way. */ for (this = joblist; this != NULL; this = this->next) { /* Start Entry */ ++nJobSchedule; JobSchedule = realloc(JobSchedule, nJobSchedule * sizeof *JobSchedule); if (!JobSchedule) { return; } JobSchedule[nJobSchedule -1].event = 'S'; JobSchedule[nJobSchedule -1].time = this->mtime; JobSchedule[nJobSchedule -1].cpu = this->ncpus; JobSchedule[nJobSchedule -1].mem = this->memory; JobSchedule[nJobSchedule -1].walltime = this->walltime + 2*60; if (this->arch) strcpy(JobSchedule[nJobSchedule -1].qname, this->arch); else strcpy(JobSchedule[nJobSchedule -1].qname, ""); /* End Entry */ ++nJobSchedule; JobSchedule = realloc(JobSchedule, nJobSchedule * sizeof *JobSchedule); if (!JobSchedule) { return; } JobSchedule[nJobSchedule -1].event = 'E'; JobSchedule[nJobSchedule -1].time = this->mtime + this->walltime; JobSchedule[nJobSchedule -1].cpu = this->ncpus; JobSchedule[nJobSchedule -1].mem = this->memory; JobSchedule[nJobSchedule -1].walltime = 0; if (this->arch) strcpy(JobSchedule[nJobSchedule -1].qname, this->arch); else strcpy(JobSchedule[nJobSchedule -1].qname, ""); } /* now sort the table into chronological order */ qsort(JobSchedule, nJobSchedule, sizeof *JobSchedule, compare_qtime); return;}void schd_print_schedule(){ int i; /* print Schedule for sanity check */ for (i=0; i<nJobSchedule; i++) { printf("%c %ld %d cpus %ld(b)memory %ld arch=%s\n", JobSchedule[i].event, JobSchedule[i].time, JobSchedule[i].cpu, schd_byte2val(JobSchedule[i].mem), JobSchedule[i].walltime, JobSchedule[i].qname); }}/* * qsort() function to order Job Schedule * * Order Job Schedule by date/time stamp of events, * descending by number of seconds queued */static intcompare_qtime(const void *e1, const void *e2){ struct Sinfo *ent1 = (struct Sinfo*)e1; struct Sinfo *ent2 = (struct Sinfo*)e2; if (ent1->time > ent2->time) return 1; if (ent1->time < ent2->time) return -1; return 0;}/* Power-of-two unit multipliers. */#define KILO ((size_t)1024)#define MEGA (KILO*1024)#define GIGA (MEGA*1024)#define TERA (GIGA*1024)/* * byte2val(bytes) * * Return a pointer to a static string that is the shortest string by which * the number of bytes can be accurately represented. i.e.: * * 1023 -> 1023b * 16384 -> 16kb * 1048576 -> 1mb * 16777216 -> 16mb * 16777217 -> 16777217b * 34359738368 -> 32gb */char *schd_byte2val(size_t bytes){ int log_1024 = 0; /* logarithm base 1024 of multiplier */ size_t mult = 1; /* Initial multiplier */ size_t next_mult = 1024; /* multiplier of next-highest unit */ static char string[32]; char *units[] = { "b", /* bytes */ "kb", /* kilobytes */ "mb", /* megabytes */ "gb", /* gigabytes */ "tb", /* terabytes */ "pb", /* petabytes */ "eb" /* exabytes */ }; /* * Find the first multiplier by which the given byte count is not * evenly divisible. If we overflow the next multiplier, we have * gone far enough. */ while (bytes && (bytes % next_mult) == 0) { mult = next_mult; next_mult <<= 10; log_1024 ++; if (next_mult == 0) break; } /* * Make 'bytes' be the number of units being represented. */ bytes /= mult; /* * Create a string from number of units, and the symbol for that unit. */ sprintf(string, "%lu%s", bytes, units[log_1024]); /* * Remember: this is a static string! */ return (string);}/* * Convert seconds into "HH:MM:SS" format. Note that the returned string * is a pointer to a static buffer. The caller must copy the time string * into a holding buffer before the next call to sec2val() occurs. */char *schd_sec2val(int seconds){ /* char *id = "sec2val"; */ static char tval[16]; int hours = 0; int minutes = 0; /* Hours */ if (seconds >= (60 * 60)) hours = seconds / (60 * 60); seconds -= (hours * (60 * 60)); /* Minutes */ if (seconds >= 60) minutes = seconds / 60; /* Seconds */ seconds -= (minutes * 60); (void)sprintf(tval, "%2.2d:%2.2d:%2.2d", hours, minutes, seconds); return (&tval[0]);}/* Convert an allocation value string to its equivalent value in bytes. */size_t schd_val2byte(char *val){ char *id = "schd_val2byte"; int b = 0; size_t num = 0; char *p; if (val == NULL) return (0); if (val[0] == '?') { fprintf(stderr, "error from getreq(physmem): %s: [%d, %d]", val, pbs_errno, errno); return (0); } b = 0; num = 0; num = strtoul(val, &p, 0); /* Now 'p' should point to first non-number character. */ /* If no units given, return the number. */ if ((p == val) || (*p == '\0')) return (num); /* XXX return num if p == val? */ /* Parse the given order of magnitude. */ switch (*p) { case 'k': case 'K': num *= KILO; break; case 'm': case 'M': num *= MEGA; break; case 'g': case 'G': num *= GIGA; break; case 't': case 'T': num *= TERA; break; case 'b': case 'B': b++; break; default: return (-1); } /* XXX if (b && *p != '\0') return error. */ /* Parse the word-size unit. */ p++; if ((*p != '\0') && !b) { switch (*p) { case 'b': case 'B': break; case 'w': case 'W': num *= NBPW; /* Multiply by size of word. */ break; default: return (-1); } } /* Return the total number of bytes represented by the value. */ return (num);}/* * Convert a value string from time to its equivalent value in seconds. */time_t schd_val2sec(char *val){ char *id = "val2sec"; char *p1, *p2, *p3, *end, *zero = "0"; time_t v1, v2, v3; time_t sec; char *valcopy; p3 = NULL; valcopy = schd_strdup(val); if (valcopy == NULL) { fprintf(stderr, "ERROR: schd_strdup(val) failed."); return ((time_t) -1); } /* Split string into at most 3 tokens. */ p1 = strtok(valcopy, ":"); p2 = strtok(NULL, ":"); if (p2 != NULL) { p3 = strtok(NULL, ":"); } /* Only seconds specified. Shift right 2 places into p3, and zero fill */ if (p2 == NULL) { p3 = p1; p2 = zero; p1 = zero; } /* Minutes and seconds specified. Shift right into p3, and zero fill */ if (p3 == NULL) { p3 = p2; p2 = p1; p1 = zero; } v1 = (time_t)strtol(p1, &end, 10); if (*end != '\0') goto error; if (v1 < 0) goto error; v2 = (time_t)strtol(p2, &end, 10); if (*end != '\0') goto error; if (v2 < 0 || v2 > 59) goto error; v3 = (time_t)strtol(p3, &end, 10); if (*end != '\0') goto error; if (v3 < 0 || v3 > 59) goto error; free (valcopy); sec = (v1 * 3600) + (v2 * 60) + v3; return (sec);error: fprintf(stderr, "Can't parse time '%s' into seconds.\n", val); free(valcopy); return ((time_t) -1);}#define DATEFMT "%m/%d/%Y@%H:%M:%S" /* MM/DD/YYYY@HH:MM:SS *//* * Convert a string of the form MM/DD/YYYY@HH:MM:SS to a time_t. Uses * strptime(3) function for parsing. */intschd_val2datetime(char *string, time_t *when){ /* char *id = "get_datetime"; */ char *remain; struct tm tm; time_t then; /* Call the "inverse" of strftime(3) to parse the string. */ remain = strptime(string, DATEFMT, &tm); /* Check for successful parsing of the date string in DATEFMT. */ if (remain == NULL) return -1; /* Make sure the date@time was the only thing in the string. */ if (*remain != '\0' && !isspace(*remain)) return -1; /* * The struct tm now contains the right information. Turn it into a * valid time_t. */ then = mktime(&tm); if (then == (time_t) -1) return -1; /* Copy the time value and return success. */ *when = then; return 0;}/* * strdup(3) is not required for POSIX compliance, so we must provide a * "lookalike". */char *schd_strdup(char *string){ size_t length; char *copy; /* * Allocate new space for a copy of the string contents, and a * trailing '\0'. */ length = strlen(string) + 1; copy = malloc(length); if (copy == NULL) return (NULL); memcpy(copy, string, length); return(copy);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -