Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

/* 3000test.c */ 2 /* v1 Oct. 1, 2017 */ 3 /* Licenced under the GPLv3, copyright Anil Somayaji */ 4 /* You really shouldn't

/* 3000test.c */ 2 /* v1 Oct. 1, 2017 */ 3 /* Licenced under the GPLv3, copyright Anil Somayaji */ 4 /* You really shouldn't be incorporating parts of this in any other code, 5  it is meant for teaching, not production */ 6 7 #include  8 #include  9 #include  10 #include  11 #include  12 #include  13 #include  14 #include  15 #include  16 17 void report_error(char *error) 18 { 19 fprintf(stderr, "Error: %s ", error); 20 21 exit(-1); 22 } 23 24 int main(int argc, char *argv[]) 25 { 26 struct stat statbuf; 27 char *fn; 28 int fd; 29 size_t len, i, count; 30 31 char *data; 32 33 if (argc if (argc  ", argv[0]); 37 } else { 38 report_error("Not enough arguments"); 39 fprintf(stderr, "Usage: %s  ", argv[0]); 40 } 41 } 42 43 fn = argv[1]; 44 45 if (stat(fn, &statbuf)) { 46 report_error(strerror(errno)); 47 } 48 49 len = statbuf.st_size; 50 printf("File %s:  ", fn); 51 printf(" inode %ld ", statbuf.st_ino); 52 printf(" length %ld ", len); 53 54 if (S_ISREG(statbuf.st_mode)) { 55 fd = open(fn, O_RDONLY); 56 if (fd == -1) { 57 report_error(strerror(errno)); 58 } 59 data = (char *) mmap(NULL, len, 60 PROT_READ, MAP_SHARED, fd, 0); 61 if (data == MAP_FAILED) { 62 report_error(strerror(errno)); 63 } 64 65 count = 0; 66 for (i=0; iif (data[i] == 'a') { 68 count++; 69 } 70 } 71 72 printf(" a count %ld ", count); 73 74 if (munmap(data, len) == -1) { 75 report_error(strerror(errno)); 76 } 77 close(fd); 78 } 79 80 return 0; 81 } 

