I am working on a uni assignment, which is to be done in C. This is my firs time programming in C, and I am VERY close to having a workable solution, but my code is throwing a Segmentation Fault during runtime and I simply cannot locate the cause.
Here is my code:
#include "./shared.h"
#include "./scheduler.h"
PCB_entry *ready_q ;
PCB_entry *ready_q_tail;
/*
* file name priority.c
*
* The functions in this file implement a "priority"
* scheduling scheme.
*
* Functions provided and brief descriptions:
*
* PCB_entry * schedule_next (void) - returns next process for CPU
*
* int insert_new (PCB_entry * proc) - insert new process into queue
*
* void list_q (void) - debugging function lists queue contents
*
* int re_insert (PCB_entry * proc, int run_time) - put process back
* into correct queue after a run on the CPU
*
* int init_q (void) - initialise queue(s)
*
*/
double pwr (double x, double y)
{
double i, p;
p = 1;
for (i = 1; i <= y; ++i){
p = p * x;
}
return p;
}
/*
* Function Schedule_next: priority
*
* Called by the central simulation system Returns a
* pointer to the PCB entry for the "process" that
* should be put on the CPU next
*
*/
PCB_entry *
schedule_next (void)
{
/* if ready_q is null, there are no processes in the system */
if (ready_q == NULL)
{
return NULL;
}
else
{
PCB_entry *next;
PCB_entry *best_proc;
next = ready_q;
best_proc = next;
while (next != NULL)
{ /* traverse to the end of the list */
if (next->current_priority < best_proc->current_priority) {
best_proc = next;
}
next = next->f_link;
}
if (best_proc == NULL) {
return NULL;
}
if (best_proc->b_link != NULL){
best_proc->b_link->f_link = best_proc->f_link;
if (best_proc->f_link != NULL) {
best_proc->f_link->b_link = best_proc->b_link;
}
} else {
ready_q = best_proc->f_link;
if (ready_q != NULL) /* don't try to de-reference a NULL
* pointer */
ready_q->b_link = NULL; /* first process in the queue
* always has a NULL back
* link */
best_proc->f_link = NULL; /* just to be tidy -- set both links
* in the PCB */
/* entry that will be returned to NULL */
best_proc->b_link = NULL;
}
return best_proc;
}
}
/*
* Function insert_new: Non-preemptive round-robin
*
* Insert a new "process" into the scheduling queue
*
* Accepts a pointer to a PCB entry that will be inserted
* into the queue returns either OK or NotOK to indicate
* success or failure
*
* Since this is FCFS priority scheduling, the new process is
* simply slotted in at the end of the queue
*
*/
int
insert_new (PCB_entry * proc)
{
if (ready_q == NULL)
{ /* no entries in table */
ready_q = proc; /* insert at the head of the list */
proc->b_link = NULL;
proc->f_link = NULL;
ready_q_tail = ready_q;
return OK;
}
else
{
ready_q_tail->f_link = proc; /* Set tail of list pointer */
proc->f_link = NULL; /* New tail of list to NULL */
proc->b_link = ready_q_tail; /* Set the b_link of the new process to previous last record of the list */
ready_q_tail = proc; /* Set the tail reference to the new pointer */
return OK;
}
#pragma error_messages (off,E_STATEMENT_NOT_REACHED)
return NotOK; /* this is not really needed, but is here to be defensive */
#pragma error_messages (on,E_STATEMENT_NOT_REACHED)
}
/*
* Function list_q
*
* Implementation of this function is optional but highly
* recommended
*/
void
list_q (void)
{
PCB_entry *next;
next = ready_q;
fprintf (stderr, "\n current state of the ready queue\n");
next = ready_q;
while (next != NULL)
{ /* traverse to the end of the list */
fprintf (stderr, "%d\t", next->pid);
next = next->f_link;
}
fprintf (stderr, "\n\n");
}
/*
* Function re_insert: priority
*
* a function to insert a process back into the queue
* following a run on the CPU. Depending on the
* scheduling algorithm chosen this would need to
* do a lot more. In a priority algorithm with boost
* and reduction, it would need to look at the
* percentage of the quantum that the process used
* and determine if a change to the priority was
* required. Also, in implementing a mulitlevel
* priority scheme, a variation of the ready_q
* pointer would be required. The simplest method
* would be an array of pointers with one element
* for each priority level.
*
* Not that, in this case it is identical to the
* insert_new code
*/
int
re_insert (PCB_entry * proc, int run_time)
{
insert_new(proc);
}
/*
* Function init_q: FCFS priority
*
* Initialises the ready queue
*
* Written as a function so that, if the ready_q
* becomes an array of pointers, the initialisation
* can be changed without re-building the main part
* of the simulator
*/
int
init_q (void)
{
ready_q = NULL;
ready_q_tail = NULL;
return OK;
}
/*
* function end_run ()
* Insert code to do any end of processing tasks for the
* functions written by the student
*/
int end_run(void)
{
fprintf(stderr, "This run had %d concurrent processes\n", Get_num_concurrent());
return 0;
}
Can anyone please help - I really dont want to fail this assignment (due in less than 24 hours). So far, its not looking good.
UPDATE:
I've gone and added a bucketload of fprintf's all over the place, and after a while I think I have isolated the problem at this line:
if (best_proc->f_link != NULL) {
I dont know how this helps me, but in the vain hope that it helps someone see the problem (because I sure dont), then so much the better.
Also, just to be clear, I dont believe this is a multithreaded application (although I am a complete noob, so who really knows) - and I didn't know I could HAVE a debugger or a stack-trace (working from 1st edition K & R "The C Programming Language") so I dont have those either. (On a side note, does programming in C normally feel like a fat japanese man is punching you in the face?)