-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAss2.c
192 lines (145 loc) · 4.27 KB
/
Ass2.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
/*
RTOS assignment 2 - UTS
Program to read from user specified Input file and Write to user specified Output file.
The purpose of this program is to demonstrate the functionality of Threads and Semaphores in C.
By Paul Vavich 11685726
*/
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <sys/types.h>
#include <string.h>
#include <time.h>
#include <sys/shm.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <sys/stat.h>
//Array for pipe
int fd[2];
/*Declaring three semaphores */
sem_t sread, swrite, sjustify;
//Thread ID
pthread_t tid1,tid2, tid3;
//Set of thread attributes
pthread_attr_t attr;
//Keyword indicating end of header, eg. when document will start writing
char header_end[] = "end_header\n";
//NOTE: This is the maximum size per line of the input File
#define MAX_BUF 50
//SHMSZ - for shared memory
#define SHMSZ 8192
#define MEM_NAME "shared"
//struct to pass to each thread
struct Parser
{
char buf[MAX_BUF];
FILE * inputF;
FILE * outputF;
} thread_data;
void *A(void *args);/*threads call this function*/
void *B(void *args);/*threads call this function*/
void *C(void *args);/*threads call this function*/
int main(int argc, char*argv[])
{
//Find Start time to calculate run time
clock_t begin = clock();
//Argument checker - User must input two file names
if(argc!=3)
{
fprintf(stderr,"Usage: Inputfile OutPutfile");
return -1;
}
//Declare struct
struct Parser thread_data;
//Declare id for Shared Memory
int shm_id;
//Declare shm pointer to store value
double* shm;
//Initilise shraed memory
shm_id = shm_open(MEM_NAME, O_CREAT | O_RDWR, 0666);
//Setting shared memory size
ftruncate(shm_id, SHMSZ);
//Assigning pointer for value of shared memory
shm = mmap(0,SHMSZ, PROT_READ | PROT_WRITE, MAP_SHARED, shm_id, 0);
//Add Files to struct
thread_data.inputF = fopen(argv[1], "r");
thread_data.outputF = fopen(argv[2], "w");
/* Get the default attributes */
pthread_attr_init(&attr);
//Initialise Pipe
if (pipe(fd) == -1)
printf("PIPE-ERROR");
/*get the default attributes*/
pthread_attr_init(&attr);
/*create the threads */
pthread_create(&tid1,&attr,A,(void *)&thread_data);
pthread_create(&tid2,&attr,B,(void *)&thread_data);
pthread_create(&tid3,&attr,C,(void *)&thread_data);
//wait for thread A to end
pthread_join(tid1,NULL);
clock_t end = clock();
double time_spent = (double)(end-begin)/CLOCKS_PER_SEC;
*shm = time_spent;
printf("Complete! Runtime time sent to memory location '%s' \n", MEM_NAME);
}
void *A(void *args)
{
//String to hold contents of file
char lineFromFile[100];
//Declaring local pointer of struct
struct Parser *tdata = (struct Parser *) args;
//For every line in input file...
while(fgets(lineFromFile,1000,tdata->inputF))
{
//write line of file into the pipe
if(write(fd[1], lineFromFile, strlen(lineFromFile)+1) != strlen(lineFromFile)+1)
printf("Pipe Error: Write Failed");
//send semaphore that pipe is ready to be read
sem_post(&sread);
//wait until next threads are ready
sem_wait(&swrite);
}
//input file has been completey read
//close output file
fclose(tdata->outputF);
//clost other threads
pthread_cancel(tid2);
pthread_cancel(tid3);
}
/*The thread will begin control in this function*/
void *B(void *args)
{
//Declaring local pointer of struct
struct Parser *tdata = (struct Parser *) args;
while(1)
{ //wait for Thread A to put data in pipe
sem_wait(&sread);
//Read Data from pipe
if(read(fd[0], tdata->buf, MAX_BUF) < 0)
printf("Pipe Error: Read Failed");
//Semaphore to start next thread
sem_post(&sjustify);
}
}
void *C(void *args)
{
//Declaring local pointer of struct
struct Parser *tdata = (struct Parser *) args;
//Flag indicating if the header has been detected as over
int found_header = 0;
while(1)
{
//wait for thread B to send complete signal
sem_wait(&sjustify);
//Write to file only if the end header has been passed
if(found_header)
//Write to file
fprintf(tdata->outputF,"%s", tdata->buf);
//If End header has been found
if(!strcmp(tdata->buf,header_end))
//set header flag
found_header = 1;
//Send signal that write is done for Thread A
sem_post(&swrite);
}
}