/* 3000pc.c */ 2 /* producer-consumer example using signals, processes and mmap */ 3 /* v1 Oct. 15, 2017 */ 4 /* Licenced under the GPLv3, copyright Anil Somayaji */ 5 /* You really shouldn't be incorporating parts of this in any other code, 6  it is meant for teaching, not production */ 7 8 #include  9 #include  10 #include  11 #include  12 #include  13 #include  14 #include  15 #include  16 #include  17 #include  18 #include  19 20 #define QUEUESIZE 32 21 #define WORDSIZE 16 22 23 const int wordlist_size = 27; 24 const char *wordlist[] = { 25 "Alpha", 26 "Bravo", 27 "Charlie", 28 "Delta", 29 "Echo", 30 "Foxtrot", 31 "Golf", 32 "Hotel", 33 "India", 34 "Juliet", 35 "Kilo", 36 "Lima", 37 "Mike", 38 "November", 39 "Oscar", 40 "Papa", 41 "Quebec", 42 "Romeo", 43 "Sierra", 44 "Tango", 45 "Uniform", 46 "Victor", 47 "Whiskey", 48 "X-ray", 49 "Yankee", 50 "Zulu", 51 "Dash" 52 }; 53 54 typedef struct entry { 55 char word[WORDSIZE]; 56 sem_t lock; 57 } entry; 58 59 typedef struct shared { 60 int prod_waiting; 61 int con_waiting; 62 entry queue[QUEUESIZE]; 63 int last_produced; 64 int last_consumed; 65 pid_t prod_pid; 66 pid_t con_pid; 67 int prod_count; 68 int con_count; 69 } shared; 70 71 72 void report_error(char *error) 73 { 74 fprintf(stderr, "Error: %s ", error); 75 } 76 77 void usage_exit(char *progname) 78 { 79 fprintf(stderr, 80 "Usage: %s    ", 81 progname); 82 exit(-1); 83 } 84 85 void producer_handler(int the_signal) 86 { 87 if (the_signal == SIGUSR1) { 88 fprintf(stderr, "Producer received SIGUSR1. "); 89 return; 90 91 } else { 92 fprintf(stderr, "Producer: No handler for for signal %d?! ", 93 the_signal); 94 return; 95 } 96 } 97 98 void consumer_handler(int the_signal) 99 { 100 if (the_signal == SIGUSR1) { 101 fprintf(stderr, "Consumer received SIGUSR1. "); 102 return; 103 } else { 104 fprintf(stderr, "Consumer: No handler for for signal %d?! ", 105 the_signal); 106 return; 107 } 108 } 109 110 void pick_word(char *word) 111 { 112 int pick; 113 114 pick = random() % wordlist_size; 115 116 strcpy(word, wordlist[pick]); 117 } 118 119 void wait_for_producer(shared *s) 120 { 121 struct timespec delay; 122 123 delay.tv_sec = 100; 124 delay.tv_nsec = 0; 125 126 s->con_waiting = 1; 127 128 while (s->con_waiting) { 129 nanosleep(&delay, NULL); 130 } 131 } 132 133 void wait_for_consumer(shared *s) 134 { 135 struct timespec delay; 136 137 delay.tv_sec = 100; 138 delay.tv_nsec = 0; 139 140 s->prod_waiting = 1; 141 142 while (s->prod_waiting) { 143 nanosleep(&delay, NULL); 144 } 145 } 146 147 void wakeup_consumer(shared *s) 148 { 149 if (s->con_waiting) { 150 s->con_waiting = 0; 151 kill(s->con_pid, SIGUSR1); 152 } 153 } 154 155 void wakeup_producer(shared *s) 156 { 157 if (s->prod_waiting) { 158 s->prod_waiting = 0; 159 kill(s->prod_pid, SIGUSR1); 160 } 161 } 162 163 void output_word(int c, char *w) 164 { 165 printf("Word %d: %s ", c, w); 166 } 167 168 int queue_word(char *word, shared *s) 169 { 170 entry *e; 171 int current, retval; 172 173 current = (s->last_produced + 1) % QUEUESIZE; 174 175 e = &s->queue[current]; 176 177 sem_wait(&e->lock); 178 179 if (e->word[0] != '\0') { 180 /* consumer hasn't consumed this entry yet */ 181 sem_post(&e->lock); 182 wait_for_consumer(s); 183 sem_wait(&e->lock); 184 } 185 186 if (e->word[0] != '\0') { 187 fprintf(stderr, "ERROR: No room for producer after waiting! "); 188 retval = -1; 189 goto done; 190 } else { 191 strncpy(e->word, word, WORDSIZE); 192 s->last_produced = current; 193 s->prod_count++; 194 wakeup_consumer(s); 195 retval = 0; 196 goto done; 197 } 198 199 done: 200 sem_post(&e->lock); 201 return retval; 202 } 203 204 int get_next_word(char *word, shared *s) 205 { 206 entry *e; 207 int current, retval; 208 209 current = (s->last_consumed + 1) % QUEUESIZE; 210 211 e = &s->queue[current]; 212 213 sem_wait(&e->lock); 214 215 if (e->word[0] == '\0') { 216 /* producer hasn't filled in this entry yet */ 217 sem_post(&e->lock); 218 wait_for_producer(s); 219 sem_wait(&e->lock); 220 } 221 222 if (e->word[0] == '\0') { 223 fprintf(stderr, "ERROR: Nothing for consumer after waiting! "); 224 retval = -1; 225 goto done; 226 } else { 227 strncpy(word, e->word, WORDSIZE); 228 e->word[0] = '\0'; 229 s->last_consumed = current; 230 s->con_count++; 231 wakeup_producer(s); 232 retval = 0; 233 goto done; 234 } 235 236 done: 237 sem_post(&e->lock); 238 return retval; 239 } 240 241 void producer(shared *s, int event_count, int producer_delay_interval) 242 { 243 char word[WORDSIZE]; 244 int i; 245 struct sigaction signal_handler_struct; 246 247 memset (&signal_handler_struct, 0, sizeof(signal_handler_struct)); 248 signal_handler_struct.sa_handler = producer_handler; 249 250 if (sigaction(SIGUSR1, &signal_handler_struct, NULL)) { 251 fprintf(stderr, "Producer couldn't register SIGUSR1 handler. "); 252 } 253 254 for (i=0; i if (producer_delay_interval > 0) { 258 if (i % producer_delay_interval == 0) { 259 sleep(1); 260 } 261 } 262 } 263 264 printf("Producer finished. "); 265 exit(0); 266 } 267 268 void consumer(shared *s, int event_count, int consumer_delay_interval) 269 { 270 char word[WORDSIZE]; 271 int i; 272 struct sigaction signal_handler_struct; 273 274 memset (&signal_handler_struct, 0, sizeof(signal_handler_struct)); 275 signal_handler_struct.sa_handler = consumer_handler; 276 277 if (sigaction(SIGUSR1, &signal_handler_struct, NULL)) { 278 fprintf(stderr, "Consumer couldn't register SIGUSR1 handler. "); 279 } 280 281 for (i=0; i con_count, word); 284 if (consumer_delay_interval > 0) { 285 if (i % consumer_delay_interval == 0) { 286 sleep(1); 287 } 288 } 289 } 290 291 printf("Consumer finished. "); 292 exit(0); 293 } 294 295 void init_shared(shared *s) 296 { 297 int i; 298 299 s->con_waiting = 0; 300 s->last_consumed = -1; 301 302 s->prod_waiting = 0; 303 s->last_produced = -1; 304 305 s->prod_pid = -1; 306 s->con_pid = -1; 307 308 s->prod_count = 0; 309 s->con_count = 0; 310 311 for (i=0; iqueue[i].word[0] = '\0'; 313 /* semaphore is shared between processes, 314  and initial value is 1 (unlocked) */ 315 sem_init(&s->queue[i].lock, 1, 1); 316 } 317 } 318 319 int main(int argc, char *argv[]) 320 { 321 int pid, count, prod_interval, con_interval; 322 323 shared *s; 324 325 srandom(42); 326 327 if (argc if (argc else { 332 report_error("Not enough arguments"); 333 usage_exit(argv[0]); 334 } 335 } 336 337 count = atoi(argv[1]); 338 prod_interval = atoi(argv[2]); 339 con_interval = atoi(argv[3]); 340 341 s = (shared *) mmap(NULL, sizeof(shared), 342 PROT_READ|PROT_WRITE, 343 MAP_SHARED|MAP_ANONYMOUS, -1, 0); 344 345 if (s == MAP_FAILED) { 346 report_error(strerror(errno)); 347 } 348 349 init_shared(s); 350 351 pid = fork(); 352 353 if (pid) { 354 /* producer */ 355 s->prod_pid = getpid(); 356 producer(s, count, prod_interval); 357 } else { 358 /* consumer */ 359 s->con_pid = getpid(); 360 consumer(s, count, con_interval); 361 } 362 363 /* This line should never be reached */ 364 return -1; 365 } 

