CS452 - Real-Time Programming - Spring 2013

Lecture 8 - Initialization: Create & Kernel

Pubilc Service Annoucements

  1. Due date for kernel 1: 27 May.

Creating a Task

In creating a task you have to do two things

  1. Get and initialize resources needed by the task
  2. Make the task look as if it had just entered the kernel

Things you need to do

Get an unused TD and memory for its stack

This is the only memory allocation that ever occurs when a program is running. It is benign because

Mostly filling in fields in the TD.

  1. task id
  2. stack pointer
  3. pointers for readQ and other queues you don't need yet.
  4. SPSR
  5. two link registers
  6. parent tid
  7. return value
  8. state

Only the first two must be in the TD, but many of the others benefit from being in the TD.

Must also initialize the stack


The Create Function

You also need a int Create( int priority, void (*code) ( ) ) function to call from user tasks.

Although it's no more than a wrapper there are a few problems to solve.

  1. Passing arguments
  2. Jumping into the kernel
  3. Getting the return value from the kernel and returning it.

Initializing the Kernel

Set up the Hardware

  1. busy-wait io
  2. low memory
  3. Turn off interrupts in the ICU

Prepare the Kernel Data Structures

Where is the kernel's stack pointer, right now? What does the stack look like?

The kernel data structures

  1. an array of empty ready queues
  2. a pointer to the TD of the active task
  3. an array of TDs
  4. a free list of pointers to free TDs

Prepare the Memory to be Used by Tasks

  1. task memory

Create the First User Task

Can run with interrupts turned off for now (belt and braces) but will need to be turned on later.

Reminder. The place where the kernel starts executing has the global name main, which cannot be re-used.


Other Primitives

These primitives exist mostly so that we, which includes you, can ensure that task creation and scheduling are working when there is not much else implemented.

Tid MyTid( )

Self-explanatory

A question, to which there is a correct answer, or more specifically, a correct (answer, reason) pair.

Tid MyParentTid( )

Self-explanatory

Where is the parent Tid, and how does the kernel find it?

void Pass( )

Doesn't block: task calling Pass( ) makes a state transition from ACTIVE to READY or ACTIVE.

Does reschedule.

When is Pass( ) a NOP?

void Exit( )

Calling task is removed from all queues, but its resources are not reclaimed or reused.

That is, the task goes into a zombie state, in which it cannot be active or ready, but continues to own all its resources.

How Should Execution Terminate?

Nicely.

When there are no tasks left on the ready queues, it goes back to RedBoot.

This behaviour changes when hardware interrupts are implemented.


Inter-task Communication

Overview

Message passing combines synchronization and communication in one set of primitives.

int Send( Tid tid, char *message, int mslen, char *reply, int rplen )

int Receive( Tid *tid, char *msg, int msglen )

int Reply( Tid tid, char *rply, int rplylen )

Send and Reply become READY at the same time.


How are They Used?

The Producer/Consumer Problem

Middle (double) arrow shows the direction that information flows.

+--------------+          +--------------+
|              |   --->   |              |
|   Producer   |   ===>   |   Consumer   |
|              |   <---   |              |
+--------------+          +--------------+

Producer Sends

Upper arrow

  1. Producer sends and blocks: "I have some XXX for you."
  2. Consumer receives: "Give me some XXX."
  3. Consumer accepts XXX.
  4. Consumer replies: "I got the XXX."
  5. Producer & consumer are simultaneously READY.

Note. 1 & 2 could be run in the opposite order.

Consumer Sends

Lower arrow

  1. Consumer sends and blocks: "I am ready for some XXX from you."
  2. Producer receives: "I have some XXX."
  3. Producer replies: "Here is the XXX."
  4. Consumer accepts XXX.
  5. Producer and consumer are simultaneously READY.

Note. 1 & 2 could be run in the opposite order.

Multiple Producers

Producers send; consumer receives in the order that producers send.

Notes.

Multiple Consumers

Consumers send; producer receives in the order that consumers send.

Note. Critical races can occur, which the application programmer must resolve.

Multiple Consumers AND Multiple Producers

Consumers send and producers send: who receives?

+---------------+          +------------+          +---------------+
|               |   --->   |            |   <---   |               |
|   Producers   |   ===>   |   Buffer   |   ===>   |   Consumers   |
|               |          |            |          |               |
+---------------+          +------------+          +---------------+

Buffer receives two types of request

  1. Producer: Here is some XXX
    Send( warehouse, accept some XXX, ... )
  2. Consumer: I want some YYY
    Send( warehouse, want some YYY, ... )

Notes.


Sequence of States

Sender

  1. Active -> Receive_Blocked
  2. Receive_Blocked -> Reply_Blocked
  3. Reply_Blocked -> Ready

Receiver

  1. Active -> Send_Blocked
  2. Send_Blocked -> Ready
  3. Ready -> Active
  4. ...
  5. Active -> Ready

There are two cases

Send before Receive

Sender

Action

Sender

State

Receiver

Action

Receiver

State

Comments
active
Send RCV_BL sender added to receiver's sendQ
active
RPL_BL Receive ready request copied

sender deleted from receiver's sendQ

active service performed
ready Reply ready reply copied

Receive before Send

Sender

Action

Sender

State

Receiver

Action

Receiver

State

Comments
active
Receive SND_BL receiver's sendQ empty
active
Send RPL_BL ready request copied
active service perfomed
ready Reply ready reply copied


Practical Details

Example of a Difficult Bug // Must figure this out!

  1. You notice that a Receiver is never on a readyQ when it is Send_Blocked
  2. When a task becomes Send-Blocked on the Receiver,
  3. You test and test and test and nothing ever goes wrong
  4. One week before the demo, your kernel crashes under your application

What two things might have gone wrong?

You might have caught one while testing, not likely the other.


Return to: