So Im just wondering about a few tips on doing a scheduler simulation.
So far, I just want to input a file at the command line i.e. /.scheduler in.file
The in.file holds the following information:
./Job1.txt
./Job2.txt
./Job3.txt
./Job4.txt
Each Job .txt file has random lines of code. With only the first line being significant. The first line is starting 'tick' time.
Job A:
10
1fi
3sdkfj
4ksdkk
5kdkfk
6kdkjf
7dkjkfd
9dkkf
10dku
At the moment I just want to take the in.file and order the 'Job' files in order of their arrival tick time i.e. first line.
My code thus far:
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "projscheduler.h"
/* I/O Files */
//static char *inputFile;
char * in;
static FILE *input;
/*Scheduled jobs indexed by PID*/
struct job list[20];
/* the next job to schedule */
//static struct job *job_next = NULL;
/* Time */
time clock;
/*Initialises job list*/
static void initialise_list(void) {
for(int i = 0; i < sizeof(list)/sizeof(list[0]); i++) {
list[i].parameters.pid = -1;
}
}
/** Read and parse input from input file */
static void parse_input(void)
{
char buffer[BUFSIZ];
//int jobs;
initialise_list();
while( fgets(buffer, sizeof(buffer), input) )
{
pid j_pid;
sscanf(buffer, "./%d.txt", &j_pid);
}
}
int main(int argc, char **argv)
{
if ( (input = fopen(in, "r")) == NULL ) {
fprintf(stderr, "cannot open %s\n", argv[1]);
}
parse_input();
return EXIT_SUCCESS;
}
HEADER FILE:
/**
* Simulation of a process scheduler
*/
//#ifndef SCHEDULER_H_
#define SCHEDULER_H_
#include <stddef.h>
/* types */
/** units of time */
typedef long time;
/** process identifier */
typedef int pid;
/** Information about a job of interest to the task scheduler */
struct job_data {
/* pid of this process */
pid pid;
/* time process starts */
time start;
/* time needed to finish */
time finish;
/* time spent processing so far */
time scheduled;
/* size of the process */
size_t size;
};
struct job {
/* Various parameters used by the scheduler */
char job_name[BUFSIZ];
struct job_data parameters;
/* next job to be scheduled */
//struct job *next;
};
I am unsure what problems you are having exactly but I can see the following errors in the code:
In the initialise_list() function the for loop will be iterating too many times and going beyond the bounds the of array:
for(int i = 0; i < sizeof(list); i++) {
as sizeof(list) will return the number of bytes occupied by the array which is 20 * sizeof(struct job). Change to:
for(int i = 0; i < sizeof(list) / sizeof(list[0]); i++) {
this is a missing left parenthesis from fopen() attempt (meaning the posted code does not compile):
if( (input = fopen(inputfile, "r") == NULL )
should be:
if( (input = fopen(inputfile, "r")) == NULL )
proj is an initialised char* and this will mostly likely cause a segmentation fault:
char *proj;
sscanf(buffer, "./%s.txt", proj);
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include "projscheduler.h"
/* I/O Files */
//static char *inputFile;
char * in;
static FILE *input;
static FILE *cur;
/*Scheduled jobs indexed by PID*/
struct job list[20];
/* the next job to schedule */
//static struct job *job_next = NULL;
/* Time */
time clock;
/*Initialises job list*/
static void initialise_list(void) {
for(int i = 0; i < sizeof(list)/sizeof(list[0]); i++) {
list[i].parameters.pid = -1;
}
}
/*Order Jobs*/
/*=static void order_jobs(void)
{
for(int i=0; i < sizeof(list)/sizeof(list[0]); i++)
{
}
*/
/** Read and parse input from input file */
static void parse_input(void)
{
char buffer[BUFSIZ];
char lines[BUFSIZ];
int jobs = 0;
struct job *current;
initialise_list();
while( fgets(buffer, sizeof(buffer), input) )
{
time start;
char buf[20];
sscanf(buffer,"./%s/", buf);
cur = fopen(buf, "r" );
fgets(lines, sizeof(lines), cur);
sscanf(lines,"%ld", &start);
current = &list[jobs];
current->job_id = buf;
current->parameters.start = start;
jobs++;
}
for (int i = 0; i < jobs; i++)
{
printf("%s starts at %ld\n", list[i].job_id, list[i].parameters.start);
}
}
int main(int argc, char **argv)
{
in = argv[1];
if ( (input = fopen(in, "r")) == NULL ) {
fprintf(stderr, "cannot open %s\n", argv[1]);
}
parse_input();
return EXIT_SUCCESS;
}
Above, I successfully read the in.file and extracted the first line from each address representing a text file.
Code above associated with following header:
/**
* Simulation of a process scheduler
*/
//#ifndef SCHEDULER_H_
#define SCHEDULER_H_
#include <stddef.h>
/* types */
/** units of time */
typedef long time;
/** process identifier */
typedef int pid;
/** Information about a job of interest to the task scheduler */
struct job_data {
/* pid of this process */
pid pid;
/* time process starts */
time start;
/* time needed to finish */
time finish;
/* time spent processing so far */
time scheduled;
/* size of the process */
size_t size;
};
struct job {
/* Various parameters used by the scheduler */
char * job_id;
struct job_data parameters;
/* next job to be scheduled */
//struct job *next;
};
Related
I'm trying to build an ancient version of the ls command (written in pre-ANSI/ISO C). But I'm getting a lot of warnings, which for most of these I can fix, however I also get a few errors. This is one of them: error: conflicting types for ‘malloc’; have ‘char *()’
This is the affected part of the program:
static char sccsid[] = "#(#)ls.c 1.21";
/*
* list file or directory;
* define DOTSUP to suppress listing of files beginning with dot
*/
#include <sys/param.h>
#include <sys/types.h>
#include <sys/sysmacros.h>
#include <sys/stat.h>
#include <sys/dir.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef STANDALONE
#define TERMINFO
#endif
/* -DNOTERMINFO can be defined on the cc command line to prevent
* the use of terminfo. This should be done on systems not having
* the terminfo feature (pre 6.0 sytems ?).
* As a result, columnar listings assume 80 columns for output,
* unless told otherwise via the COLUMNS environment variable.
*/
#ifdef NOTERMINFO
#undef TERMINFO
#endif
#ifdef TERMINFO
#include <curses.h>
#include <term.h>
#endif
#define DOTSUP 1
#define ISARG 0100000 /* this bit equals 1 in lflags of structure lbuf
* if *namep is to be used;
*/
#define DIRECT 10 /* Number of direct blocks */
#ifdef u370
/* Number of pointers in an indirect block */
#define INDIR (BSIZE/sizeof(daddr_t))
/* Number of right shifts to divide by INDIR */
#define INSHFT 10
#else
/* Number of pointers in an indirect block */
#define INDIR 128
/* Number of right shifts to divide by INDIR */
#define INSHFT 7
#endif
struct lbuf {
union {
char lname[DIRSIZ]; /* used for filename in a directory */
char *namep; /* for name in ls-command; */
} ln;
char ltype; /* filetype */
unsigned short lnum; /* inode number of file */
short lflags; /* 0777 bits used as r,w,x permissions */
short lnl; /* number of links to file */
unsigned short luid;
unsigned short lgid;
long lsize; /* filesize or major/minor dev numbers */
long lmtime;
};
struct dchain {
char *dc_name; /* path name */
struct dchain *dc_next; /* next directory in the chain */
};
struct dchain *dfirst; /* start of the dir chain */
struct dchain *cdfirst; /* start of the durrent dir chain */
struct dchain *dtemp; /* temporary - used for linking */
char *curdir; /* the current directory */
int nfiles = 0; /* number of flist entries in current use */
int nargs = 0; /* number of flist entries used for arguments */
int maxfils = 0; /* number of flist/lbuf entries allocated */
int maxn = 0; /* number of flist entries with lbufs assigned */
int quantn = 1024; /* allocation growth quantum */
struct lbuf *nxtlbf; /* pointer to next lbuf to be assigned */
struct lbuf **flist; /* pointer to list of lbuf pointers */
struct lbuf *gstat();
FILE *pwdfu, *pwdfg, *dirf;
int aflg, bflg, cflg, dflg, fflg, gflg, iflg, lflg, mflg;
int nflg, oflg, pflg, qflg, sflg, tflg, uflg, xflg;
int Cflg, Fflg, Rflg;
int rflg = 1; /* initialized to 1 for special use in compar() */
int flags;
int err = 0; /* Contains return code */
char *dmark; /* Used if -p option active. Contains "/" or NULL. */
unsigned lastuid = -1, lastgid = -1;
int statreq; /* is > 0 if any of sflg, (n)lflg, tflg are on */
char *dotp = ".";
char *makename();
char tbufu[16], tbufg[16]; /* assumed 15 = max. length of user/group name */
char *ctime();
long nblock();
long tblocks; /* total number of blocks of files in a directory */
long year, now;
int num_cols = 80;
int colwidth;
int filewidth;
int fixedwidth;
int curcol;
int compar();
int new_line()
{
if (curcol) {
putc('\n',stdout);
curcol = 0;
}
}
int pprintf(char *s1, char *s2)
{
register char *s;
register int c;
register int cc;
int i;
for (s = s1, i = 0; i < 2; i++, s = s2)
while(c = *s++) {
if (c < ' ' || c >= 0177) {
if (qflg)
c = '?';
else if (bflg) {
curcol += 3;
putc ('\\', stdout);
cc = '0' + (c>>6 & 07);
putc (cc, stdout);
cc = '0' + (c>>3 & 07);
putc (cc, stdout);
c = '0' + (c & 07);
}
}
curcol++;
putc(c, stdout);
}
}
/*
* pdirectory: print the directory name, labelling it if title is
* nonzero, using lp as the place to start reading in the dir.
*/
int pdirectory (char *name, int title, int lp)
{
register struct dchain *dp;
register struct lbuf *ap;
register char *pname;
register int j;
filewidth = 0;
curdir = name;
if (title) {
putc('\n', stdout);
pprintf(name, ":");
new_line();
}
nfiles = lp;
readdir(name);
if (fflg==0)
qsort(&flist[lp],(unsigned)(nfiles - lp),sizeof(struct lbuf *),compar);
if (Rflg) for (j = nfiles - 1; j >= lp; j--) {
ap = flist[j];
if (ap->ltype == 'd' && strcmp(ap->ln.lname, ".") &&
strcmp(ap->ln.lname, "..")) {
dp = (struct dchain *)calloc(1,sizeof(struct dchain));
if (dp == NULL)
fprintf(stderr,"ls: out of memory\n");
pname = makename(curdir, ap->ln.lname);
dp->dc_name = (char *)calloc(1,strlen(pname)+1);
if (dp->dc_name == NULL) {
fprintf(stderr,"ls: out of memory\n");
free(dp);
}
else {
strcpy(dp->dc_name, pname);
dp -> dc_next = dfirst;
dfirst = dp;
}
}
}
if (lflg || sflg)
curcol += printf("total %ld", tblocks);
pem(&flist[lp],&flist[nfiles],lflg||sflg);
}
int main(int argc, char **argv)
{
extern char *optarg;
extern int optind;
int amino, opterr=0;
int c;
register struct lbuf *ep;
struct lbuf lb;
int i, width;
long time();
char *malloc();
void qsort(), exit();
malloc is declared in stdlib.h as :
void *malloc(size_t size);
You code wrongly re-declares it as:
char *malloc();
Remove the wrong re-declaration and review use of malloc() carefully.
I have currently made this much of the code:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <ctype.h>
#define STRSIZE 21
struct PInven{
int count;
struct PItem{
char name[STRSIZE];
int amount;
}Pitem;
}Pinven;//this needs to be an output file
int ReadInProduce (){
//read in file and check to see if the file exist or not.
FILE * PinFile = fopen("produce.txt","r");
if (PinFile == NULL){
printf("ERROR: WRONG FILE");
}
else{
printf("I did it!!\n");
}
//assigning the value gotten into the struct variable(but need to maybe change this since it needs to be an output)
fscanf(PinFile,"%d",&Pinven.count);
printf("%d\n", Pinven.count);
int i;
for(i =0; i <Pinven.count; i++){
fscanf(PinFile,"%20s %d",Pinven.Pitem.name, &Pinven.Pitem.amount);
printf("%s %d\n",Pinven.Pitem.name, Pinven.Pitem.amount);
}
//making an array to hold the variables
//FILE * PoutFile = fopen("produce_update.txt","w");
fclose(PinFile);
return 0;
}
From there I want to get the file that is read to the structs to be printed out into an array so that later on I can make a function that will be able to compare to the to it.
Basically a store management system. Where the file of the inventory is read in and compared to the file that is store and return a new value for the amount of produce now either left or gained.
10 //number of items that will be stored in the store
apple 19
banana 31
broccoli 9
...
In general, it's a really bad idea to include header information in the file about the number of entries in the file. You want to be able to do stream processing, and that will be more difficult if you need that meta-data. More importantly, it is important to understand how to write the code so that you don't need it. It's not really that difficult, but for some reason people avoid it. One simple approach is just to grow the array for each entry. This is horribly inefficient, but for the sake of simplicity, here's an example that expects the file not not include that first line:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <ctype.h>
#include <limits.h>
#define STRSIZE 128
struct PItem{
char name[STRSIZE];
int amount;
};
struct PInven{
int count;
struct PItem *PItem;
};
static void
grow(struct PInven *p)
{
p->PItem = realloc(p->PItem, ++p->count * sizeof *p->PItem);
if( p->PItem == NULL ){
perror("out of memory");
exit(1);
}
}
int
ReadInProduce(struct PInven *P, const char *path)
{
FILE * PinFile = fopen(path, "r");
if( PinFile == NULL ){
perror(path);
exit(1);
}
char fmt[64];
int max_len;
max_len = snprintf(fmt, 0, "%d", INT_MAX);
snprintf(fmt, sizeof fmt, "%%%ds %%%dd", STRSIZE - 1, max_len - 1);
grow(P);
struct PItem *i = P->PItem;
while( fscanf(PinFile, fmt, i->name, &i->amount) == 2 ){
i += 1;
grow(P);
}
P->count -= 1;
fclose(PinFile); /* Should check for error here! */
return P->count;
}
int
main(int argc, char **argv)
{
struct PInven P = {0};
char *input = argc > 1 ? argv[1] : "produce.txt";
ReadInProduce(&P, input);
struct PItem *t = P.PItem;
for( int i = 0; i < P.count; i++, t++ ){
printf("%10d: %s\n", t->amount, t->name);
}
}
As an exercise for the reader, you should add some error handling. At the moment, this code simply stops reading the input file if there is bad input. Also, it would be a useful exercise to do fewer reallocations.
you should change Structure of PInven to it can save a dynamic array of Pitem with a Pitem pointer.
tested :
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#define STRSIZE 21
typedef struct {
char name[STRSIZE];
int amount;
} Pitem;
struct PInven {
int count;
Pitem *pitem;
} Pinven; // this needs to be an output file
int main() {
// read in file and check to see if the file exist or not.
FILE *PinFile = fopen("produce.txt", "r");
if (PinFile == NULL) {
printf("ERROR: WRONG FILE");
} else {
printf("I did it!!\n");
}
// assigning the value gotten into the struct variable(but need to maybe
// change this since it needs to be an output)
fscanf(PinFile, "%d", &Pinven.count);
Pinven.pitem = (Pitem *)malloc(sizeof(Pitem) * Pinven.count);
printf("%d\n", Pinven.count);
int i;
for (i = 0; i < Pinven.count; i++) {
fscanf(PinFile, "%20s %d", Pinven.pitem[i].name,
&Pinven.pitem[i].amount);
// printf("%s %d\n",Pinven.pitem[i].name, Pinven.pitem[i].amount);
}
for (i = 0; i < Pinven.count; i++) {
printf("%s %d\n", Pinven.pitem[i].name, Pinven.pitem[i].amount);
}
// making an array to hold the variables
// FILE * PoutFile = fopen("produce_update.txt","w");
fclose(PinFile);
// remember free
free(Pinven.pitem);
return 0;
}
I am creating a struct called Job and I want to create an array of struct Job. The name of my array is jobQueue I populate the array using commandline args. The instructor has it set up to where **args is being used. After the user inputs the name of the job and the execution time it gets added to the array. However, when I try to print jobQueue[0].name using the list() funct I have written, the name does not get printed. I'm trying to get my code set up to where I can print the name. I have provided a minimal version of my overall project that just focuses on the specific problem I am encountering and should compile and run fine.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <assert.h>
#include <sys/wait.h>
#include <stdint.h>
#define EINVAL 1
#define E2BIG 2
#define MAXMENUARGS 7
//structure job initialize
struct Job {
//initializing name variable
char *name;
int executionTime;
};
//init the array
struct Job jobQueue[5] = {0};
//cmd function provided by intructor
int cmd_run(int nargs, char **args) {
int execT;
sscanf(args[2], "%d", &execT);
run(args[1], execT);
return 0;
}
//cmd function provided by intructor
void cmd_list() {
list();
}
//cmd function provided by intructor
static struct {
const char *name;
int (*func)(int nargs, char **args);
} cmdtable[] = {
/* commands: single command must end with \n */
{ "r", cmd_run},
{ "run", cmd_run},
{ "list\n", cmd_list}
};
//cmd function provided by intructor
//this is the function that handles the arguments entered by the user
//provided it just in case someone needs to see how arguments are being
//processed
int cmd_dispatch(char *cmd) {
time_t beforesecs, aftersecs, secs;
u_int32_t beforensecs, afternsecs, nsecs;
char *args[MAXMENUARGS];
int nargs = 0;
char *word;
char *context;
int i, result;
void *Dispatcher(void *arg);
for (word = strtok_r(cmd, " ", &context);
word != NULL;
word = strtok_r(NULL, " ", &context)) {
if (nargs >= MAXMENUARGS) {
printf("Command line has too many words\n");
return E2BIG;
}
args[nargs++] = word;
}
if (nargs == 0) {
return 0;
}
for (i = 0; cmdtable[i].name; i++) {
if (*cmdtable[i].name && !strcmp(args[0], cmdtable[i].name)) {
assert(cmdtable[i].func != NULL);
/* Call function through the cmd_table */
result = cmdtable[i].func(nargs, args);
return result;
}
}
printf("%s: Command not found\n", args[0]);
return EINVAL;
}
//adds job to the array using user arguments
void run(char name[], int executionTime) {
//creates a job using the arguments specified by user
struct Job job = {name, executionTime};
jobQueue[0] = job;
printf("\nJob added to queue now please type 'list'\n");
}
//name will not print here
void list() {
printf("\nSee how the name will not print below?\n");
char executionTimeStr[5];
for (int c = 0; c < sizeof (jobQueue) / sizeof (jobQueue[0]); c++) {
//prints job info formatted
if (jobQueue[c].name != NULL) {
sprintf(executionTimeStr, "%d", jobQueue[c].executionTime);
//job name will not print here, output is just left blank
printf("%s %20.8s", "Name", "ExecTime");
printf("%-10.15s %11.3s\n",
jobQueue[c].name,
executionTimeStr
);
}
}
}
int main(int argc, char *argv[]) {
printf("Welcome to our batch job scheduler\n");
printf("Please enter the following exactly: 'run job1 10' \n");
//ignore this, it handles my commandline parser
char *buffer;
size_t bufsize = 64;
buffer = (char*) malloc(bufsize * sizeof (char));
if (buffer == NULL) {
perror("Unable to malloc buffer");
exit(1);
}
while (1) {
printf("User Input: ");
getline(&buffer, &bufsize, stdin);
cmd_dispatch(buffer);
}
//ignore this, it handles my commandline parser
return 0;
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
#include <dirent.h>
#include <pthread.h>
#include <string.h>
#include <stdio.h>
#include <semaphore.h>
int file_index = 0; // index for array[500];
struct webData {
char web_names [255];
};
void *thread(void *wData_element)
{
struct webData *temp = wData_element;
FILE *fp;
char line[255]=""; // hold each line;
fp = fopen(temp->web_names, "r");
if(fp == NULL)
{
perror("Error: File open failure.");
}
else
{
fgets(line,255, fp);
printf("%s\n", line);
}
fclose(fp);
return NULL;
}
int main(int argc, char const* argv[])
{
DIR * dir_pointer; // define a dir pointer;
struct dirent * entry; // entry under dir;
//char *dir = "./data/";
dir_pointer = opendir("./data/"); // assign dir location into dir pointer
// declare the struct wData array for each file.
struct webData wData[500];
// declare the threads array.
pthread_t tid_array[500];
while( (entry = readdir(dir_pointer)) != NULL)
{
if(entry->d_type == DT_REG) // avoid the . and .. dir;
{
char full_path[255];
full_path[0] = '\0'; // initilize the string;
strcat(full_path, "./data/"); // concatenate file directory;
strcat(full_path, entry->d_name); // concatenate filename;
strcpy(wData[file_index].web_names, full_path); // store file name into web_names array;
pthread_create(&tid_array[file_index], NULL, thread, &wData[file_index]);
file_index++; // increase the file index for next file.
}
}
for(int i=0; i<500; i++)
{
pthread_join(tid_array[i], NULL);
}
return 0;
}
For this program:
There are 500 files in the data folder.
For each file, I create a thread to do some action on the file.
After I iterate all 500 files. I join all the threads.
My question is:
How can I create 10 threads, and each thread does some action on exact 50 files?
How can I make sure each thread only handle 50 files since they are running concurrently?
For example:
thread 1 handles files number from 1-50
thread 2 handles files number from 51-100
.
.
.
Thanks a lot for any related source or example.
First you declare a parameter-struct for the threads
typedef struct thread_param_s {
// each thread will get an array of webData-files
struct webData* data;
// number of elements
int n;
} thread_param_t;
You create this param-struct for each thread, fill it accordingly and pass it in pthread_create instead of the wData*
Now you adjust your current code
#include <dirent.h>
#include <pthread.h>
#include <string.h>
#include <stdio.h>
#include <semaphore.h>
int file_index = 0; // index for array[500];
struct webData {
char web_names [255];
};
void *thread(void *param)
{
thread_param_t* thread_param = (thread_param_t*)param;
int i;
// iterate through all files
for (i = 0; i < thread_param->n; i++) {
struct webData *temp = thread_param->data + i;
FILE *fp;
char line[255]=""; // hold each line;
fp = fopen(temp->web_names, "r");
if(fp == NULL)
{
perror("Error: File open failure.");
}
else
{
fgets(line,255, fp);
printf("%s\n", line);
}
}
return NULL;
}
int main(int argc, char const* argv[])
{
DIR * dir_pointer; // define a dir pointer;
struct dirent * entry; // entry under dir;
//char *dir = "./data/";
dir_pointer = opendir("./data/"); // assign dir location into dir pointer
// declare the struct wData array for each file.
struct webData wData[500];
// declare the threads array.
while( (entry = readdir(dir_pointer)) != NULL)
{
if(entry->d_type == DT_REG) // avoid the . and .. dir;
{
char full_path[255];
full_path[0] = '\0'; // initilize the string;
strcat(full_path, "./data/"); // concatenate file directory;
strcat(full_path, entry->d_name); // concatenate filename;
strcpy(wData[file_index].web_names, full_path); // store file name into web_names array;
file_index++; // increase the file index for next file.
// just fill wData here
}
}
pthread_t tid_array[10];
thread_param_t thread_param[10];
int thread_counter = 0;
// number of files for each thread
int step = file_index / 10;
int i;
// create all threads
for(i = 0; i < 9; i++)
{
thread_param[i].n = step;
thread_param[i].data = wData + step * i;
pthread_create(&tid_array[i], NULL, thread, thread_param + i);
}
// the last thread may get more data, because of integer rounding
thread_param[i].n = file_index - step * i;
thread_param[i].data = wData + step * i;
pthread_create(&tid_array[i], NULL, thread, thread_param + i);
for(int i=0; i<10; i++)
{
pthread_join(tid_array[i], NULL);
}
return 0;
}
Below is my code:
I cant seem to use qsort effectively... It turns my array into 0's after they are populated with names and start times... Is it a problem with my qsort call? or the qsort itself.
The header with the structures is as follows:
/**
* Simulation of a process scheduler
*/
//#ifndef SCHEDULER_H_
#define SCHEDULER_H_
#include <stddef.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
/* types */
/** units of time */
typedef long time;
/** process identifier */
typedef int pid;
/** Information about a job of interest to the task scheduler */
struct job_data {
/* pid of this process */
pid pid;
/* time process starts */
time start;
/* time needed to finish */
time finish;
/* time spent processing so far */
time scheduled;
/* Number of lines */
int lines;
};
struct job {
/* Various parameters used by the scheduler */
char job_id[20];
struct job_data parameters;
char *lines[20];
};
/* I/O Files */
//static char *inputFile;
char * in;
static FILE *input;
static FILE *cur;
/*Scheduled jobs indexed by PID*/
struct job list[20];
/* the next job to schedule */
//static struct job *job_next = NULL;
/* Time */
time clock;
/*Comparison for qsort*/
int compare_start(const void *x, const void *y)
{
const struct job *a = x;
const struct job *b = y;
printf("%ld, %ld\n", a->parameters.start, b->parameters.start);
if (a->parameters.start < b->parameters.start)
{
return -1;
}
if (a->parameters.start > b->parameters.start)
{
return 1;
}
return 0;
}
/*Order Jobs*/
static void order_jobs(void)
{
qsort(list, (sizeof list) / (sizeof list[0]), sizeof list[0], compare_start);
}
/** Read and parse input from input file */
static void parse_input(void)
{
char buffer[BUFSIZ];
char lines[BUFSIZ];
int jobs = 0;
struct job *current;
while( fgets(buffer, sizeof(buffer), input) )
{
time start;
char buf[BUFSIZ];
sscanf(buffer,"./%s/", buf);
cur = fopen(buf, "r" );
int n_lines = 0;
while( fgets(lines, sizeof(lines), cur) )
{
if( n_lines == 0 )
{
current = &list[jobs];
strcpy(current->job_id, buf);
sscanf(lines,"%ld", &start);
current->parameters.start = start;
}
n_lines++;
}
current->parameters.lines = n_lines;
jobs++;
fclose(cur);
}
order_jobs();
for (int i = 0; i < jobs; i++)
{
printf("%s %ld %d\n", list[i].job_id, list[i].parameters.start, list[i].parameters.lines);
}
}
int main(int argc, char **argv)
{
in = argv[1];
if ( (input = fopen(in, "r")) == NULL ) {
fprintf(stderr, "cannot open %s\n", argv[1]);
}
parse_input();
fclose(input);
return EXIT_SUCCESS;
}
You only load jobs entries into the array, but you tell qsort() to sort the entire array (20 elements). This probably puts non-initialized elements at the front, which you then print.