/* 3000random.c */ 2 /* prints out random numbers obtained from system /dev/urandom */ 3 /* (This is much, much better than using rand() or random())! */ 4 /* v1 Oct. 15, 2017 */ 5 /* Licenced under the GPLv3, copyright Anil Somayaji */ 6 /* You really shouldn't be incorporating parts of this in any other code, 7  it is meant for teaching, not production */ 8 9 #include  10 #include  11 #include  12 #include  13 14 #define BUFSIZE 1024 15 16 typedef struct rand_state { 17 unsigned long buffer[BUFSIZE]; 18 int current; 19 int fd; 20 } rand_state; 21 22 void fill_rand_buffer(rand_state *r) 23 { 24 ssize_t count; 25 26 count = read(r->fd, (void *) &r->buffer, 27 BUFSIZE * sizeof(unsigned long)); 28 29 if (count > sizeof(unsigned long)) { 30 r->current = count / sizeof(unsigned long); /* was %, that was wrong! */ 31 } else { 32 fprintf(stderr, "Couldn't fill random buffer. "); 33 } 34 } 35 36 void system_rand_init(rand_state *r) 37 { 38 r->fd = open("/dev/urandom", O_RDONLY); 39 40 fill_rand_buffer(r); 41 } 42 43 long system_rand(long max, rand_state *r) 44 { 45 unsigned long val; 46 47 if (r->current if (r->current /* fill_rand_buffer should have already 51  reported an error */ 52 return 0; 53 } 54 } 55 56 val = r->buffer[r->current]; 57 r->current--; 58 return val % max; 59 } 60 61 int main(int argc, char *argv[]) 62 { 63 int count, i; 64 long max, x; 65 rand_state r; 66 67 if (argc != 3) { 68 fprintf(stderr, "Usage: %s   ", argv[0]); 69 exit(-1); 70 } 71 72 count = atoi(argv[1]); 73 max = atol(argv[2]); 74 75 printf("count = %d, max = %ld ", count, max); 76 77 system_rand_init(&r); 78 79 for (i = 0; i  ", x); 82 } 83 84 return 0; 85 } 

