Clocks & Asynchronous Events. Overview Clocks API Implementation Asynchronous Events API ...

Preview:

Citation preview

Clocks & Asynchronous Events

Overview

Clocks API Implementation

Asynchronous Events API Single Threaded Model Multi-Threaded Model Code Walkthrough Demo

Clocks

Real-Time Specification Classes: Clock

getRealtimeClock() getResolution() getTime() setResolution()

Implementation

o Clocks are represented by a c struct:

struct clockStruct {htime time;htime resolution;

/* int threadID; /* ID of the thread instantiating this clock */struct clockStruct *nextClock; /* linked list */THREAD TimerQueue; /* queue of threads waiting on this clock */

};

typedef struct clockStruct CLOCK;

Implementation

Multiple clocks allow: Events to be checked at different frequencies More efficiency

Asynchronous Events

An asynchronous event represents something that can happen.

It can have a set of handlers associated with it.

When the event occurs, the handler is scheduled by the scheduler.

Real-Time Specification

The RTSJ includes a number of classes for dealing with Asynchronous Events. AsyncEvent AsyncEventHandler Interruptable

AsyncEvent

Methods addHandler(asyncEventHandler handler) bindTo(java.lang.String happening) Fire()

AsyncEventHandler

Code which is run in response to an eventA java.lang.Runnable with a set of

parametersSimilar to a RealTimeThread

Basic Problem with a Single Thread

Time

scheduler scheduler

Thread 1 Thread 2

Basic Problem with a Single Thread

Time

scheduler scheduler

Thread 1

Event Occurs

Thread 2

Basic Problem with a Single Thread

Time

scheduler scheduler

Thread 1

Event OccursEvent Handled

Thread 2

This shows how the KVM currently works.Events are put into a queue.Queue is polled periodically at

rescheduling.Allows context switching to be

implementation independent.

Basic Problem with a Single Thread

Problems with this model

Asynchronous events should be handled very quickly.

If the current thread does not yield, the VM hangs.

Solution

When an event happens, the currently executing thread should be switched out of context and the event handler switched in.

Asynchronous Events

Thread 1

Scheduler

Event Handler

Time

Asynchronous Events

Thread 1

Scheduler

Event Handler

Time

Asynchronous Events

Thread 1

Scheduler

Event Handler

Time

Asynchronous Events

Thread 1

Scheduler

Event Handler

Time

Asynchronous Events

Thread 1

Scheduler

Event Handler

Time

Asynchronous Events

Thread 1

Scheduler

Event Handler

Time

Asynchronous Events using Signals

This method for handling asynchronous events uses multiple threads.

An external thread sends a signal to the KVM where it is caught by a signal handler.

ExternalThread

KVM Thread

Signal Handler

Signal HandlerSignal

Demo Overview

TwoThreadsTest.java

SimpleThread.java

Java.lang.threadsleep();

nativeCore.cJava_lang_Thread_sleep();

Java

C

TwoThreadsTest.java

class TwoThreadsTest { public static void main (String[] args) { new SimpleThread("Jamaica").start(); new SimpleThread("Fiji").start(); new SimpleThread("Taiti").start(); new SimpleThread("Hawaii").start(); }}

SimpleThread.java

class SimpleThread extends Thread { String name; public SimpleThread(String str) { super();

name = new String(str); } public void run() { for (int i = 0; i < 10; i++) { System.out.println(i + " " + name); try { sleep((int)(1000)); } catch (InterruptedException e) {} } System.out.println("DONE! " + name); }}

Java/lang/thread.java

public static native void sleep(long millis) throws InterruptedException;

Kvm/VmCommon/src/nativeCore.c

void Java_java_lang_Thread_sleep(void){ long64 period; popLong(period);

/* only block if the time period is not zero */ if (ll_zero_ge(period)) { /* Copy CurrentThread because suspendThread clears it */ THREAD thisThread = CurrentThread;

/* Suspend the current thread before we add the timer */ suspendThread();

/* Now add the timer (this is the safe way) */ registerAlarm(thisThread, period, resumeThread);

} else { raiseException("java/lang/IllegalArgumentException"); }}

Signal Handlers:

• registerAlarm() adds a thread to TimerQueue• TimerQueue is a Queue of threads sorted by

wakeupTime• To handle timer events, we start a new thread

clockThread which checks the TimerQueue and sends a signal to the JVM when a timer has expired.

• When a signal is received by the VM, execution is interrupted and the signal handler clock_signal_handler() is called.

• clock_signal_handler() switches the waiting thread back into context.

Demo Overview (2)

RTClock_md();

KVM Thread

Signal Handler

Signal HandlerSIGUSR1

Clock_signal_handler();

Kvm/VmUnix/src/runtime_md.c

/*===================================================== * FUNCTION: InitializeRTClock * TYPE: initialization * OVERVIEW: called from StartJVM.c to start a seperate clock * thread for RT clock interrupt * INTERFACE: * parameters: none * returns: none *===================================================*/ void InitializeRTClock() {

pthread_t clockThread; pthread_create(&clockThread, NULL, RTClock_md, NULL); printf("* Initialize RTClock done\n");

}

Kvm/VmUnix/src/runtime_md.c

/*================================================================= * FUNCTION: RTClock_md * TYPE: Machine dependent function * OVERVIEW: runs in a seperate pthread to send interrupts for timer events *================================================================*/ void *RTClock_md(void *p) {

ulong64 now, nextTimer; for(;;) { if (TimerQueue != NULL) {

now = CurrentTime_md(); enterSystemCriticalSection();

nextTimer = GET_ULONG(TimerQueue->wakeupTime); exitSystemCriticalSection(); if (ll_compare_le(nextTimer, now)) {

kill(0, 10); /* send signal SIGUSR1 */ }

} }

} /* RTClock_md */

Kvm/VmUnix/src/runtime_md.c

/*================================================ * FUNCTION: clock_signal_handler * TYPE: RT clock * OVERVIEW: called when we receive a signal from the * clock thread * INTERFACE: * parameters: signal * returns: none *=============================================*/

static void clock_signal_handler(int sig) { reschedule(); }

Kvm/VmCommon/h/events.h

#define reschedule() \ printf("Rescheduling...\n"); \

do { \ ulong64 wakeupTime; \ if (!areAliveThreads()) { \ return; /* end of program */ \ } \ checkTimerQueue(&wakeupTime); \

BetterHandleEvent(wakeupTime); \ __ProcessDebugCmds(0); \

} while (!SwitchThread());

OS Limitations

Linux does not support some threading functions: Suspend Resume

These are supported by: OpenBSD RT-Linux Solaris Timesys Linux

Recommended