Project 2 kthreads concurrency shuttle Highlevel overview User

  • Slides: 30
Download presentation
Project 2 kthreads, concurrency, shuttle

Project 2 kthreads, concurrency, shuttle

Highlevel overview • User space – program wants to control the shuttle simulation by

Highlevel overview • User space – program wants to control the shuttle simulation by sending requests. – start_shuttle() – issue_request() – stop_shuttle() • Kernel space program wants to simulate the shuttle according those requests. Need to use a thread to simulate the shuttle running.

Kthreads • Thread: basic executable unit. • Run the shuttle in its own kthread,

Kthreads • Thread: basic executable unit. • Run the shuttle in its own kthread, not the thread that calls the module_init function.

kthreads • Kernel Threads • Kthread_run(threadfn, data, name, . . . ) – Creates

kthreads • Kernel Threads • Kthread_run(threadfn, data, name, . . . ) – Creates a new thread of execution that starts with the function pointed to by threadfn – threadfn: fuction pointer – data: data passed to threadfn – name: name of the thread

while shuttle_running if users want get off at current terminal Unload (release space) if

while shuttle_running if users want get off at current terminal Unload (release space) if users want get on at current terminal and have space (. . other performance logic) Load (consume space) Move to next desired terminal (*) endwhile

Module • (1) Start a new kernel thread, performing a infinite loop. • (2)

Module • (1) Start a new kernel thread, performing a infinite loop. • (2) Simulating the shuttle (load, unload, move to next) • (3) Finally you may use kthread_stop to stop that thread.