QUESTIONS!!!

1. [1] Why does a different version of stat(), lstat(), exist that treats symbolic links differently? Why isn't a different version needed for hard links?

2. [1] How can you modify 3000pc so the producer stops producing once it fills the queue?

3. [1] Under what circumstances is fill_rand_buffer() called in 3000random?

4. [1] If the two signal handling functions in 3000pc were replaced by one function, would there be any significant loss of functionality? Briefly explain.

5. [2] How could you modify 3000test.c so it can report on whether two device files are equal without actually accessing the underlying devices? Specify the changes you would make to 3000test.c rather than doing this from scratch.

6. [2] Does the MAP_SHARED flag on line 60 of 3000test.c (inside the call to mmap) make a significant difference in its execution? Specifically, what happens when you remove it or changed it to MAP_PRIVATE? Why?

7.[2] When a file is mmap'd into memory, when is its contents loaded from disk? How can you verify this using 3000test?

8. [2] What is one way simple way you can modify 3000pc so the consumer consumes as the producer produces, i.e., the producer and the consumer move essentially in lock step? Your modification should not involve sleeping by either the producer or the consumer. Why does your change work? (To do this precisely is hard; to do this approximately involves a change to one line. The approximate solution is sufficient.)

9. [2] Which is faster, /dev/urandom or /dev/random? What evidence do you have for this difference based on code that you ran (3000random or other programs)?

10. [2] How does the behavior of 3000pc change if you delete lines 149 and 152 (the if statement in wakeup_consumer())? Why? (Explain what the program does after this change and why it may be problematic.)

11. [2] What happens if you delete line 231 (the call to wakeup_producer()) in 3000pc? Why?

12. [2] How does the behavior of the program change if you change QUEUESIZE to 8? What about 128?

3000test.c image text in transcribed

image text in transcribed

3000pc.c

image text in transcribed

image text in transcribed

image text in transcribed

image text in transcribed

image text in transcribed

image text in transcribed

image text in transcribed

3000random.c

image text in transcribed

image text in transcribed

Questions!!!!!!

image text in transcribed

VIRGIN 2:01 PM homeostasis.scs.carleton.ca Code 3000test.e/ v1 Oct. , 2017 Licenced under the GPLv3, copyright Anil You really shouldn't be incorporating parts of it is meant for teaching, not production/ Somayaji */ this in any other code include #include #include #include #include u #include include 24 include 15include " void reporterror(char error) Eprintf(stderr, "Error: sin,error) exit(-1) a int main(int argc, char argv struct stat statbuf; char *fn; int fd size t len, i, count; char dataj if (arge 2) if (arge ", argvt 0]) else t report error("Not enough Eprintf(stderr,"Usager ts cEile>in argvt0]) fn argvl if (stat (fn, statbuf)) report error(strerror (errno)) len statbuf.st size printf( "File is: In",fn)1 printf( inode ldin, statbuf.st ino); printf( if (S ISREG(statbuf.st_mode)) length ldn, len) fd = open (fn, ORDONLY)

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Current Trends In Database Technology Edbt 2004 Workshops Edbt 2004 Workshops Phd Datax Pim P2panddb And Clustweb Heraklion Crete Greece March 2004 Revised Selected Papers Lncs 3268

Authors: Wolfgang Lindner ,Marco Mesiti ,Can Turker ,Yannis Tzitzikas ,Athena Vakali

2005th Edition

3540233059, 978-3540233053

More Books

Students also viewed these Databases questions