clocks & asynchronous events. overview clocks api implementation asynchronous events api ...
Post on 22-Dec-2015
218 views
TRANSCRIPT
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