Skip to content

Commit 80ee4b4

Browse files
authored
Refactoring and docs (#7)
* Conflicts fixed * Refactoring and adding docs * Refactoring and Docs * Refactoring and Docs * Refactoring and Docs * Refactoring and Docs * Refactoring and adding docs * Refactoring and Docs * Refactoring and adding docs * Refactoring and adding docs
1 parent 542b11a commit 80ee4b4

File tree

7 files changed

+188
-49
lines changed

7 files changed

+188
-49
lines changed

Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,4 @@ tar:
4242

4343
clean:
4444
rm $(BUILDDIR) -rf
45-
rm $(BINARY) -f
4645
rm $(target).tar.gz -f

report.pdf

115 KB
Binary file not shown.

report.txt

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
Objectives:
2+
This assignment is intended to give experience in developing multithreaded
3+
programs that require thread synchronization and deadlock prevention. My
4+
implementation uses mutexes. So they were the main focus for this.
5+
6+
7+
How to use:
8+
Makefile commands (assignment spec):
9+
- Executing ‘make’ produces the a4tasks executable file.
10+
- Executing ‘make clean’ removes any unneeded files produced in compilation and the `submit.tar` archive
11+
- Executing ‘make tar’ produces the ‘submit.tar’ archive.
12+
13+
Running the program:
14+
After compiling the a4tasks binary it can be invoked using the command line:
15+
./a4tasks inputFile monitorTime NITER
16+
Where the arguments are defined as:
17+
inputFile: file describing the tasks to be executed.
18+
monitorTime: integer (in milliseconds) that specifies how often a monitor thread runs.
19+
NITER: integer noting the amount of iterations each task executes before the simulator finishes.
20+
21+
Design Overview:
22+
In general, c++ code is used with functional programing. Code is also
23+
separated into separate files to decrease recompile time and create logical
24+
code separation.
25+
26+
1. main
27+
- entry point to the program
28+
2. task.h
29+
- contains a struct for a task
30+
3. taskManager
31+
- runs the simulation
32+
- contains the program logic
33+
4. util
34+
- handles mutex initialization, lock, and unlock
35+
- handles pthread create and join
36+
5. parsers
37+
- parses CLI argurments and files into vars
38+
- parses vars into strings
39+
40+
Three variables are global for the program: a resource map containing resource names to amount;
41+
taskList, an array containing all the tasks from the file; and threads, an array containg all the
42+
pthread_ts.
43+
44+
Three mutexes were used for the program. One controlls access to the resource map, a second controlls
45+
access to tasks' assigned variable and a third controlls access to a task's assigned variable.
46+
47+
The entire input file is read before the timer starts for the run time and threads are created.
48+
49+
Project Status:
50+
The program properly uses threads that take global resources and prints results as
51+
specified in the example. So the program is complete and adheres to specifications
52+
however due to the nature of the project an exact match was never made to the example output.
53+
54+
If letters are used as the monitor time or as nIter they will be taken as zero.
55+
56+
57+
Testing and Results:
58+
A continuous integration checker was used to ensure that the program always compiled and exited
59+
with exit status EXIT_SUCCESS during development.
60+
The example input were ran and loosely compared with example outputs. The program was run with
61+
test files of my creation too.
62+
63+
64+
Acknowledgments:
65+
66+
Linux man pages
67+
https://linux.die.net/
68+
69+
mutex initialization, lock, and unlock & delay
70+
http://webdocs.cs.ualberta.ca/~c379/F18/379only/raceC.c
71+

src/.Rhistory

Whitespace-only changes.

src/parsers.cpp

Lines changed: 53 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,11 @@ int validateArgs(int argc, char *argv[]) {
3434
if (monitorTime < 0) {
3535
printf("monitorTime invalid\n");
3636
return EINVAL;
37-
} else if (monitorTime > 100000) {
38-
printf("monitorTime invalid\n");
39-
return EOVERFLOW;
4037
}
4138

4239
if (iterations < 0) {
4340
printf("NITER invalid\n");
4441
return EINVAL;
45-
} else if (iterations > 100000) {
46-
printf("NITER invalid\n");
47-
return EOVERFLOW;
4842
}
4943

5044
return 0;
@@ -64,6 +58,10 @@ CLI_ARGS parseArgs(int argc, char *argv[]) {
6458
return args;
6559
}
6660

61+
/**
62+
* Makes the termination output for resources
63+
* @return
64+
*/
6765
std::string getFormattedSystemResourceInfo() {
6866
std::map<string, int>::iterator itr;
6967
std::string systemResources;
@@ -80,36 +78,53 @@ std::string getFormattedSystemResourceInfo() {
8078
return systemResources;
8179
}
8280

81+
void convertStatus(STATUS tStatus, char *status) {
82+
if (tStatus == IDLE) {
83+
strcpy(status, IDLE_FLAG);
84+
} else if (tStatus == WAIT) {
85+
strcpy(status, WAIT_FLAG);
86+
} else {
87+
strcpy(status, RUN_FLAG);
88+
}
89+
}
90+
91+
void getFormattedSystemTaskResourceInfo(std::string reqResource, char* buffer) {
92+
char *saveptr;
93+
char *resourceName;
94+
int resourcesNeeded;
95+
char resourceString[RESOURCE_MAX_LEN];
96+
strcpy(resourceString, reqResource.c_str());
97+
resourceName = strtok_r(resourceString, ":", &saveptr);
98+
resourcesNeeded = atoi(strtok_r(nullptr, ":", &saveptr));
99+
100+
sprintf(buffer, "\t %s: (needed=\t%d, held= 0)\n", resourceName, resourcesNeeded);
101+
}
102+
103+
/**
104+
* Makes the termination output for tasks
105+
* @return
106+
*/
83107
std::string getFormattedSystemTaskInfo() { //TODO: refactor to be clearer
84108
std::string systemTasks;
85109
for (unsigned int i = 0; i < taskList.size(); i++) {
86110
char buffer[1024];
87-
char status[20];
88-
if (taskList.at(i).status == IDLE) {
89-
strcpy(status, IDLE_FLAG);
90-
} else if (taskList.at(i).status == WAIT) {
91-
strcpy(status, WAIT_FLAG);
92-
} else {
93-
strcpy(status, RUN_FLAG);
94-
}
111+
char status[RESOURCE_MAX_LEN];
112+
convertStatus(taskList.at(i).status, status);
113+
95114
sprintf(buffer, "[%d] %s (%s, runTime= %i msec, idleTime= %i msec):\n", i,
96115
taskList.at(i).name, status,
97116
taskList.at(i).busyTime, taskList.at(i).idleTime);
98117
systemTasks.append(buffer);
118+
99119
sprintf(buffer, "\t (tid= %lu)\n", threads[i]);
100120
systemTasks.append(buffer);
121+
101122
for (auto &reqResource : taskList.at(i).reqResources) {
102-
char *saveptr;
103-
char *resourceName;
104-
int resourcesNeeded;
105-
char resourceString[50];
106-
strcpy(resourceString, reqResource.c_str());
107-
resourceName = strtok_r(resourceString, ":", &saveptr);
108-
resourcesNeeded = atoi(strtok_r(nullptr, ":", &saveptr));
109-
110-
sprintf(buffer, "\t %s: (needed=\t%d, held= 0)\n", resourceName, resourcesNeeded);
111-
systemTasks.append(buffer);
123+
char resBuffer[1024];
124+
getFormattedSystemTaskResourceInfo(reqResource, resBuffer);
125+
systemTasks.append(resBuffer);
112126
}
127+
113128
sprintf(buffer, "\t (RUN: %d times, WAIT: %lu msec)\n\n", taskList.at(i).timesExecuted,
114129
taskList.at(i).totalWaitTime);
115130
systemTasks.append(buffer);
@@ -160,7 +175,7 @@ void parseResourcesLine(const string &line) {
160175
}
161176

162177
/**
163-
* converts a task line to an item on the task list
178+
* converts a task file line to an item on the task list
164179
* @param line
165180
*/
166181
void parseTaskLine(const string &line) {
@@ -196,6 +211,11 @@ void parseTaskLine(const string &line) {
196211
taskList.push_back(newTask);
197212
}
198213

214+
/**
215+
* Returns Input File Line Type
216+
* @param line
217+
* @return
218+
*/
199219
LINE_TYPES getInputFileLineType(const string &line) {
200220
const char *flag;
201221
if (!line.length() || line[0] == '#' || line[0] == '\r' || line[0] == '\n') {
@@ -216,6 +236,10 @@ LINE_TYPES getInputFileLineType(const string &line) {
216236
return INVALID_LINE;
217237
}
218238

239+
/**
240+
* Converts a input line into a system resource, if a correct type
241+
* @param line
242+
*/
219243
void parseInputFileLine(const string &line) {
220244
switch (getInputFileLineType(line)) {
221245
case TASK_LINE:
@@ -236,6 +260,10 @@ void parseInputFileLine(const string &line) {
236260
}
237261
}
238262

263+
/**
264+
* Converts a input file into a system resource, if formatted correctly
265+
* @param inputFile
266+
*/
239267
void readInputFile(const string &inputFile) {
240268
string line; //line read from file
241269

0 commit comments

Comments
 (0)