Processes and threads assignments (LE: 1,3,5,7,8,9,10,11,13) 1. - - PDF document

processes and threads assignments le 1 3 5 7 8 9 10 11 13
SMART_READER_LITE
LIVE PREVIEW

Processes and threads assignments (LE: 1,3,5,7,8,9,10,11,13) 1. - - PDF document

Linkping University 2011-01-30 Department of Computer and Information Science (IDA) Concurrent programming, Operating systems and Real-time operating systems (TDDI04) Processes and threads assignments (LE: 1,3,5,7,8,9,10,11,13) 1. Consider a


slide-1
SLIDE 1

Linköping University 2011-01-30 Department of Computer and Information Science (IDA) Concurrent programming, Operating systems and Real-time operating systems (TDDI04) 3

Processes and threads assignments (LE: 1,3,5,7,8,9,10,11,13)

  • 1. Consider a computer running an mp3 player, an X-window system, a terminal with

bash running top, a clock, and a word-processor. The mp3-player have several things going on, playing music, updating a graphic mixer chart and showing rolling text with title information and playtime remaining. The word processor does spell checking while you write and shows an animated help icon. a) Identify several processes in this system. b) Identify several threads in this system. c) Draw a picture of how the operating system may represent the various processes and threads at a given time. d) How are the threads in your picture related to the processes? Which other process - thread relations may exist? e) What differs between kernel-threads, user-threads and processes? Which data does the OS store about them?

  • 2. Which are the purposes and motivations of using operating systems?
  • 3. A system starts an IDLE thread during boot, and then a thread BILL. The threads are

implemented according to the following (we count one instruction per line).

IDLE: BILL: ADAM: EVE: while (true) thread_create(ADAM); wait(!EVE); eat(Apple); noop; thread_create(EVE); enjoy(OS X); wake(ADAM); forbid(Apple); invent(MAC); launch(Vista);

The operating system will place the new thread in an appropriate queue when it is created or waiting. The operating system manages thread-switches automatically at random times. Assume now that you are in control of the dice, and the thread queues. a) Show a sequence of events (executed instructions and thread switches) that finish all threads while fulfilling the following two conditions: MAC must be invented before OS X, and OS X must be enjoyed before Apple is forbidden. (The instruction wake(ADAM) will move ADAM to an appropriate queue.) b) Show a different sequence of events that break the conditions (MAC is invented after OS X, and Apple is forbidden before eaten). Show the queue contents after each instruction. c) What can you learn from the example?

  • 4. Answer the following regarding processes and threads:

a) Define a process. b) Define a thread. c) Motivate the use of processes and threads. d) What is the purpose of a process control block. e) List the possible states (queues) a thread/process can be in during it’s lifetime.

slide-2
SLIDE 2

TDDI04 2011-01-30 4

  • 5. Assume a computer have D I/O devices to request data from, P processors to

execute on and a main memory that can hold at most M processes simultaneous. a) How many processes can be in the running/executing state simultaneous? b) How many processes can be ready to run, at most? c) How many processes can be in the waiting state?

  • 6. An operating system can be structured in several ways, and in several layers.

a) What is the central idea behind a micro-kernel? b) Which are the main subsystems in an operating system, and how are they related (how does the subsystems use each other? Hint: think of which order the subsystems is needed when starting a program.)

  • 7. Interrupts have a central role in operating systems.

a) Explain why interrupts are so important. b) How does the operating system use interrupts?

  • 8. When executing code from multiple threads on an uniprocessor the code are

interleaved to make it appear each thread is executing simultaneous. This leads to problems when the code share data common to the threads. One thread may be interrupted at any time, and the shared data it is working on may be modified by another thread, and later the original thread continue unaware of the interrupt and modification of data. This may lead to errors. Find all such problems in the code given below.

10: /* Each value in this global array of pointers is set to NULL in main */ 11: void* content[128]; 12: 13: /* Add data to free slot in array. This is called from many threads. */ 14: int array_add(void* data) 15: { 16: for (i = 0; i < 128; ++i) 17: { 18: /* if free, use it */ 19: if (content[i] == NULL) /* determine if index is free */ 20: { 21: content[i] = data; /* save data pointer in free index */ 22: break; 23: } 24: } 25: return i; /* return index used */ 26: } 27: 28: /* Remove data from array. This is called from many threads. */ 29: void* array_remove(int id) 30: { 31: void* ret = content[id]; /* temporarily save the index’s pointer */ 32: content[id] = NULL; /* mark the index as free */ 33: return ret; /* return the pointer that was removed */ 34: } 35: 36:

slide-3
SLIDE 3

TDDI04 2011-01-30 5

  • 9. Answer the following regarding system calls:

