From RTSC-Pedia

Jump to: navigation, search
revision tip
—— LANDSCAPE orientation
[printable version]  offline version generated on 04-Aug-2010 21:08 UTC  

RTSC Module Primer/Lesson 2

Configuration parameters — using the Bench module

Leveraging everything you've learned in the last lesson, we'll now extend our "Hello World" program by using a second module—canonically named acme.utils.Bench—which supports program benchmarking by measuring the execution time of one or more C language statements. Besides reinforcing general patterns of RTSC module usage from within the C language, the Bench module in particular features a RTSC configuration parameter (or "config", for short) that becomes assignable in a target-program's corresponding XDCscript meta-program.

Lesson 7 covers the internal implementation of Bench, looking at the module from its supplier's perspective. In this lesson, however, all we know about Bench comes from the module's public specification—which defines the client programmer's perspective seen here.

Contents

Reading the program

Once again, the application features a pair of interrelated source files—the target-program prog.c together with its corresponding meta-program prog.cfg.

lesson2/prog.c
1
 
 
 
 
2
 
3
 
 
 
#include <acme/utils/Bench.h>
#include <xdc/runtime/System.h>
 
int main()
{
    Bench_begin("System_printf timing");
    System_printf("Hello World\n");
    Bench_end();
 
    return 0;
}
lesson2/prog.cfg
4
 
 
5
var Bench = xdc.useModule('acme.utils.Bench');
var System = xdc.useModule('xdc.runtime.System');
 
Bench.enableFlag = true;

The Bench module—whose fully-qualified name is reflected in the #include directive at line 1—features two functions used to bracket the fragment of code we wish to benchmark:

  • Bench_begin, which accepts a string (output later) as its sole argument and initiates a new measurement; and

  • Bench_end, which terminates the current measurement and then prints the string passed earlier to Bench_begin followed by the measurement itself.

While this example only brackets one C statement with Bench_begin / Bench_end—albeit one statement that itself contains a call to System_printf which internally can execute a significant number of statements—the pattern applies to arbitrary blocks of code. As a constraint, nesting of Bench_begin / Bench_end pairs is not supported in the current implementation of this module.

Turning now to prog.cfg, line 5 explicitly enables time measurement inside the Bench module; without this assignment, the target functions Bench_begin and Bench_end effectively become no-ops. For C programmers unfamiliar with the "object-oriented" syntax of JavaScript—and hence XDCscript—the object.property idiom at line 5 is not unlike accessing a struct field in C. The object itself—held in a local variable that happens to be named Bench—results from a call to the useModule property of a special (global) object named xdc on line 4; the object.property idiom is in fact more general than a simple field access, and subsumes function calls as well.

Unlike C, JavaScript enables you to enclose characters strings of arbitrary length inside single-quotes ('xdc.runtime.System') as well as inside the more familiar double-quotes ("Hello World\n"). As a convention, we'll limit use of the first form to names of RTSC modules passed to xdc.useModule; similar color-coding between lines 1 and 4 in the example above reinforces an important relationship between a RTSC target-program and its corresponding meta-program.

Assigning values to module configs

Module configs play a very special role in the world of RTSC modules, in that they are initially assignable in XDCscript meta-programs but eventually become frozen constants in the corresponding C target-program. Like any C variable, each config belongs to a particular type that can range from standard elementary types (numbers, booleans, strings) to supplier-defined compound types built from structures, arrays, and pointer-like references; and like any C variable, each config can optionally have a initial value of the same type, which effectively becomes the config's default value if not explicitly assigned in the meta-program.

To underscore their inherent "assignability", configs by convention will have camelCase names beginning with lower-case letters—the prevailing practice in C for naming variables, arguments, and struct fields.

In the case of enableFlag in our example, the Bench module specifies this config as a boolean with a default value of false. Attempting to assign Bench.enableFlag a value of some other type (say, the integer value 1 or the string value "yes") will result in a fatal XDCscript type-error—not unlike what happens in C (which is a strongly-typed language), but quite different from standard JavaScript (which is rather "loosely-typed" and generally tolerant of just about any mixture of types and values).

Building the program

