0% found this document useful (0 votes)
66 views18 pages

Chapter 07

This document discusses semaphore management in an operating system kernel. It describes how to create and delete semaphores using functions like OSSemCreate() and OSSemDel(). It explains how tasks and interrupts can pend and post to semaphores using functions like OSSemPend() and OSSemPost(). It provides examples of how semaphores are used to synchronize access between tasks and ensure mutual exclusion.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
66 views18 pages

Chapter 07

This document discusses semaphore management in an operating system kernel. It describes how to create and delete semaphores using functions like OSSemCreate() and OSSemDel(). It explains how tasks and interrupts can pend and post to semaphores using functions like OSSemPend() and OSSemPost(). It provides examples of how semaphores are used to synchronize access between tasks and ensure mutual exclusion.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 18

Chapter 7:

Semaphore Management

1
Semaphores
• A 16-bit unsigned integer used to hold the
semaphore count (0 to 65535)
– Counting semaphore

• Create a semaphore by calling OSSemCreate( )


– Specify the initial value of a semaphore

2
Semaphore Management
• OSSemCreate()
Creating a semaphore
• OSSemDel()
Deleting a semaphore
• OSSemPend
Waiting on a semaphore
• OSSemPost
Signaling a semaphore
• OSSemAccept()
Getting a Semaphore without waiting

3
Relationships between tasks,ISR, and a
semaphore

OSSemPend()
OSSemAccept() Task
Task OSSemPost() OSSemQuery()
N
OR

ISR OSSemPost() OSSemAccept()


OSSemAccept() ISR
N

4
OSSemCreate()

All kernel objects need to be created from task-level


code or before multitasking starting

Obtain a free ECB

Clear OSEventGrp and OSEventTbl[]

5
OSSemDel()
• pevent is a pointer to the ECB associated with
the desired semaphore.
• opt determines delete options as follows:
– OS_DEL_NO_PEND
Delete semaphore ONLY if no task pending
– OS_DEL_ALWAYS
Deletes the semaphore even if tasks are waiting. In this
case, all the tasks pending will be readied.

6
OSSemDel()
Event Control Block
opt =?

EventGrp 1 1 DEL_ALWAYS DEL_NO_PEND

N
EventGrp = 0 EventGrp = 0
Y
1
EventTbl N Y
1 1
EventTaskRdy
EventTaskRdy Free(Sem)
N

EventGrp ==00
EventGrp
reterun err

Y 7
OSSemDel()
OS_EVENT *OSSemDel (OS_EVENT *pevent, INT8U opt, INT8U *err) {
OS_ENTER_CRITICAL();
if (pevent->OSEventGrp != 0x00) { See if any tasks waiting on semaphore
tasks_waiting = TRUE;
} else tasks_waiting = FALSE; Delete semaphore only if no task waiting
switch (opt) {
case OS_DEL_NO_PEND: Return Event
if (tasks_waiting == FALSE) { Control Block to
pevent->OSEventType = OS_EVENT_TYPE_UNUSED; free list
pevent->OSEventPtr = OSEventFreeList;
OSEventFreeList = pevent;
OS_EXIT_CRITICAL();
*err = OS_NO_ERR;
return ((OS_EVENT *)0);
} else {
OS_EXIT_CRITICAL();
*err = OS_ERR_TASK_WAITING;
return (pevent); 8
}
OSSemDel()
case OS_DEL_ALWAYS: Always delete the semaphore
while (pevent->OSEventGrp != 0x00) { Ready ALL
OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM); tasks waiting
} for semaphore
pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
pevent->OSEventPtr = OSEventFreeList;
OSEventFreeList = pevent;
OS_EXIT_CRITICAL();
if (tasks_waiting == TRUE) {
OS_Sched();
}
*err = OS_NO_ERR;
return ((OS_EVENT *)0);

default:
OS_EXIT_CRITICAL();
*err = OS_ERR_INVALID_OPT;
return (pevent);
}
9
}
OSSemDel()
• This call can potentially disable interrupts for a
long time.
– The interrupt disable time is directly proportional
to the number of tasks waiting on the semaphore.
• Because all tasks pending on the semaphore
will be readied, you must be careful in
applications where the semaphore is used for
mutual exclusion.

10
OSSemPend()
Example 1: OSEventCnt=1
task1() {
/*…*/
OSSemPend();
/*…*/
}

User mode

OSSemPend() { Kernel mode

?(OSEventCnt>0)
return;

11
OSSemPend()
Example 2: OSEventCnt=0
task1() {
/*…*/ task2() {
OSSemPend(); /*…*/
/*…*/ OSSemPost();
} /*…*/
}

CTX_SW User mode

OSSemPend() {
OSSemPost() { Kernel mode
?(OSEventCnt>0) EventTaskRdy()
wait(pevent); OS_Sched()
sched(); return;
?(status == Rdy)
return; }
}

Task Running Task Running


OS_STAT_RDY
OS_STAT_SEM OS_STAT_RDY 12
OSSemPend()
Example 3: OSEventCnt=0
task1() {
/*…*/
OSSemPend(TO=3); task2() {
/*…*/ /*…*/
} OSSemPost();
/*…*/
}

User mode

OSSemPend() {
?(OSEventCnt>0) OSSemPost() { Kernel mode
TCBDly=3; EventTaskRdy()
wait(pevent); OS_Sched()
sched() return;
?(status != Rdy)
OS_EventTO() }
return;
}

Task Running
OS_STAT_SEM
0
1
2
3
13
OSSemPend()

The semaphore is available.

decrement semaphore only if


positive

14
OSSemPend()
The semaphore is not
available.

Timeout

15
OSSemPost()

See if any task waiting for


semaphore

Ready the highest priority task


waiting on the event

Increment the
semaphore
count 16
OSSemAccept()

17
OSSemQuery()

.
.
.

18

You might also like