a) Why are system calls needed? Try to think of the benefits on all levels. b) Who requests, and who executes system calls? Why? What is meant by dual-mode operation? What is different from a normal function call? c) How is a system call performed? Try to explain all technical details. 10.The following code uses several processors to sum the values in an array. Using several processors can lead to the same problems as running interleaved threads

  • n one processor. Explain how the calculation may become wrong.

10: /* sum: A pointer to the variable containing the final sum. 11: start: A pointer to the first value in an array to sum. 12: stop: A pointer which the summation should stop just before. 13: */ 14: void sum_array(int* sum, int* start, int* stop) 15: { 16: while (start < stop) 17: { 18: *sum = *sum + *start; 19: ++start; 20: } 21: } 22: 23: /* Some code in the main function is omitted for brewity. */ 24: int main() 25: { 26: int sum = 0; 27: int array[512]; 28: 29: /* Code to initiate the array with data is placed here. */ 30: 31: /* Start four threads to sum different parts of the array. 32: * 33: * thread_create schedules (places in ready queue) a new thread 34: * to execute the sum_array function. As this shecdule is just a 35: * list insert it will return quickly, probably (but not always) 36: * before the new thread even staret execution. 37: */ 38: thread_create(sum_array, &sum, array + 128*0, array + 128*1); 39: thread_create(sum_array, &sum, array + 128*1, array + 128*2); 40: thread_create(sum_array, &sum, array + 128*2, array + 128*3); 41: thread_create(sum_array, &sum, array + 128*3, array + 128*4); 42: }

11.An antivirus process starts a new thread to scan a zip file (compressed archive containing many files) for viruses. The new thread will first open the zip to verify it’s

  • integrity. If the integrity is fine the thread will continue to scan each file within the
  • archive. If the integrity (archive format is unrecognized or faulty) the thread will

inform the main process thread of this and then quit. The main process thread will then scan the archive as a regular file, without unpacking the data. In this case the process need confirmation from the thread to determine it’s action. The code below implement a solution that seems plausible. What errors may occur? Which different

  • rder of events exists?
slide-4
SLIDE 4

TDDI04 2011-01-30 6 10: /* Open the file as a zip file and scan each file inside for viruses. 11: * Set the output parameter bad to true if the zip is invalid. */ 12: void unpack_and_scan(const char* filename, bool* bad) 13: { 14: zip = open_zip(filename); 15: 16: if (open_failed(zip)) 17: { 18: *bad = true; 19: return; /* exit thread */ 20: } 21: 22: /* Iterate each file contained in the zip and scan it. */ 23: for (file = zip_first(zip); file != NULL; file = zip_next(zip)) 24: { 25: scan_regular_file(file); 26: } 27: } 28: 29: /* Scan all files given as argument to main. 30: * > indicate lines important for the assignemnt. */ 31: int main(int argc, char* argv[]) 32: { 33: int i; 34: for (i = 0; i < argc; ++argc) 35: { 36: switch ( file_extension(argv[i]) ) 37: { 38: case ZIP: 39: { 40: > bool bad_file = false; 41: > 42: > /* thread_create schedules a new thread to execute 43: > * unpack_and_scan. As schedule is just a list insert it 44: > * will return quickly, probably before the new thread even 45: > * stared execution. */ 46: > thread_create(unpack_and_scan, argv[i], &bad_file); 47: > 48: > if ( ! bad_file ) 49: > { 50: > break; /* break switch and continue for loop. */ 51: > } 52: > /* Fall through to COM,EXE,DLL action since break is missing.*/ 53: } 54: case COM,EXE,DLL: 55: { 56: scan_regular_file(filename); 57: break; /* break switch and continue for loop. */ 58: } 59: case TXT,BMP,PNG,JPG: 60: { 61: break; /* Considered safe files. Do nothing. */ 62: } 63: } /* end switch */ 64: } /* end for */ 65: 66: return 0; 67: }

slide-5
SLIDE 5

TDDI04 2011-01-30 7

12.The stack below is implemented as a singly linked list. Multiple threads are executing the pop and push functions concurrently. Show all thread execution sequences that will produce errors.

10: /* This structure represents one item on the stack. */ 11: struct stack_node 12: { 13: struct stack_node* next; 14: int data; 15: } 16: 17: /* This structure represents the entire stack. */ 18: struct stack 19: { 20: struct stack_node* top; 21: } 22: 23: /* Initiate the stack to become empty. 24: * Called once before any threads are started. */ 25: void stack_init(struct stack* s) 26: { 27: top = NULL; 28: } 29: 30: /* Pop one item from the stack if possible. The stack is specified as 31: * parameter. Many threads use this function simultaneously. */ 32: int stack_pop(struct stack* s) 33: { 34: struct stack_node* popped = s->top; /* Get the top element */ 35: if (popped != NULL) /* Was it anything there? */ 36: { 37: int data = popped->data; /* Save the data we want */ 38: s->top = popped->next; /* Remove the top element */ 39: free(popped); /* Free removed element memory */ 40: return data; /* Return the saved data */ 41: } 42: return -1; /* The stack was empty */ 43: } 44: 45: /* Push one item to the stack. The stack and the integer data to push 46: * are specified as parameters. Many threads use this function. */ 47: void stack_push(struct stack* s, int x) 48: { 49: struct stack_node* new_node = malloc(sizeof(struct stack_node)); 50: new_node->next = s->top; 51: new_node->data = x; 52: s->top = new_node; 53: } 54: 55: int main() 56: { 57: struct stack s; 58: stack_init(&s); 59: 60: /* Create a dozen threads using the stack through &s ... */ 61: 62: return 0; 63: }