No different from Lesson 1, you can build «examples»/lesson2 by invoking gmake all within this directory; output will again reflect the configuration, compilation, and linking of the example at hand.

 
1
 
 
 
 
2
3
>> gmake all
«xdcroot»/xs xdc.tools.configuro -t ti.targets.C64P -p ti.platforms.sim64Pxx -o cfgsite prog1.cfg
making package.mak (because of package.bld) ...
generating interfaces for package cfgsite (because package/package.xdc.xml is older than package.xdc) ...
configuring prog.x64P from package/cfg/prog_x64P.cfg ...
cl64P package/cfg/prog_x64P.c ...
«c6xtools»/bin/cl6x -q -@cfgsite/compiler.opt -c prog.c
«c6xtools»/bin/lnk6x -q -z -c prog.obj cfgsite/linker.cmd -o prog.out -l «c6xtools»/lib/rts64plus.lib

Delving a little deeper into line 1, we rely here upon a special command named xs bundled with XDCtools (and already in your PATH if you're set-up correctly) to launch configuro with a particular set of arguments.

In general, the xs command invokes a host-based XDCscript application whose (fully-qualified) name actually designates a particular RTSC package that in turn contains the application's XDCscript sources; the application is the package, and vice versa. The xs command forwards any remaining arguments after the package name to the application's main function.

The -t option to configuro likewise uses a canonical name to identify a particular RTSC target embodied as an XDCscript recipe, though here the fully-qualified name designates a (special kind of) RTSC module corresponding to the target of choice; for this example, we have chosen the ti.targets.C64P module as our target. The -p option uses a similar technique for identifying a particular RTSC platform, only here the name designates a package rather than a module; our example relies upon ti.platforms.load6x (a fast load-and-go simulator) for its execution platform.

Perhaps you're sensing a pattern here—everything in RTSC resides in some package whose canonical name should be globally-unique, qualified in many cases with a (unique) vendor or organization name. By convention, package names should avoid introducing upper-case letters; modules, on the other hand, will typically have capitalized CamelCase names that standout when prefixed with lower-case package names.

Finally, the -o option to configuro names a directory that will ultimately contain the generated compiler.opt and linker.cmd files, referenced further down in the commands at lines 2 and 3 which respectively invoke the underlying compiler and linker.

The output messages between lines 1 and 2 originate with an underlying command used internally by configuro—a command that you'll use directly in later lessons; ignore these messages for now.

Running and modifying the program

Simply invoke gmake test from the command-line and you should see the following output:

 
 
 
>> gmake test
Hello World
System_printf timing [2159]

Feel free at this point to modify prog.c in any way you choose and observe the impact on timing—add a second call to System_printf, call System_printf repetitively from within a simple for loop, and so forth. Even more important, observe the messages that result when you rebuild the example by invoking gmake all from the command-line:

 
2
3
>> gmake all
«c6xtools»/bin/cl6x -q -@cfgsite/compiler.opt -c prog.c
«c6xtools»/bin/lnk6x -q -z -c prog.obj cfgsite/linker.cmd -o prog.out -l «c6xtools»/lib/rts64plus.lib

Note that only compilation of prog.c followed by linking of prog.out occurred; since we left prog.cfg unchanged, configuro didn't have to run at this time. Were you to now modify prog.cfg, however—say by assigning false to Bench.enableFlag—you would see messages related to configuration and linking, but not compilation:

 
1
 
 
3
>> gmake all
«xdcroot»/xs xdc.tools.configuro -t ti.targets.C64P -p ti.platforms.sim64Pxx -o cfgsite prog.cfg
configuring prog.x64P from package/cfg/prog_x64P.cfg ...
cl64P package/cfg/prog_x64P.c ...
«c6xtools»/bin/lnk6x -q -z -c prog.obj cfgsite/linker.cmd -o prog.out -l «c6xtools»/lib/rts64plus.lib

To forcibly rebuild the example entirely from scratch and see all of the build messages, first invoke gmake clean to remove all generated output files.

RTSC configuration generally dominates the time required to build a RTSC program (as you're starting to realize), but fortunately most build systems (not just gmake) will only perform this step when absolutely necessary. Furthermore, prog.cfg meta-programs will often stabilize much more rapidly than prog.c target-programs during application development, suggesting that you will spend far more build cycles compiling rather than configuring over an extended period of time. Finally, one invocation of configuro can actually serve an entire family of application programs—large test suites come to mind here—which further amortizes the cost of RTSC configuration.

See also

Consuming Configurable Content/makefiles RTSC configuration with makefiles
 
Command - xs XDCscript interpreter
Command - xdc.tools.configuro Target content configuration tool

[printable version]  offline version generated on 04-Aug-2010 21:08 UTC  
Copyright © 2008 The Eclipse Foundation. All Rights Reserved
Views
Personal tools
package reference