





















Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
Shared variables in threaded c programs, focusing on critical sections and synchronization. It covers the memory model for threads, variable mapping to memory instances, and the importance of controlling cooperation between threads using synchronization. The document also includes examples of threads accessing each other's stacks and the impact of incorrect ordering on concurrent execution.
Typology: Slides
1 / 29
This page cannot be seen from the preview
Don't miss anything!






















Threads Memory Model
Each thread runs in the context of a process. Each thread has its own separate thread context.
Thread ID, stack, stack pointer, program counter, condition codes, and general purpose registers.
All threads share the remaining process context.
Code, data, heap, and shared library segments of the process virtual address space.
Open files and installed handlers
While register values are truly separate and protected....
Any thread can read and write the stack of any other thread.
What resources are shared?
refer to data on the stack, each thread has its own stack never pass/share/store a pointer to a local variable on another thread’s stack!
stored in the static data segment, accessible by any thread
stored in the heap, shared if you can name it
in C, can conjure up the pointer e.g., void *x = (void *) 0xDEADBEEF
in Java, strong typing prevents this
must pass references explicitly
must assume threads interleave executions arbitrarily and at different rates scheduling is not under application writers’ control
enables us to restrict the interleaving of executions
Example of Threads Accessing
Another Thread’s Stack
**char ptr; / global /
**int main() { int i; pthread_t tid; char msgs[2] = { "Hello from foo", "Hello from bar" }; ptr = msgs; for (i = 0; i < 2; i++) Pthread_create(&tid, NULL, thread, (void )i); Pthread_exit(NULL); }
*/ thread routine */ void thread(void vargp) { int myid = (int)vargp; static int svar = 0;
printf("[%d]: %s (svar=%d)\n", myid, ptr[myid], ++svar); }
Shared Variable Analysis
ptr, svar, and msgs are shared.
i and myid are NOT shared.
badcnt.c: An Improperly Synchronized
Threaded Program
unsigned int cnt = 0; / shared / #define NITERS 100000000 int main() { pthread_t tid1, tid2; Pthread_create(&tid1, NULL, count, NULL); Pthread_create(&tid2, NULL, count, NULL);
Pthread_join(tid1, NULL); Pthread_join(tid2, NULL);
if (cnt != (unsigned)NITERS2) printf("BOOM! cnt=%d\n", cnt); else printf("OK cnt=%d\n", cnt); }*
*/ thread routine */ void count(void arg) { int i; for (i=0; i<NITERS; i++) cnt++; return NULL; }
linux> ./badcnt BOOM! cnt=
linux> ./badcnt BOOM! cnt=
linux> ./badcnt BOOM! cnt=
cnt should be
equal to 200,000,000.
What went wrong?!
Concurrent Execution
Ii denotes that thread i executes instruction I %eaxi is the contents of %eax in thread i’s context
H 1 L 1 U 1 S 1 H 2 L 2 U 2 S 2 T 2 T 1
1 1 1 1 2 2 2 2 2 1
i (thread) (^) instri %eax 1 cnt
%eax 2
Concurrent Execution (cont)
H 1 L 1 U 1 H 2 L 2 S 1 T 1 U 2 S 2 T 2
1 1 1 2 2 1 1 2 2 2
i (thread) (^) instri %eax 1 cnt
%eax 2
Progress Graphs
H 2
L 2
U 2
S 2
T 2
Thread 1
Thread 2
(L 1 , S 2 )
Trajectories in Progress Graphs
H 1 L 1 U 1 S 1 T 1
H 2
L 2
U 2
S 2
T 2
Thread 1
Thread 2
Safe and Unsafe Trajectories
H 1 L 1 U 1 S 1 T 1
H 2
L 2
U 2
S 2
T 2
Thread 1
Thread 2
Unsafe region (^) Unsafe trajectory
Safe trajectory
critical section wrt cnt
critical section wrt cnt
int withdraw(account, amount) {
int balance = get_balance(account);
balance -= amount; put_balance(account, balance);
return balance;
}
what happens if you both go to separate ATM machines, and simultaneously withdraw $10.00 from the account?