Structure static int yourshuttle_init(void) { //create an proc entry //set function pointers } static

Structure static int yourshuttle_init(void) { //create an proc entry //set function pointers } static void yourshuttle_exit(void) { //reset function pointers to null //remove module data file module_init(yourshuttle_init); module_exit(yourshuttle_exit);

Structure int yourstartshuttle(void) { //initilization //kthread_run } int yourissuerequest(pass_type, initial_terminal, dest_terminal) { //add pass

Structure int yourstartshuttle(void) { //initilization //kthread_run } int yourissuerequest(pass_type, initial_terminal, dest_terminal) { //add pass } int yourstopshuttle(void) { //release resources

Add one 1 shuttle 2 3 4 5

Add one 1 shuttle 2 3 4 5

Good 1 shuttle 2 3 4 5

Good 1 shuttle 2 3 4 5

Remove one 1 shuttle 2 3 4 5

Remove one 1 shuttle 2 3 4 5

Good 1 shuttle 2 3 4 5

Good 1 shuttle 2 3 4 5

Simultaneously 1 shuttle 2 3 4 5

Simultaneously 1 shuttle 2 3 4 5

1 shuttle 2 3 4 5

1 shuttle 2 3 4 5

Bad 1 shuttle 2 3 4 5

Bad 1 shuttle 2 3 4 5

That is correct 1 shuttle 2 3 4 5

That is correct 1 shuttle 2 3 4 5

Why • Two processes(threads) are accessing the same data. • The order of doing

Why • Two processes(threads) are accessing the same data. • The order of doing things matters. • Potential problem, unpredictable.

Concurrency problem? • User space: – start_taxi, issue_request, stop_taxi • Kernel space: – simulate

Concurrency problem? • User space: – start_taxi, issue_request, stop_taxi • Kernel space: – simulate the shuttle and the queues • Bad thing happens if they are accessing the same queue.

Protection • There can not be multiple threads accessing the same data, simultaneously. •

Protection • There can not be multiple threads accessing the same data, simultaneously. • User space – add one passenger to the queue • Kernel space – remove one passenger from the queue

"Lock" • The solution is to use lock. • When a thread wants to

"Lock" • The solution is to use lock. • When a thread wants to access the queue, it first check if it is locked: – if yes, then it waits until it becomes unlocked – if no, then it is fine to move on.

 • Add one lock before accessing the data; • Remove the lock after

• Add one lock before accessing the data; • Remove the lock after accessing the data; • What is a lock – mutex – semaphore – atom –. . .

Mutex • Semaphone is old. . . do not use semaphone. • Use mutex.

Mutex • Semaphone is old. . . do not use semaphone. • Use mutex. • Put a pair of mutex lock before and after the critical section.

mutex struct mutex lock; mutex_init(&lock); mutex_lock(&lock); {. . . } mutex_unlock(&lock);

mutex struct mutex lock; mutex_init(&lock); mutex_lock(&lock); {. . . } mutex_unlock(&lock);

Mutex Kernel Module (Prepares Lock) struct mutex m; mutex_init(&m); User-space Code (Adds Alice) mutex_lock(&m)

Mutex Kernel Module (Prepares Lock) struct mutex m; mutex_init(&m); User-space Code (Adds Alice) mutex_lock(&m) list_item->data = Alice list_item->next = NULL list_item->prev = bob_item Queue->last = list_item mutex_unlock(&m); Kernel Module (Removes Bob) mutex_lock(&m) newlast = list_item->last->prev newlast->next = NULL delete Queue->last = newlast mutex_unlock(&m)

Mutex Kernel Module (Prepares Lock) struct mutex m; mutex_init(&m); User-space Code (Adds Alice) Requests

Mutex Kernel Module (Prepares Lock) struct mutex m; mutex_init(&m); User-space Code (Adds Alice) Requests lock Receives it mutex_lock(&m) list_item->data = Alice list_item->next = NULL list_item->prev = bob_item Queue->last = list_item mutex_unlock(&m); Kernel Module (Removes Bob) mutex_lock(&m) newlast = list_item->last->prev newlast->next = NULL delete Queue->last = newlast mutex_unlock(&m)

Mutex Kernel Module (Prepares Lock) struct mutex m; mutex_init(&m); User-space Code (Adds Alice) Doing

Mutex Kernel Module (Prepares Lock) struct mutex m; mutex_init(&m); User-space Code (Adds Alice) Doing stuff mutex_lock(&m) list_item->data = Alice list_item->next = NULL list_item->prev = bob_item Queue->last = list_item mutex_unlock(&m); Kernel Module (Removes Bob) mutex_lock(&m) newlast = list_item->last->prev newlast->next = NULL delete Queue->last = newlast mutex_unlock(&m)

Mutex Kernel Module (Prepares Lock) struct mutex m; mutex_init(&m); User-space Code Requests lock (Adds

Mutex Kernel Module (Prepares Lock) struct mutex m; mutex_init(&m); User-space Code Requests lock (Adds Alice) Already locked Waits. . . mutex_lock(&m) list_item->data = Alice list_item->next = NULL list_item->prev = bob_item Queue->last = list_item mutex_unlock(&m); Kernel Module (Removes Bob) mutex_lock(&m) newlast = list_item->last->prev newlast->next = NULL delete Queue->last = newlast mutex_unlock(&m)

Mutex Kernel Module (Prepares Lock) struct mutex m; mutex_init(&m); User-space Code (Adds Alice) Releases

Mutex Kernel Module (Prepares Lock) struct mutex m; mutex_init(&m); User-space Code (Adds Alice) Releases lock Notifies threads mutex_lock(&m) list_item->data = Alice list_item->next = NULL list_item->prev = bob_item Queue->last = list_item mutex_unlock(&m); Kernel Module (Removes Bob) mutex_lock(&m) newlast = list_item->last->prev newlast->next = NULL delete Queue->last = newlast mutex_unlock(&m)

Mutex Kernel Module (Prepares Lock) struct mutex m; mutex_init(&m); User-space Code Wakes up (Adds

Mutex Kernel Module (Prepares Lock) struct mutex m; mutex_init(&m); User-space Code Wakes up (Adds Alice) Requests lock Gets lock mutex_lock(&m) list_item->data = Alice list_item->next = NULL list_item->prev = bob_item Queue->last = list_item mutex_unlock(&m); Kernel Module (Removes Bob) mutex_lock(&m) newlast = list_item->last->prev newlast->next = NULL delete Queue->last = newlast mutex_unlock(&m)