lecture 14: mutual exclusion, locks and barrier with pthreadspthread_mutex_lock blocks the calling...

35
Lecture 14: Mutual Exclusion, Locks and Barrier with PThreads Concurrent and Mul=core Programming Department of Computer Science and Engineering Yonghong Yan [email protected] www.secs.oakland.edu/~yan 1

Upload: others

Post on 10-Oct-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

Lecture14:MutualExclusion,LocksandBarrierwithPThreads

ConcurrentandMul=coreProgramming

DepartmentofComputerScienceandEngineeringYonghongYan

[email protected]/~yan

1

Page 2: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

ReviewandOverview

•  ThreadbasicsandthePOSIXThreadAPI–  Processvsthreads

•  ThreadcreaHon,terminaHonandjoining–  pthread_create,pthread_joinandpthread_exit–  BoxingmulHpleargumentsinstructtopasstothreadfuncHon

•  Threadsafety•  Synchroniza=onprimi=vesinPthreads

–  Mutualexclusion,locksandbarrier

2

Page 3: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

DataRacinginaMul=threadProgramConsider:/* each thread to update shared variable best_cost */ !

!if (my_cost < best_cost) !

best_cost = my_cost;

–  twothreads,–  theiniHalvalueofbest_costis100,–  thevaluesofmy_costare50and75forthreadst1andt2!!

best_cost = my_cost;•  Thevalueofbest_costcouldbe50or75!•  Thevalue75doesnotcorrespondtoanyserializaHonofthetwo

threads.

3

T1 T2

if (my_cost (50) < best_cost)! !

best_cost = my_cost;

if (my_cost (75) < best_cost)!!

best_cost = my_cost;

Page 4: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

SameSitua=onforReading/Upda=ngaSingleVariable

intcount=0;int*cp=&count;….*cp++;/*bytwothreads*/

