docs:rtlib:aem

Run-time reconfigurable application Compiling

RTLib Abstract Execution Model (AEM) API

To facilitate the development of run-time reconfigurable application, the RTLib provides what we call Abstract Execution Model (AEM).
The AEM “embeds” the execution flow of the application in a way that let the BarbequeRTRM to manage its life-cycle.

Generally, we can structure an application by splitting it in more Execution Contexts (EXC).
From the BarbequeRTRM an EXC is a “schedulable task”. Having more EXC in the same application can come from the need of schedule parts of the application with different priorities and resource usages. This is made possible since the recipes are associated to the Execution Contexts.

The Execution Contexts of the same application MUST be independent, since actually the BarbequeRTRM do not take into account task-interdependency

Example: A video-conference application. We might design the application by splitting audio and video decoding tasks, because we have encountered (profiled) very different resource usage levels.

Anyway, consider that all the example applications provided with BOSP commonly are integrated using a single EXC.

Run-time reconfigurable application

In this section we see the basic integration process of the application into the AEM.

We consider a single EXC, since this is also the most common case. An Execution Context must be registered into the BarbequeRTRM. To do that, the application must define and instantiate a class derived from a specific C++ base class provided by the RTLib, i.e., BbqueEXC.

In next sub-section we discuss the details of this class.

Base class BbqueEXC

The base class BbqueEXC, defined into the header file under <BOSP_PATH>/include/bbque/rtlib/bbque_exc.h

Let's define a SimpleEXC class, placing it into a the include/simple_exc.h header file, where include is a sub-directory under the path containing the application source files.

/** FILE simple_exc.h **/
 
#include <bbque/bbque_exc.h>
 
class SimpleEXC : public BbqueEXC {
 
public:
        // SimpleEXC constructor code
	SimpleEXC(std::string const & name,
		  std::string const & recipe,
		  RTLIB_Services_t *rtlib):
	        // Call the super class constructor!
	    BbqueEXC(name, recipe, rtlib) {
            // Best pratice: Place class setup code into the onSetup()
            // function member
	}
 
        // Destructor
	virtual ~SimpleEXC() { }
 
private:
	// Methods to implement our application (as explained thereafter)
	RTLIB_ExitCode_t onSetup();
	RTLIB_ExitCode_t onConfigure(uint8_t awm_id);
	RTLIB_ExitCode_t onRun();
	RTLIB_ExitCode_t onSuspend();
	RTLIB_ExitCode_t onMonitor();
};

The class declares callback member functions, that we will explain later.

Initialization

In order to communicate with the Barbeque RTRM, the first step required to the applications is the initialization of the communication channel, and the retrieving of the services provided by the framework. Looking at an hypothetical main.cc:

#include <bbque/simple_exc.h>
 
int main(...) {
	...
	RTLIB_Services_t * rtlib;
	RTLIB_Init("MyApplication", &rtlib);
 
	if (!rtlib) {
		cout << "Error: Initialization failed "<< endl;
		return -1;
	}
	...
	return EXIT_SUCCESS;
}

RTLIB_Services_t is the structure returned by the BarbequeRTRM containing references to all the services that the application can require. For further details, please check barbeque/include/bbque/rtlib.h

A NULL return is a fatal error condition, meaning that the initialization has gone wrong and thus that the application cannot communicate with the framework.

EXC: Registration

As we already said, we must register our Execution Context. The registration step is implicitly performed by instancing the SimpleEXC class:

#include <bbque/simple_exc.h>
 
int main(...) {
	...
	SimpleEXC * myExeC = new SimpleTask(exc_name, recipe_name, rtlib);
	if (!myExeC) 
		cout << "Error: ExC not registered! "<< endl;
		return -2;
	}
	...
	return EXIT_SUCCESS;
}

The arguments of the constructor will contain all the information needed for the registration: the name associated to the EXC, the name of the recipe file (excluding “.recipe” extension) and the reference to the RTLIB_Service_t returned by the previous call. If the class has been correctly instanced then the registration has been successfully performed.

* onSetup() Implement this function with initialization and thread creation stuff. We strongly suggest to place this kind of code here, in order to allow the RTRM to perform a correct initialization of the structures supporting the collection of the runtime statistics.

EXC: Lifecycle

At this point, we are ready to require the execution of our simple EXC:

#include <bbque/simple_exc.h>
 
int main(...) {
	...
	result = myExeC->Start();
	if (result != RTLIB_OK) {
		cout << "Error: Unable to start the ExC "<< endl;
		return -4;
	}
 
        // Wait for the termination condition
        myExeC->WaitCompletion();
	...
	return EXIT_SUCCESS;
}

Once called Start() the Execution Context is instanced into a control thread, running a managed loop. Inside this loop, a set of SimpleEXC member function callbacks can be invoked, accordingly to the the resource management actions of the BarbequeRTRM.

The image below summarizes the Abstract Execution Model, where the white boxes are related to the member function callbacks of the derived class. As we can see, the AEM configures a sort of state diagram. Thus, the callback functions must implement what our Execution Context must do whenever reach the corresponding execution state.

Before discussing more in detail the member function callbacks, please note the WaitCompletion() call. This member function simply block the main thread of the application in a waiting state, until the termination condition of the Execution Context has not been raised.

 Abstract Execution Model

Now, we can provide details on the remaining member function callbacks.

* onConfigure() Called when a AWM has been assigned for the first time, or a change of AWM has been necessary. Here must be placed the code to setup the execution of the next runs, taking into account the set of resources related to the AWM.

* onSuspend() There are no resources for the EXC. Its execution must be stopped. Here should be coded whatever is needed to leave the application in a safe state.

* onRun() This is the entry point of our task. Here must be implemented the code to execute a computational run. It is very important each run would last some tens, or at maximum a few hundreds of milliseconds, in order to make the task interruptible with a “reasonable” time granularity. This would prevent the application from being killed by the RTRM.

/** FILE simple_exc.cc **/
 
RTLIB_ExitCode_t SimpleEXC::onRun() {
	...
	if (...) 	/** if no more workload, we can stop */
		return RTLIB_EXC_WORKLOAD_NONE;
 
	return RTLIB_OK;
}

* onMonitor() After a computational run, the application may check whether the level of QoS is acceptable or not. In the second case, some action could be taken. However this will be made available in a future release.

Compiling

Tested compilers: gcc-4.6/4.7

/usr/bin/g++ -o simple_app main.cc simple_exc.cc  \
    -I./include -I<BOSP_PATH>/out/include         \
    -L<BOSP_PATH>/out/lib/bbque/                  \
    -lbbque_rtlib
docs/rtlib/aem.txt · Last modified: 2014/09/25 17:38 by jumanix

Page Tools