400 likes | 544 Views
TI BIOS. Inter-Thread Comm & Synch - ITC. Introduction. Semaphores (SEM) have been used in prior chapters to synchronize threads, and are a common approach in many systems.
E N D
TI BIOS Inter-Thread Comm & Synch - ITC Dr. Veton Këpuska
Introduction • Semaphores (SEM) have been used in prior chapters to synchronize threads, and are a common approach in many systems. • While there are times that the SEM is a good choice, there are other situations in which their use can lead to problems. In this chapter, a variety of inter-thread communication and synchronization examples will be considered employing a variety of BIOS thread comm API, including: LCK MBX QUE ATM MSGQ Dr. Veton Këpuska
Inter-Thread Comm & Synch Dr. Veton Këpuska 2
Critical Section Resource Protection • Pass a copy of resources to 2nd thread • No possibility of conflict, allows both to use concurrently • Doubles storage requirements, adds copy time • Assign concurrent threads to the same priority – FIFO + No possibility of conflict, no memory/time overhead, easy - Forces involved threads to be same priority • Disable interrupts during critical sections + Needed if a hardware interrupt shares data - Affects response time of all threads in the system • Disable SWI/TSK scheduler during critical section + Assures one SWI/TSK to finish with resource before another begins - Affects the response times of all other SWIs Dr. Veton Këpuska
Critical Section Resource Protection • Raise priority of SWI/TSK during critical section * Set priority to highest priority which may access the resource + Equal priority SWIs/TSKs run in FIFO order, avoiding competition - Can affect response times of SWIs/TSKs of intervening priority • Use atomic functions on shared resources + Imposes minimal jitter on interrupt latencies - Only allows minimal actions on shared resources • Regulate access rights viaSemaphores + No conflict or memory/time overhead of passing copy - Multiple semaphore schemes can introduce problems Dr. Veton Këpuska
Module Topics Dr. Veton Këpuska 2
Atm – Atomic Functions Dr. Veton Këpuska
DSP/BIOS Atomic Functions • Allows thread to manipulate variables without interrupt intervention • Are C callable functions optimized in assembly • Allows reliable use of global variables shared between SWI and HWI ATM_decATM_inc - Good for inter-thread counters ATM_clearATM_set - Counters - to start/restart - Generic pass of value between threads ATM_andATM_or - Perform boolean op’s on shared variables - Good for event flags, etc x 10 11? 10/0 11 TSK … x = x+1; LD reg, x ADD reg, 1 ST x, reg … a HWI ... for(x...) x = 0; ... Dr. Veton Këpuska
Module Topics Dr. Veton Këpuska 2
sem – sEMAPHORES Dr. Veton Këpuska
Synchronization Semaphore A and B same priority, A is ready before B SEM_pend(semObj) Priority=1 B SEM_post(semObj) Priority=1 A time B higher priority than A, B is ready before A SEM_pend(semObj) block! Priority=2 Not dependent on A Depends on A B SEM_post(semObj) preempted! Priority=1 Precondition for B A time Dr. Veton Këpuska
Semaphores and Priority • Both B and C depend on A • B depends on the semaphore first, then C • When A posts, B runs first because it pended first • Semaphores use a FIFO Queue for pending tasks! Dr. Veton Këpuska
Semaphores and Priority SEM_pend(&semObj) block! interrupt! Priority=2 Not dependent on A C SEM_pend(&semObj) block! Priority=1 Depends on A Not dependent on A B SEM_post(&semObj) preempted! Priority=1 Precondition for B and C A time Dr. Veton Këpuska
Mutual Exclusion Semaphore • Two or more tasks need concurrent access to a serial reusable resource • Mutual exclusion using semaphore • Initialize semaphore count to 1 • pend before accessing resource - lock out other task(s) • post after accessing resource - allow other task(s) Void task0() { SEM_pend(&semMutex); `critical section`SEM_post(&semMutex); } Void task1() { SEM_pend(&semMutex); `critical section` SEM_post(&semMutex); } Priority=2 SEM_pend(&semMutex)block! SEM_post(&semMutex) Task1 SEM_post(&semMutex)preempted! SEM_pend(&semMutex) Priority=1 Task0 Dr. Veton Këpuska
Mutual Exclusion Semaphore • Problems may occur when tasks compete for more than one resource • Priority inversion • Deadlock Dr. Veton Këpuska
Priority Inversion High-priority tasks block while waiting for lower-priority tasks to relinquish semaphore Priority Pend(mutex) blocks post (mutex) higher B B C Initially Mutex = 1 D Post(mutex) preempted Pend(mutex) interrupt! lower A A Time Dr. Veton Këpuska
Priority Inversion “The failure turned out to be a case of priority inversion” — Mars Pathfinder Flight Software Cognizant Engineer Dr. Veton Këpuska
Inversion Solution: Priority Inheritance Interruptreadies B Elevate task priority before calling accessing resource Lower task priority after accessing resource Priority post(mutex), setpri(A,oldpri) pend(mutex) A B pend(mutex) C post(mutex) D setpri(A,newpri) lower A A time Dr. Veton Këpuska
Question: Do we even need to use semaphore in this situation? - No • Do not use TSK_yield() if semaphore is removed Dr. Veton Këpuska
Deadlock • Also known as deadly embrace • Tasks cannot complete because they have blocked each other • TaskA and TaskB require the use of resource 1 and 2. • Neither task will release a resource until it is completed static Void TaskB() {SEM_pend(&res_2); //use resource2 Task_B may get stuck here SEM_pend(&res_1); //use resource1 SEM_post(&res_2); SEM_post(&res_1); } static Void TaskA() { SEM_pend(&res_1); // use resource1 Task_A may get stuck here SEM_pend(&res_2); // use resource2 SEM_post(&res_1); SEM_post(&res_2); } Dr. Veton Këpuska
Deadlock Conditions • Mutual exclusion : Access to shared resource protected with mutual exclusion SEM • Circular pend: Circular chain of tasks hold resources that are needed by others in the chain (cyclic processing) • Multiple pend and wait: Tasks lock more than one resource at a time • Preemption: Tasks needing mutual exclusion are at a different priorities Dr. Veton Këpuska
Deadlock: Detect, Recover, Eliminate • Difficult to detect • May happen infrequently • Use timeouts in blocking API; monitor timeout via SYS_error • Monitor SWI with implicit STS • Recover is not easy • Reset the system • Rollback to a pre-deadlock state • Solution • Careful design • Rigorous testing Dr. Veton Këpuska
Deadlock: Detect, Recover, Eliminate • Eliminating Deadlock: Remove one of these conditions • Mutual exclusion: Make resources sharable • Circular pend: Set a particular order • Multiple pend and post: Lock only one resource at a time or all resources that will be used (starvation potential) • Preemption: Assign tasks that need mutual exclusivity to the same priority • Better:Use more sophisticated BIOS API Dr. Veton Këpuska
Module Topics Dr. Veton Këpuska 2
LCK – Lock Dr. Veton Këpuska
Nested Semaphore Calls: LCK Use of SEMaphore with nested pendyields permanent block Void Task_A() { SEM_pend(&semUser); funcInner(); SEM_post(&semUser); } Void funcInner() { SEM_pend(&semUser); // use resource guarded by semSEM_post(&semUser); } Unrecoverableblocking call Use of LCK (Lock) with nested pendavoids blockout Void Task_A() { LCK_pend(&lckUser); funcInner(); LCK_post(&lckUser); } Void funcInner() { LCK_pend(&lckUser); // use resource guarded by lckLCK_post(&lckUser); } Dr. Veton Këpuska
Nested Semaphore Calls: LCK • BIOS MEM Manager and selected RTS functions internally use LCK, can cause TSK switch Dr. Veton Këpuska
Module Topics Dr. Veton Këpuska 2
MBX – Mailbox Dr. Veton Këpuska
MBX_pend MBX_post MBX_create MBX_delete MBX Mailbox NOTE: The MBX API are not related to the mailbox component of the SWI object! + mailbox message can be any desired structure + semaphore signaling built in (read and write) + allows multiple readers and/or writers - fixed depth of messaging - copy based – 2 copies made in/out of MBX Dr. Veton Këpuska
Example: Passing Buffer Info Via Mailbox MBX_post - add message to end of mailbox typedefstructMsgObj { Intlen; Int * addr; }; Void writer(Void) { MsgObjmsg; IntmyBuf[SIZE]; ... msg.addr = myBuf; msg.len = SIZE*sizeof(Int); MBX_post(&mbx, &msg, SYS_FOREVER); ... } block if MBX is already full handle to msgobj * msg to put/get timeout MBX_pend - get next message from mailbox Void reader(Void) { MsgObj mail; Int size, *buf; ... MBX_pend(&mbx, &mail,SYS_FOREVER); buf = mail.addr; size = mail.len; ... } block until mail received or timeout Dr. Veton Këpuska
Message Object creation via TCONF MBX.OBJMEMSEG = prog.get(“ISRAM"); varmyMBX = MBX.create("myMBX"); myMBX.comment = "my MBX"; myMBX.messageSize = 1; myMBX.length = 1; myMBX.elementSeg = prog.get(“IRAM"); Creating Mailbox Objects Message Object creation via GCONF Dynamic Message Object Creation hMbx = MBX_create(msgsize, mbxlen, attrs); MBX_delete(hMbx); structMBX_Attrs { Intsegid;} Message Size = MADUs per message Mailbox Length = max # messages queued Dr. Veton Këpuska
Module Topics Dr. Veton Këpuska 2
QUE - Queue Dr. Veton Këpuska
TTO Technical Training Organization QUE - Queue + any number of messages can be passed + message can be anything desired (beginning with QUE_elem) + atomic API are provided to assure correct sequencing - no semaphore signaling built in 19
Queues : QUE • QUE message is anything you like, starting with QUE_Elem • QUE_Elemis a set of pointers that BIOS uses to manage a double linked list • Items queued are NOT copied – only the QUE_Elemptrs are managed! Dr. Veton Këpuska
Queues : QUE structMyMessage { QUE_Elemelem; first field for QUE Int x[1000]; array/structure sent notcopy based! } Message1; typedefstructQUE_Elem { structQUE_Elem *next; structQUE_Elem *prev; } QUE_Elem; QUE_put(hQue,*msg3) add message to end of queue (writer) QUE_Obj msg1 msg2 msg3 *elem = QUE_get(hQue) get message from front of queue (reader) msg1 QUE_Obj msg2 msg3 Dr. Veton Këpuska
QUE API Summary Mod 10 Dr. Veton Këpuska
TTO Technical Training Organization “Synchronous QUE” Option Talker QUE_put(&myQ,msg); SEM_post(&myQSem); Listener SEM_pend(&myQSem,-1); msg=QUE_get(&myQ); 23
BIOS Instrumentation:Inter-Thread Comm & Synch - ITC END Dr. Veton Këpuska