CSCI1600: Embedded and Real Time Software Lecture 25: Real Time Scheduling III Steven Reiss, Fall...

Post on 18-Jan-2016

220 views 0 download

Tags:

transcript

CSCI1600: Embedded and Real Time SoftwareLecture 25: Real Time Scheduling III

Steven Reiss, Fall 2015

Total Bandwidth Server Initially es = 0 and d = 0

When a new job with execution time e comes into an empty queue

Set d = max(d,t) + e/us

Set es = e

When the server completes the current job, remove the job from the queue If there are more jobs,

Set the server deadline to d+eq/us and es= eq

Example

Periodic: P1(4,1), P2(6,3)

Aperiodic: A3: e=2 at time 1, A4: e= 1 at time 2

First determine Us

Up = ¼ + 3/6 = 0.75

Us = 0.25 (could be less)

Example

At Start P1(4,1), P2(6,3), es= 0, d = 0

A3: e=2 at time 1

At time 1: d = max(0,1) + 2 / 0.25 = 9, es = 2

P1

P2

P3

Example

P1(4,1), P2(6,3), Ps(9,2)

At time 3: new aperiodic job Pt (A4: e= 1 at time 2), but Ps not done

At time 7: Ps finishes, P2 has deadline 12

P1

P2

P3

Example

At time 7: d = d + eq/Us = 9 + 1/0.25 = 13, es = 1

Ps(13,1)

P1

P2

P3

Example

At time 7: d = d + eq/Us = 9 + 1/0.25 = 13, es = 1

Ps(13,1)

P1 and P2 have deadlines of 12

P1

P2

P3

Handling Task Dependencies

Suppose tasks depend on one another Represent this as a precedence relation

Ti -> Tj if Ti must precede Tj

Why would this arise?

How can we schedule the result

EDF doesn’t work directly

EDF* Scheduling

Let Di be the deadline for task i

Let ei be the execution time for task i

Define D’i as the modified deadline for task i