slide-6
SLIDE 6

TDDI04 2011-01-30 8

13.The code below implements a bounded buffer. The two functions support adding and removing values from a buffer with limited (bounded) size. This code is executed in several threads. N threads are reading values and M threads are writing values. At the point where the buffer is empty or full each function takes care of waiting for values or space to become available. Find at least two execution sequences that will result in errors.

10: #define SIZE 256 11: /* With this size and 8-bit read- and write positions the position 12: * counters will automatically go from 255 around to 0. 13: * Else we must add code to wrap around (position % SIZE).*/ 14: 15: /* This structure represent a bounded buffer (queue) */ 16: struct bounded 17: { 18: int buffer[SIZE]; 19: int used_size = 0; /* Initiation like this is not possible in 20: int8 read_pos = 0; * real C-code. You must use an init function. 21: int8 write_pos = 0; */ 22: }; 23: 24: /* Read the oldest value in the queue. */ 25: int bounded_read(struct bounded* b) 26: { 27: /* We must wait until the queue have at least one value. */ 28: while (b->used_size == 0) 29: ; /* Busy wait is BAD! */ 30: 31: /* Now we have(?) a value to read (remove). */ 32: --b->used_size; 33: 34: /* Read the value from the read position. */ 35: return b->buffer[b->read_pos++]; 36: } 37: 38: /* Write a new value to the next free position in the queue. */ 39: void bounded_write(struct bounded* b, int x) 40: { 41: /* We must wait until at least one slot is available. */ 42: while (b->used_size == SIZE) 43: ; /* Busy wait is BAD! */ 44: 45: /* Now we have(?) an empty position to use. */ 46: b->buffer[b->write++] = x; 47: ++b->used_size; 48: } 49: 50: int main() 51: { 52: struct bounded bounded_buffer; 53: 54: /* Create M threads writing the queue through &bounded_buffer ... */ 55: /* Create N threads reading the queue through &bounded_buffer ... */ 56: 57: return 0; 58: }

slide-7
SLIDE 7

TDDI04 2011-01-30 9

14.The function reserve_seat is executed concurrently by several threads. To keep track of reserved seats a global multidimensional array is used, where each

  • ccupied seat is set to true. When several seats are booked the function will

guarantee that only consecutive (next to each other) seats are reserved. To achieve the longest possible sequence of free seats after a reservation, reservations are always done from the longest free sequence. Outline at least two execution sequences that will produce errors.

10: bool seats[ROWS][COLUMNS]; /* true mean occupied */ 11: 12: /* The main program may be an internet server for reservation of 13: * movie seats. It sets all seats to free initially, and starts 14: * one reservation thread each time a user connects to the server. 15: */ 16: 17: /* Reserve ‘n’ consecutive seats in ‘row’ */ 18: bool reserve_seat(int n, int row) 19: { 20: int max_start = 0; 21: int max_count = 0; 22: int c = 0; 23: 24: while (c < COLUMNS) 25: { 26: int start; 27: int end; 28: 29: while (c < COLUMNS && seats[row][c] == true) 30: ++c; 31: start = c; /* first free seat in row */ 32: 33: while (c < COLUMNS && seats[row][c] == false) 34: ++c; 35: end = c; /* column of the next occupies seat */ 36: 37: /* Is it the longest sequence of free seats in row? */ 38: if (max_count < (end - start)) 39: { 40: max_start = start; 41: max_count = end - start; 42: } 43: } 44: 45: /* Was the longest free sequence long enough? */ 46: if (max_count < n) 47: { 48: return false; 49: } 50: 51: /* allocate the seats */ 52: for (c = max_start; 53: c < (max_start + n); ++c) 54: { 55: seats[row][c] = true; 56: } 57: 58: return true; 59: }

slide-8
SLIDE 8

TDDI04 2011-01-30 10

15.Assignments 8 and 10-14 above have synchronization problems. Errors will occur during the execution when thread switches occur untimely. a) Identify all critical sections. b) Apply proper mechanisms to secure correct execution in all cases. c) Improve on your solutions to allow for the most efficient execution when more processors are available (minimize the need for threads to wait for each other).