$25
Software Tools and Systems Programming
Assignment Overview:
The purpose of this assignment is to provide experience in managing linked lists using pointers and structures.
When embarking on a detailed assignment like assignment five (5) there are two ways to approach the task.
The first is to just start programming and write code that accomplishes many if not all the tasks all at once. This is the way we all started to code in first year. The assignments were fairly uncomplicated. This meant the code could be approached as a single task and worked on as a unit.
But this does not lend itself to larger and more complex projects.
The second method is to understand the task and break it down into smaller, more manageable sections. Then code one section to completion at a time.
It is highly recommended that the second approach be used for this assignment. It will save much time and also very much frustration.
The hints provided at the end of this document will detail one possible approach to this second method.
PREPERATION:
For this assignment, create a new directory under the assignments directory created in the first assignment. Label this new directory: asn5
All work should be performed in this directory. Use a UNIX editor like vi to create and compile the C code.
The code MUST compile in the UNIX environment to be considered correct.
This time the assignment will be contained within multiple files.
Assignment Five (5)
This assignment will simulate the use of a printer queue to manage the processing of printer jobs.
Every time a document is requested to be printed, a printer job is created and placed in the printer queue. The printer will process one job at a time by printing the page(s) of a document. Once all the pages of the current printer job have been processed, the request is released, and the printer will inspect the printer queue to retrieve and remove the next job in the queue.
The simulation will operate on a per cycle basis. Whereas a real printer queue is continuous, this simulation will execute for a given finite number of cycles.
The main program will loop through this process for some finite set of cycles denoted by the defined preprocessor definition of ITERATIONS representing number of cycles.
Each print job will have four factors:
a) – document number (next number in sequence)
b) – request priority: 1 – high priority
2 – average priority
3 – low priority
c) – Number of pages in the requested document
d) – Number of cycles the print job has been in the queue.
Each cycle will consist of:
a) - creating a new print job request:
This request will be based on a 10% chance in each cycle that a new request will be generated.
The request priority will be distributed as:
1 – high priority ( 10% probability )
2 – average priority ( 70% probability )
3 – low priority ( 20% probability)
The number of pages will be a random number between 0 and MAXPAGES
The document number will be the next number in the sequence, starting with the number one (1).
b) - the new print job request will be placed in the queue:
The position in the queue will be based on:
- first - priority (lower number (representing higher priority) before a larger (lower priority) number.
- second - within the priority, the number of pages, with the documents with a lower number of pages being positioned before documents in the queue with larger number of pages. (assume the existing printer queue is represented as the image below)
( if a new printer job request (document 15) is created with an average priority (2) and seven (7) pages, then the new printer job request will be placed immediately before the first existing job of priority 2, page count of 8. (before request for document 8) see image below. ) note: if the new printer job priority was 2 and the number of pages was 6 then the new printer job would be placed in the exact same position – immediately before the higher page count.
( below is an image of the existing printer queue once the new printer job has been added to the list.)
c) – print page(s) of the current active print job:
Check that there is a print job being processed by the printer.
-If there is not a current active printer job, then remove the next printer job request from the front of the printer queue. Document 4 has been removed and sent to the printer.
( below is an image of the existing printer queue once the front printer job
(document 4 - priority 1 – pages 2) has been popped off the list and sent to the printer.)
- Decrement the number of pages of the current active print job by the PAGEPERMINUTE value.
- if all the pages are printed after decrementing, then remove the print job from the printer.
d) – increment the cycle count for each print job request in the queue: Transverse the entire printer queue and increment the cycle count by 1.
After incrementing the cycle count for a print job, check if the cycle count for a print job request has exceeded MAXCYCLES. If so, print out a message if DEBUG_SHOW_EXCEEDED is set to 1.
OUTPUT:
The program will display a message every time a print process is completed. The message will be:
Print Job Completed - Document Number: xx - Cycle Count: yy
where xx is the document number just completed and yy is the number of cycles the print job required to be completed.
Print out a message indicating the program has completed execution (note: change to your name).
End of Program - * MAX MAGGUILLI *
Number of printer jobs left in queue: xx
The program will also have a series of debug statements controlled by preprocessor definitions.
DEBUG_LIST
- print out a listing of printer jobs currently in the queue:
Current Printer Queue Size: xx
Current Printer Queue : DocNum: xx NumofPages xx PriorityLevel xx NumOfCycles xx
Current Printer Queue : DocNum: xx NumofPages xx PriorityLevel xx NumOfCycles xx Current Printer Queue : DocNum: xx NumofPages xx PriorityLevel xx NumOfCycles xx
...
END OF LIST
- or if queue is empty:
EMPTY QUEUE - no print jobs currently in queue
DEBUG_ADDING
- printout every time a new printer job is added to the queue:
Adding to Queue - Doc: xx NoPages: xx Priority: xx
DEBUG_PRINT_PROCESS
- print out current printing process of active printing document:
PRINTING - DOCUMENT: xx PAGE: xx priority: xx
DEBUG_SHOW_CYCLES
- print out a list of every printer job after the cycle count has been increased by 1.
Increment Cycle - Document: xx Pages: xx Priority: xx Cycle Count: xx
DEBUG_SHOW_EXCEEDED
- print out the first time a print job cycle count exceeds MAXCYCLES
- prints only once when that specific print job cycle count exceeds MAXCYCLES
EXCEEDED CYCLE COUNT - Document: xx Pages: xx Priority: xx Cycle Count: xx
BONUS – (optional) worth 20% extra added to your assignment five (5) grade.
e) – reposition a printer job if the cycle count of an individual printer job has exceeded the specified number of maximum cycles:
After incrementing the cycle count for a print job, check if the cycle count for a print job request has exceeded MAXCYCLES.
If it has, then change the priority to zero (0) and move the print job request to the front of the queue.
BUT! This request MUST be placed at the end of any existing print jobs that also have a priority of zero. If it was placed at the very front as the first item, then some print jobs would never be sent to the printer.
(assume that MAXCYCLES is set to 10. Then once the second print job above (document 6) is processed, its priority will be changed to zero (0) and it will be repositioned (moved) towards the beginning of the printer queue.)
[first, document number 5’s cycle count was increased from 2 to 3, then document number 6’s cycle count is increased from 9 to 10. The count of 10 exceeds MAXCYCLES … )
so document number 6 has its priority level changed to zero (0) ...
then printer job for document number 6 is moved to the end of all the existing printer jobs with a priority level of zero (0). ]
Continue down the print queue and increment the cycle count for the remaining print jobs.
If another print job cycle exceeds MAXCYCLES, repeat the process, but move the print job to the end of the print jobs with priority zero (0).
In the image above, when the cycle count for document 3 (the fifth print job in the queue) is incremented, it will exceed MAXCYCLES and will be moved to the end of any of the print jobs with a priority of zero (0). NOT to the front of the printer queue.
Notice that the print job for document number 3 is now the second member of the list. This is because it was placed at the end of all the existing priority zero (0) members. This is regardless of the number of pages in document number 3. The number of pages is not taken into consideration when number of cycles exceeds MAXCYCLES. The print job must be placed at the end of all the existing priority zero (0) members even if the other members with zero (0) priority have a higher page count.
Coding Practices:
Regarding modularity, each of these operations will be contained in their own function and each function will reside in their own .c file. The main function will be the program control section.
Regarding incremental programming, each operation will be a separate project, where, after the first project, each one will build off the last.
Correct use of controls will be introduced by forbidding the use of infinite loops with conditional break statements imbedded in the control.
Example:
while (1) {
... c statements
... c statements ... c statements if (something) break; ... c statements
... c statements
}
This is tantamount to using a hammer to drive in a screw. Yes, it works, but it is NOT pretty, and it does NOT do the job correctly. This causes the programmer to look and attempt to validate the logic of the loop termination. This practice will result in major deductions on your assignments.
The break and continue statements are powerful and useful parts of the C language when used correctly. Using it in the above example is counter to the use of the while loop. This assignment may contain a possible location creating an example of the correct usage of the break statement in C code (this is optional).
Your main.c must only contain minimal computation (as demonstrated in class).
Code Standards:
1.) create two (2) header files (similar as was required for assignment four).
one file labeled headers.h the other file is labeled definitions.h
2.) Global variables are not allowed.
3.) Linked list must be singly linked list (double linked list not allowed).
4.) All structures (and/or unions) are dynamically allocated.
5.) Members of the printer queue are nodes that only contain pointers to other nodes and a pointer to the data item representing a document. (Review the notes for details)
Each print job node in the printer queue will be based on the following definition:
// ADT Type Definitions typedef struct node
{
void* dataPtr; // pointer to document structure struct node* next; // must be a singly linked list } LIST_NODE;
5.) The preprocessor definitions are to be set as follows:
#define PAGESPERMINUTE 1
#define MAXCYCLES 200
#define MAXPAGES 30
#define ITERATIONS 1000
Code Standards:
1.) create two (2) header files.
one file labeled headers.h with the following contents:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "definitions.h"
2.) the other file is labeled definitions.h with the following contents:
- any preprocessor definitions (e.g. DEBUG) - all function prototypes.
3.) all arrays are to be dynamically allocated based on user input.
Required Coding Standards
All code is to be indented correctly.
Comments at the very beginning (top – first lines) of each of the C code files must be:
/* CS2211a 2021 */
/* Assignment 05 */
/* your name */
/* your student number */
/* your UWO User Name */
/* Date Completed */
Your program is to be submitted as C code file.
Your script will be a script file created in UNIX.
All variables MUST have a comment describing their intended use(s) demonstrating an understanding of what each variable is used for.
A comment describing the code for each major part of the code is expected. Comment(s) can be added to describe any complete statements you create. They can be brief but must convey what that section of code performs.
Any questions or ambiguities are to be asked through the Forums only. Any individual emails containing questions on this assignment will be replied to with a request to restate the question in the Forums in Owl where they will be addressed.
Working in UNIX.
Save the files in your asn5 directory.
NEXT: Follow the steps below to complete Part 2.
1. Type the following to begin recording your session in a file called yourUserName_asn5.output
script YourUserName_asn5.output
note - (using your actual user name).
2. Display the current date and time using the appropriate command
3. Display your username using the appropriate command
4. Display the contents of the current working directory using the ‘l’ switch (lower case L).
5. Display the contents of the file main.c (i.e. show the main() function in your C program)
6. Compile the program again ensuring the executable is labeled: asn5
(yes, even though we have not covered makefiles, it is recommended you use one if you wish)
7. Run the program.
8. Type exit to stop your screen capture session.