D’i = min(Di,MIN(Tj dependent on Ti)[D’j – ej]

Then use EDF on the modified deadlines

Thread Scheduling

All our schedules assume single core, single thread This might not be realistic today

Can we just use these techniques for multithreaded scheduling? Using any available processor

What can go wrong?

Thread Scheduling Assume m processors, m+1 tasks

Tasks 1..m are (1,2e) for small e (2me < 1)

Task m+1 is (1+e,1)

What happens? Using EDF/RM/DM

Tasks 1..m are all scheduled

But then m+1 can’t run

Even though there is lots of idle time

Other anomalies are possible (esp. w/ synchronization)

Thread Scheduling

Can still use the basic algorithms Assign each task to a particular thread

Ensure the utilization of that thread is <= 1 (k)

Then you can use EDF (RM/DM) to schedule the thread

Optimal assignment is NP-hard But approximations are pretty good

Interprocess Communication

Multiple tasks need to communicate We’ve covered shared memory

Using synchronization where necessary

When is synchronization necessary?

What other means are there?

Mailboxes What it is

A synchronized holder for a single message

Operations create – initialize a mailbox structure

accept – takes in a message

pend – waits for a message

post – sends a message

Messages void * (arbitrary pointer)

Mailbox Implementation

Mutex for operations

Create: set up everything, empty mailbox

Accept: check if mailbox is empty, if not, emtpy it

Pend: Wait until the mailbox is non-empty

Put task on wait queue for mailbox

Then get message and return it

Conflicts can be FIFO, priority-based, random

Mailbox Implementation Post:

If queued tasks, find proper waiter and remove from queue

Insert message into mailbox

Let that task continue

Else if there already is a message, return error

Else save message and return

Note that all operations are synchronized appropriately

What mailboxes can’t do Multiple messages (but can prioritize)

Blocking on post

Message Queues

Similar to mailboxes

Differences More than one message at a time

Can be dynamic or fixed maximum sized

Block on send

At least optionally

Message Queue Implementation

What does this look like Synchronized producer consumer queue

Handling multiple readers and writers

What this doesn’t handle Variable sized messages

Communication without shared memory

Pipes

Similar to message queues except Handle varying sized messages

May be entirely byte oriented

May take <length,data> for messages

Can work across processes if messages lack pointers

Can work across machines But have to be wary of endian problems

Wider Scale Communications

Might want to do more Communicate between processes

Communicate between devices (e.g. in a car)

Means for doing so Attached devices: point-to-point communication

Busses

Ethernet: MAC (Media Access Control), UDP

Ethernet: TCP, IP

Internetworking UDP (covered in CSCI1680)

Not very different from interacting with a bus

Best effort delivery (no reliability guarantees, acks)

You manage retries, assembly/dissembly, congestion

Good for sensor updates, etc.

TCP/IP Similar to a IPC pipe

Adds reliability, byte stream interface

Internally manages retries, ordering, etc.

Web services, simple APIs

TCP/IP Sockets are like 2-way pipes

Both sides can read/write independently

Sockets are address by host-port

Connection to a socket Create socket on the server

Bind it to a known port (on the known host)

Do an accept on the socket

Create a socket on the client

Connect to know server socket (connect) operation

Server does accept on its socket

This yields a new socket bound to that client

TCP/IP Lightweight implementation exist (even for Arduino)

Library interface for lwIP (Light Weight IP) ip_input(pbuf,netif)

Takes an IP package and the network interface as args

Does TCP/IP processing for the packet

tcp_tmr()

Should be called every 250ms

Does all TCP timer-base processing such as retransmission

Event-based callbacks

This is not sockets, but it is TCP/IP

lwIP Basics

Initialization: tcp_init

Manage all TCP connections tcp_tmr()

Must be called every 100-250 milliseconds

sys_check_timeout()

Calls tcp_tmr and other network related timers

lwIP Server Connection

tcp_new : create a PCB for a new socket

tcp_bind : bind that socket to a port on this host

tcp_listen : listen for connections

tcp_accept : specify a callback to call Passed routine called when someone tries to connect

tcp_accepted : called from the routine to accept the connection

lwIP Client Connection

tcp_new : create new PCB (socket)

tcp_bind : bind the socket to target host/port

tcp_connect : establish the connection Provides callback function

Called when connected

Or if there is an error in the connection

lwIP Sending Data

tcp_sent : specify callback function Called when data acknowledged by remote host

tcp_sndbuf : get maximum data that can be sent

tcp_write : enqueues the data for write Can be via copy or in-place

tcp_output : forces data to be sent

lwIP Receiving Data

tcp_recv : specifies a callback function Function called when data is received

Or when there is an error (connection closed)

Calls tcp_recved to acknowledge the data

lwIP Other Functions

tcp_poll : handle idle connections

tcp_close : close a connnection

tcp_abort : forcibly close a connection

tcp_err : register an error handling callback

Simple Web Server Assuming the host IP is known

Create a server socket on port 80

Listen for connections

Read message from connection

Should be header + body

Simple message = header only

Decode header, branch on URL

Compute output page

Send reply on the connection

HTTP header + HTML body

Simple Web Communicator

To send periodic updates Put together a message

Simple HTTP header

URL using ?x=v1&y=v2 to encode data

Connect to <SERVER HOST:80>

Send the message

Close connection

Simple Server Communicator

Use arbitrary message format

Use arbitrary host/port for the server

Send and receive messages in that format

Sample Code: Minimal Servermain() {

struct tcp_pcb * pcb

tcp_tcb_new();

tcp_bind(pcb,NULL,80);

tcp_listen(pcb);

tcp_accept(pcb,http_accept,NULL);

/* main loop */

}

 

http_accept(void * arg,struct

tcp_pcb * pcb) {

tcp_recv(pcb,http_recv,NULL);

}

 

http_recv(void * arg,

struct tcp_pcb *pcb,struct pbuf * p) {

// do something with packet p

}

Next Time

Real Time Operating Systems