4Picturesfromwikipedia:h[p://en.wikipedia.org/wiki/Race_condiHon

Page 5: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

Whythishappens

Read/writetothesameloca=onbythetwothreadsinterleaved

5

Page 6: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

GeneralSolu=on:Cri=calSec=onandMutualExclusion

•  CriHcalsecHon=asegmentthatmustbeexecutedbyonlyonethreadatanyHme ! !!

•  MutexlocksprotectcriHcalsecHonsinPthreads–  lockedandunlocked–  AtanypointofHme,onlyonethreadcanacquireamutexlock

•  Usingmutexlocks–  requestlockbeforeexecuHngcriHcalsecHon–  entercriHcalsecHonwhenlockgranted–  releaselockwhenleavingcriHcalsecHon

if (my_cost < best_cost)! best_cost = my_cost;

6

Page 7: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

MutualExclusionusingPthreadMutexint pthread_mutex_lock (pthread_mutex_t *mutex_lock); !int pthread_mutex_unlock (pthread_mutex_t *mutex_lock); !int pthread_mutex_init (pthread_mutex_t !*mutex_lock,! const pthread_mutexattr_t *lock_attr);!

pthread_mutex_tcost_lock;intmain(){...pthread_mutex_init(&cost_lock,NULL);pthread_create(&thhandle,NULL,find_best,…)...}void*find_best(void*list_ptr){...pthread_mutex_lock(&cost_lock);//enterCSif(my_cost<best_cost)best_cost=my_cost;pthread_mutex_unlock(&cost_lock);//leaveCS}

Cri=calSec=on

pthread_mutex_lockblocksthecallingthreadifanotherthreadholdsthelockWhenpthread_mutex_lockcallreturns1.  Mutexislocked,enterCS2.  Anyotherlockinga[empt(callto

thread_mutex_lock)willcausetheblockingofthecallingthread

Whenpthread_mutex_unlockreturns1.  Mutexisunlocked,leaveCS2.  Onethreadwhoblockson

thread_mutex_lockcallwillacquirethelockandenterCS

7

Page 8: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

Producer-ConsumerUsingLocksConstrains:•  Theproducerthreads

–  mustnotoverwritethesharedbufferwhentheprevioustaskhasnotbeenpickedupbyaconsumerthread.

•  Theconsumerthreads–  mustnotpickuptasksunHlthereissomethingpresentinthe

shareddatastructure.–  IndividualconsumerthreadshouldpickuptasksoneataHme

Conten=on:–  Betweenproducers–  Betweenconsumers–  Betweenproducersandconsumers

8

Page 9: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

Producer-ConsumerUsingLockspthread_mutex_t task_queue_lock; int task_available; main() {

.... task_available = 0; pthread_mutex_init(&task_queue_lock, NULL); ....

}

9

void *producer(void *producer_thread_data) { .... while (!done()) { inserted = 0; create_task(&my_task); while (inserted == 0) { pthread_mutex_lock(&task_queue_lock); if (task_available == 0) { insert_into_queue(my_task); task_available = 1; inserted = 1; } pthread_mutex_unlock(&task_queue_lock); } } }

void *consumer(void *consumer_thread_data) { int extracted; struct task my_task; while (!done()) { extracted = 0; while (extracted == 0) { pthread_mutex_lock(&task_queue_lock); if (task_available == 1) { extract_from_queue(&my_task); task_available = 0; extracted = 1; } pthread_mutex_unlock(&task_queue_lock); } process_task(my_task); } }

Cri=calSec=on

Notethepurposeofinsertedandextracedvariables

Page 10: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

ThreeTypesofMutexes

•  Normal–  Deadlocksifathreadalreadyhasalockandtriesasecondlockonit.

•  Recursive–  AllowsasinglethreadtolockamutexasmanyHmesasitwants.

•  Itsimplyincrementsacountonthenumberoflocks.–  Alockisrelinquishedbyathreadwhenthecountbecomeszero.

•  Errorcheck–  Reportsanerrorwhenathreadwithalocktriestolockitagain(as

opposedtodeadlockinginthefirstcase,orgranHngthelock,asinthesecondcase).

•  Thetypeofthemutexcanbesetinthea[ributesobjectbeforeitispassedatHmeofiniHalizaHon–  pthread_mutex_a[r_init

10

Page 11: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

OverheadsofLocking

11

•  LocksenforceserializaHon–  ThreadmustexecutecriHcalsecHonsoneameranother

•  LargecriHcalsecHonscanleadtosignificantperformancedegradaHon.

•  Reducetheblockingoverheadassociatedwithlocksusing:

int pthread_mutex_trylock ( pthread_mutex_t *mutex_lock);

–  acquirelockifavailable–  returnEBUSYifnotavailable–  enablesathreadtodosomethingelseiflockunavailable

•  pthreadtrylocktypicallymuchfasterthanlockoncertainsystems

–  ItdoesnothavetodealwithqueuesassociatedwithlocksformulHplethreadswaiHngonthelock.

Page 12: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

12

Condi=onVariablesforSynchroniza=on

Acondi=onvariable:associatedwithapredicateandamutex–  AsyncvariableforacondiHon,e.g.mybalance>500

•  AthreadcanblockitselfunHlacondiHonbecomestrue

–  Whenblocked,releasemutexsootherscanacquireit•  WhenacondiHonbecomestrue,observedbyanotherthread,thecondiHonvariableisusedtosignalotherthreadswhoareblocked

•  AcondiHonvariablealwayshasamutexassociatedwithit.–  AthreadlocksthismutexandteststhecondiHon

Page 13: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

13

Condi=onVariablesforSynchroniza=on/*theopaquedatastructure*/pthread_cond_t!/*ini=aliza=onanddestroying*/int pthread_cond_init(pthread_cond_t *cond, ! const pthread_condattr_t *attr); !

int pthread_cond_destroy(pthread_cond_t *cond); !!/*blockandreleaselockun=lacondi=onistrue*/int pthread_cond_wait(pthread_cond_t *cond, ! pthread_mutex_t *mutex);!int pthread_cond_timedwait(pthread_cond_t *cond, !pthread_mutex_t *mutex, const struct timespec *wtime);! !/*signaloneorallwai=ngthreadsthatcondi=onistrue*/int pthread_cond_signal(pthread_cond_t *cond); !int pthread_cond_broadcast(pthread_cond_t *cond);

Page 14: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

pthread_cond_t cond_queue_empty, cond_queue_full; !pthread_mutex_t task_queue_cond_lock; !int task_available; !/* other data structures here */ !!main() { !/* declarations and initializations */ !task_available = 0; !pthread_cond_init(&cond_queue_empty, NULL); !pthread_cond_init(&cond_queue_full, NULL); !pthread_mutex_init(&task_queue_cond_lock, NULL); !/* create and join producer and consumer threads */ !

} !

14

Producer-ConsumerUsingCondi=onVariables

•  TwocondiHons:•  Queueisfull:(task_available==1)ßcond_queue_full•  Queueisempty:(task_available==0)ßcond_queue_empty

•  AmutexforprotecHngaccessingthequeue(CS):task_queue_cond_lock

Page 15: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

void *producer(void *producer_thread_data) { !int inserted; !while (!done()) { !

create_task(); !pthread_mutex_lock(&task_queue_cond_lock);! !while (task_available == 1) !pthread_cond_wait(&cond_queue_empty,! &task_queue_cond_lock);! !

insert_into_queue(); !task_available = 1; CS!!pthread_cond_signal(&cond_queue_full);! !pthread_mutex_unlock(&task_queue_cond_lock); !

} !} !

15

Producer-ConsumerUsingCondi=onVariables

Releasemutex(unlock)whenblocked/wait

Acquiremutex(lock)whenawaken

Producer:1.   Waitforqueuetobecomeempty,no=fiedbyconsumerthroughcond_queue_empty2.   insertintoqueue3.   Signalconsumerthroughcond_queue_full

1

2

3

Page 16: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

void *consumer(void *consumer_thread_data) { !while (!done()) { !pthread_mutex_lock(&task_queue_cond_lock);! !while (task_available == 0) !

pthread_cond_wait(&cond_queue_full, !&task_queue_cond_lock); !!

my_task = extract_from_queue(); !task_available = 0; !!pthread_cond_signal(&cond_queue_empty);! !pthread_mutex_unlock(&task_queue_cond_lock); !process_task(my_task); !

} !} !

16

Consumer:1.   Waitforqueuetobecomefull,no=fiedbyproducerthroughcond_queue_full2.   Extracttaskfromqueue3.   Signalproducerthroughcond_queue_empty

Releasemutex(unlock)whenblocked/wait

Acquiremutex(lock)whenawaken

Producer-ConsumerUsingCondi=onVariables

1

2

3

Page 17: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

ThreadandSynchroniza=onA^ributes

•  Threemajorobjects–  pthread_t–  pthread_mutex_t–  pthread_cond_t

•  Defaulta[ributeswhenbeingcreated/iniHalized–  NULL

•  Ana[ributesobjectisadata-structurethatdescribesenHty(thread,mutex,condiHonvariable)properHes.–  OncetheseproperHesareset,thea[ributesobjectcanbe

passedtothemethodiniHalizingtheenHty.–  Enhancesmodularity,readability,andeaseofmodificaHon.

17

Page 18: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

A^ributesObjectsforThreads

18

•  IniHalizeana[ributeobjectsusingpthread_attr_init!

•  IndividualproperHesassociatedwiththea[ributesobjectcanbechangedusingthefollowingfuncHons:pthread_attr_setdetachstate, !pthread_attr_setguardsize_np, !pthread_attr_setstacksize, !pthread_attr_setinheritsched,!pthread_attr_setschedpolicy, and!pthread_attr_setschedparam !

Page 19: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

A^ributesObjectsforMutexes

19

•  IniHalizeana[ributesobjectusingfuncHon:pthread_mutexattr_init.

•  pthread_mutexa^r_se^ype_npforseqngthemutextypepthread_mutexa^r_se^ype_np(pthread_mutexa^r_t*a^r,inttype); !

•  Specifictypes:–  PTHREAD_MUTEX_NORMAL_NP–  PTHREAD_MUTEX_RECURSIVE_NP–  PTHREAD_MUTEX_ERRORCHECK_NP

Page 20: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

A^ributesObjectsforCondi=onVariable

•  IniHalizeana[ributeobjectusingpthread_condattr_init

•  int pthread_conda^r_setpshared(pthread_conda^r_t*ca^r,intpshared)tospecifiesthescopeofacondiHonvariabletoeitherprocessprivate(intraprocess)orsystemwide(interprocess)viapshared–  PTHREAD_PROCESS_SHARED–  PTHREAD_PROCESS_PRIVATE

20

Page 21: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

•  PthreadMutexandCondi=onVariablesaretwobasicsyncoperaHons.

•  Higherlevelconstructscanbebuiltusingbasicconstructs.–  Read-writelocks–  Barriers

•  PthreadhasitscorrespondingimplementaHon–  pthread_rwlock_t–  pthread_barrier_t

•  WewilldiscussourownimplementaHons

21

CompositeSynchroniza=onConstructs

Page 22: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

22

Read-WriteLocks

•  Concurrentaccesstodatastructure:–  Readfrequentlybut–  Wri[eninfrequently

•  Behavior:–  Concurrentread:Areadrequestisgrantedwhenthereare

otherreadsornowrite(pendingwriterequest).–  Exclusivewrite:Awriterequestisgrantedonlyifthereisno

writeorpendingwriterequest,orreads.•  Interfaces:

–  Therwlockdatastructure:structmylib_rwlock_t–  Readlock:mylib_rwlock_rlock–  writelock:mylib_rwlock_wlock–  Unlock:mylib_rwlock_unlock.

Page 23: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

•  Twotypesofmutualexclusions–  0/1mutexforprotecHngaccesstowrite–  Countermutex(semaphore)forcounHngreadaccess

•  Componentsketch–  acountofthenumberofreaders,–  0/1integerspecifyingwhetherawriterispresent,–  acondiHonvariablereaders_proceedthatissignaledwhenreaders

canproceed,–  acondiHonvariablewriter_proceedthatissignaledwhenoneofthe

writerscanproceed,–  acountpending_writersofpendingwriters,and–  apthread_mutex_tread_write_lockassociatedwiththeshareddata

structure

23

Read-WriteLocks

Page 24: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

24

Read-WriteLocks

typedef struct { !int readers; !int writer; !pthread_cond_t readers_proceed; !pthread_cond_t writer_proceed; !int pending_writers; !pthread_mutex_t read_write_lock; !

} mylib_rwlock_t; !!void mylib_rwlock_init (mylib_rwlock_t *l) { !l->readers=0; l->writer=0; l->pending_writers=0; !pthread_mutex_init(&(l->read_write_lock), NULL); !pthread_cond_init(&(l->readers_proceed), NULL); !pthread_cond_init(&(l->writer_proceed), NULL); !

} !

Page 25: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

Read-WriteLocks

void mylib_rwlock_rlock(mylib_rwlock_t *l) { !pthread_mutex_lock(&(l->read_write_lock)); !!while ((l->pending_writers > 0) || (l->writer > 0)) !

pthread_cond_wait(&(l->readers_proceed), !&(l->read_write_lock)); !!

l->readers ++; !!pthread_mutex_unlock(&(l->read_write_lock)); !

} !

25

Readerlock:1.   ifthereisawriteorpendingwriters,performcondi=onwait,2.   elseincrementcountofreadersandgrantreadlock

1

2

Page 26: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

Read-WriteLocksvoid mylib_rwlock_wlock(mylib_rwlock_t *l) { !pthread_mutex_lock(&(1->read_write_lock)); !1->pending_writers ++; !!while ((1->writer > 0) || (1->readers > 0)) { !

pthread_cond_wait(&(1->writer_proceed), ! &(1->read_write_lock));!

} !!

1->pending_writers --; !1->writer ++; !!pthread_mutex_unlock(&(1->read_write_lock)); !

} !

26

Writerlock:1.   Iftherearereadersorwriters,incrementpendingwriters

countandwait.2.   Onbeingwoken,decrementpendingwriterscountand

incrementwritercount

1

2

Page 27: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

Read-WriteLocks

void mylib_rwlock_unlock(mylib_rwlock_t *l) { ! pthread_mutex_lock(&(1->read_write_lock)); ! if (1->writer > 0) /* only writer */! 1->writer = 0; !

else if (1->readers > 0) /* only reader */! 1->readers --; !

pthread_mutex_unlock(&(1->read_write_lock)); !! if ((1->readers == 0) && (1->pending_writers > 0)) ! pthread_cond_signal(&(1->writer_proceed)); !

else if (1->readers > 0) ! pthread_cond_broadcast(&(1->readers_proceed)); !

} !

27

Reader/Writerunlock:1.   Ifthereisawritelockthenunlock2.   Iftherearereadlocks,decrementcountofreadlocks.3.   Ifthereadcountbecomes0andthereisapendingwriter,no=fywriter4.   Otherwiseiftherearependingreaders,letthemallgothrough

1

2

3

4

Page 28: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

Barrier

•  AbarrierholdsoneormulHplethreadsunHlallthreadsparHcipaHnginthebarrierhavereachedthebarrierpoint

28

Page 29: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

Barrier

•  Needsacounter,amutexandacondi=onvariable–  Thecounterkeepstrackofthenumberofthreadsthathave

reachedthebarrier.•  Ifthecountislessthanthetotalnumberofthreads,thethreadsexecuteacondiHonwait.

–  Thelastthreadentering(master)wakesupallthethreadsusingacondiHonbroadcast.

29

typedef struct {! int count;!pthread_mutex_t count_lock;!pthread_cond_t ok_to_proceed;!

} mylib_barrier_t;!!void mylib_barrier_init(mylib_barrier_t *b) {!b->count = 0;!pthread_mutex_init(&(b->count_lock), NULL);!pthread_cond_init(&(b->ok_to_proceed), NULL);!

}!

Page 30: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

Barriers

void mylib_barrier (mylib_barrier_t *b, int num_threads) {!pthread_mutex_lock(&(b->count_lock));!!b->count ++;!if (b->count == num_threads) {!

b->count = 0;!pthread_cond_broadcast(&(b->ok_to_proceed));!

} else!while (pthread_cond_wait(&(b->ok_to_proceed),!&(b->count_lock)) != 0);!!

pthread_mutex_unlock(&(b->count_lock));!}!

30

Barrier1.   Eachthreadincrementsthecounterandcheckwhetherallreach2.   Thethread(master)whodetectthatallreachessignalotherstoproceed3.   Ifnotallreach,thethreadwaits

1

2

3

Page 31: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

Flat/LinearvsTree/LogBarrier

31

•  Linear/Flatbarrier.–  O(n)fornthread–  AsinglemastertocollectinformaHonofallthreadsandnoHfythemto

conHnue•  Tree/Logbarrier

–  Organizethreadsinatreelogically–  MulHplesubmastertocollectandnoHfy–  RunHmegrowsasO(logp).

Page 32: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

Barrier

•  ExecuHonHmeof1000sequenHalandlogarithmicbarriersasafuncHonofnumberofthreadsona32processorSGIOrigin2000.

32

Page 33: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

References

•  Adaptedfromslides“ProgrammingSharedAddressSpacePlaxorms”byAnanthGrama.BradfordNichols,DickBu[lar,JacquelineProulxFarrell.

•  “PthreadsProgramming:APOSIXStandardforBe[erMulHprocessing.”O'ReillyMedia,1996.

•  Chapter7.“IntroducHontoParallelCompuHng”byAnanthGrama,AnshulGupta,GeorgeKarypis,andVipinKumar.AddisonWesley,2003

•  Otherpthreadtopics–  intpthread_key_create(pthread_key_t*key,void(*destroy)(void*))–  intpthread_setspecific(pthread_key_tkey,constvoid*value)–  void*pthread_getspecific(pthread_key_tkey)

33

Page 34: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

Allevia=ngLockingOverhead(Example)/* Finding k matches in a list */ !void *find_entries(void *start_pointer) { !/* This is the thread function */ !struct database_record *next_record; !int count; !current_pointer = start_pointer; !do { !

next_record = find_next_entry(current_pointer); !count = output_record(next_record); !

} while (count < requested_number_of_records); !} !int output_record(struct database_record *record_ptr) { !int count; !pthread_mutex_lock(&output_count_lock); !output_count ++; !count = output_count; !pthread_mutex_unlock(&output_count_lock); !if (count <= requested_number_of_records) !

print_record(record_ptr); !return (count); !

} ! 34

Page 35: Lecture 14: Mutual Exclusion, Locks and Barrier with PThreadspthread_mutex_lock blocks the calling thread if another thread holds the lock When pthread_mutex_lock call returns 1. Mutex

Allevia=ngLockingOverhead(Example)/* rewritten output_record function */ !int output_record(struct database_record

*record_ptr) { !int count; !int lock_status; !lock_status=pthread_mutex_trylock(&output_count_lock); !if (lock_status == EBUSY) { !

insert_into_local_list(record_ptr); !return(0); !

} else { !count = output_count; !output_count += number_on_local_list + 1; !pthread_mutex_unlock(&output_count_lock); !print_records(record_ptr, local_list, !

requested_number_of_records - count); !return(count + number_on_local_list + 1); !

} !} !

35