Time for the 1st RTFM challenge!

A re-implementation of the legendary LOST countdown timer. You will compete for the best (w.r.t., robustness, functionality/similarity to the original LOST countdown) solution!

The plan is to put the winning solution online, along the on-line compiler/downloads etc. The online server runs ontop of windows, and I suspect it will be challenging to offer more than simple text I/O in between the online server and the running -core application. (We will see to that problem when the time comes.)

For now, this is what you should do to start out with:

1 Extract the specification from:

2 Re-implement the functionality in -core (to start out with).

- the -core v1.0 (in git) follows the timing semantics described in Section F). Under “Words from the author” you find:
“One can think of extensions allowing for emitting messages with baseline being the current time (i.e., create a time stamped interrupt), and the possibility to enforce rendez vous synchronisation.”
Looking at the LOST countdown problem, we find that it is necessary to get the time at which the “string” was entered by the user (i.e., create a time stamped interrupt). This will be an assignment for you to implement both in the -core language and the run-time system later. But as for now, you may use an alternative approach.

Have a look at the following example (this compiles and runs with the current -core and PTCORE):
Task task_print(char c) {
    #> printf("Char entered %c, Current time !!!! %f\n", c, RT_time_to_float(RT_get_bl()));<#

Idle {
    #> printf("User Idle\n");
    char c = getc(stdin);
    async task_print(c);

defines the following API to the run-time:
#define RT_sec                  1000000
#define RT_ms			1000

typedef int64_t RTFM_time;
#define RT_time			RTFM_time

// prototypes
RTFM_time RTFM_get_bl(int id);
void RTFM_set_bl(int id);
RTFM_time time_get();

#define RT_time_sub(t1, t2)     (t1 - t2)
#define RT_time_add(t1, t2)     (t1 + t2)
#define RT_time_to_float(t)     ( ((float) t)/RT_sec )
#define RT_time_of_float(f)     ((RTFM_time) (f * RT_sec))
#define RT_time_to_us(t)	(t)

// Run-time API, built in functions
#define RT_set_bl()     	{ RTFM_set_bl(RTFM_id); }
#define RT_get_bl()         	( RTFM_get_bl(RTFM_id) )

#define RT_rand(i)      	( rand() % i )
#define RT_sleep(s) 		( sleep( s ) )
#define RT_usleep(us)        	( usleep( us ) )
#define RT_printf(...) 		{ printf( __VA_ARGS__ ); }
#define RT_getc()		( getc(stdin) )
#define RT_putc(c)		{ putc(c, stdout); 

(Naming is that RTFM_* is used internally in the run-time, while RT_* is part of the user API. If you want to make cross-platform (OSX/Linux/Win32) RT applications you should use the RT_* primitives only.)

The notion of absolute time in RT is in micro seconds (us) since the system was “born” (i.e., Idle is scheduled at time 0us).

Calling RTFM_set_bl() sets a new baseline for the current task (in this case Idle). In the current run-time system implementation RTFM_id, is used to identify the current task, the macro RTFM_set_bl() hides this detail, since exposing RTFM_id is potentially dangerous if users make assumptions on it, RTFM_id is a mere artefact of the run-time.

Consequently, the async (without after) will create a message (task instance) with baseline being the time at which RTFM_set_bl() was called.

This allows us to in the receiving task get this time RT_get_bl() and thus provides a solution (or rather workaround to our problem).

This has the (unwanted) side effect that the baseline of the sender is (in this case Idle) is no longer the baseline of its triggering message (for Idle being time 0). In our case its fine but it is not always what you want, that is why YOU later will extend -core with time stamped messages (“pend” semantics). However, for your first implementation of the LOST countdown, you may use the aforementioned work-around.

Reading further from the words of the author you find:
"Another potential extension, is to allow aborting messages that have been emitted but not yet started. To this end, the async will need to return a “hook" allowing abortion.

Time stamped messages, as well as message abortion will be studied by the students of Compiler Construction fall of 2014, and potentially added to the timing semantics merged into the distribution of our compilers.”

Look once again at the LOST countdown, think of the situation that the user has entered a valid key 4, 8, 15, 16, 23 and 42 (followed by enter), but the asynchronous message triggering an “incident” has already been emitted. This is exactly the situation when we would like to abort the “incident” message. However, also in this case (without aborting messages) we can work around the problem). Hint, use global variables to define the “state” of the system (resource claim, can be used to enforce race free execution, in case shared data is not atomically accessed). Later in the course, you will implement the “pend” semantics for time stamped messages, but for your first LOST counter implementation, use the work-around.

Your first LOST countdown timer should start ticking soon!
(For the final competition, we might have the pends and aborts in place, and even a -cOOre language for its implementation, so this is just a warmup)

Per Lindgren, founder RTFM-lang, September 2014

Last edited Sep 4, 2014 at 10:49 AM by RTFMPerLindgren, version 5