next up previous contents index
Next: 2.2 Carrying On Up: 2. Application Programmer's Guide Previous: 2. Application Programmer's Guide   Contents   Index

Subsections


2.1 Getting Started

2.1.1 Introduction

To get into YAPI as quickly as possible, we illustrate the concepts by following the design of a Producer-Consumer application, which is the Hello World type of application for YAPI. The example is fully compliant with the coding style as presented in Section 2.6.1, but to avoid that you immediately get lost in details only the very essential features of YAPI are used. The more advanced features of YAPI are introduced in Section 2.2, and a complete reference can be found in Section 2.7. The complete source code of the Producer-Consumer example can be found in the YAPI Applications package.

We assume that you are already familiar with C++ concepts, such as classes, constructors, (virtual) member functions, inheritance, function overloading, templates, and references. For a good introduction to C++ we refer to [19].

2.1.2 Producer-Consumer

In the Producer-Consumer example we have two processes, a producer which writes integer values to a channel, and a consumer which reads the values from the channel. The first value that is written by the producer indicates the number of values that will follow.

Figure 2.1: Producer-Consumer
\begin{figure}\centerline{\psfig{figure=Figures/pc.eps,width=0.35\textwidth}}\end{figure}

In the remainder of this section we will discuss the Producer-Consumer example in a top-down way. We start with the main program in which the process network is created and started. Next we describe the process network, followed by the producer process and the consumer process.

2.1.3 The Main Program

To run a YAPI application one must first create a process network, and next call the YAPI function start to execute it. In its simplest form this is done in the main function as shown in Program 2.1.1. Assume that the class PC represents the Producer-Consumer process network which is declared in the file pc.h. We create the network with the declaration PC pc(id("pc")). This may look complicated, but basically what happens is that we create a variable pc which is a process network of type PC with identification string "pc". Next we execute the network using the start function from the YAPI Run-Time Environment. The start function is declared in the include file yapi.h.


Program 2.1.1   The Main Program (main.cc)
#include "pc.h"
#include "yapi.h"

int main()
{
        RTE rte;

        // create the process network
        PC pc( id("pc") );

        // start the process network
        rte.start(pc);

        return 0;
}


2.1.4 The Process Network

The Producer-Consumer process network is represented by the class PC. The declaration of this class can be found in the file pc.h, and the implementation can be found in the file pc.cc.


Program 2.1.2   Process Network Declaration (pc.h)
#include "yapi.h"

#include "producer.h"
#include "consumer.h"

class PC : public ProcessNetwork
{
public:
        PC(const Id& n);
        const char* type() const;

private:
        Fifo<int> fifo;

        Producer producer;
        Consumer consumer;
};


The class PC is derived from the YAPI class ProcessNetwork. The class has two public member functions, namely a constructor and a type function. These two functions must be defined in all process networks. The constructor is used to create the network in the main program, and the type function may be used to identify the type of the network as a string, for instance for debugging. Next, the class has private members, which in case of a network are the fifos and the processes that constitute the network. In case of the Producer-Consumer network we have a fifo that conveys values of type int, a process of type Producer called producer, and a process of type Consumer called consumer. The fifo is declared in the YAPI include file yapi.h, and the processes are declared in the user-defined include files producer.h and consumer.h, respectively.


Program 2.1.3   Process Network Implementation (pc.cc)
#include "pc.h"

PC::PC(const Id& n) :
        ProcessNetwork(n),
        fifo    (id("fifo")),
        producer(id("producer"), fifo),
        consumer(id("consumer"), fifo)
{ }

const char* PC::type() const
{
        return "PC";
}


The implementation of the class PC can be found in the file pc.cc. In this file we find an implementation of the constructor and the type function. The constructor first initializes the base class, ProcessNetwork, and next it initializes the private members, which are the fifo and the two processes. The initialization of these objects is performed by calling their constructors. The constructor of a fifo has one argument, namely its identification string. The constructor of a process also has an identification argument, and one or more fifos that are connected to its input and output ports. In this example the fifo is passed as an argument to the constructor of the producer, where it is bound to the output port, and the fifo is also passed as an argument to the constructor of the consumer where it is bound to the input port. The type function of a process network returns the class name as a string, which is "PC" in this case.

2.1.5 The Producer

The producer process is represented by the class Producer. The class is declared in the include file producer.h and its implementation can be found in the file producer.cc.

A user-defined process must be defined by a class that is derived from the YAPI class Process. It must have a constructor, a type function, and a main function. The purpose of the constructor and the type function are similar to those of a process network. Additionally, a process has a main function which represents the functionality of the process. A process network has no main function because its functionality is represented by its processes and fifos. A process has one or more input or output ports which must be declared as private member variables such that they can be accessed by the process from the main member function but not by other processes. The producer has one output port of type int, called out. The classes OutPort and Process are YAPI classes which are declared in include file yapi.h.

The constructor of the producer has two arguments, an identification of type Id, and an output object of type Out<int>. Template class Out is a base class of both Fifo and OutPort such that both fifos and output ports can be passed as arguments. In this example output port out is connected to fifo fifo in Program 2.1.3. In Section 2.2.1 we will show an example in which an output port is connected to another output port.


Program 2.1.4   Producer Process Declaration (producer.h)
#include "yapi.h"

class Producer : public Process
{
public:
        Producer(const Id& n, Out<int>& o);
        const char* type() const;
        void main();

private:
        OutPort<int> out;
};



Program 2.1.5   Producer Process Implementation (producer.cc)
#include "producer.h"
#include <iostream>

Producer::Producer(const Id& n, Out<int>& o) :
        Process(n),
        out( id("out"), o)
{ }

const char* Producer::type() const
{
        return "Producer";
}

void Producer::main()
{
        std::cout << "Producer started" << std::endl;

        const int n = 1000;

        write(out, n);

        for (int i=0; i<n; i++)
        {
                write(out, i);
        }

        std::cout << type() << " " 
                  << fullName() << ": "
                  << n << " values written" 
                  << std::endl;
}


The implementation of the class Producer can be found in the file producer.cc. In this file we find an implementation of the constructor, the type function, and the main function. In the constructor we first initialize the base class, Process, and next we initialize the private member, which is the output port. The constructor of an output port has two arguments, namely its identification string, and an output object, which could be a fifo, or another output port as we will see later.

The type function of class Producer returns the string "Producer". In the main function the constant n defines the number of tokens to be transferred. First the number of tokens is written to output port out, and next, in the for-loop, the numbers are written. Finally, before exiting the main function the type and the name of the process are printed to indicate that the process has terminated successfully.

2.1.6 The Consumer

The consumer process is similar to the producer. The differences are that it has an input port instead of an output port, and that data is read from this port instead of being written.


Program 2.1.6   Consumer Process Declaration (consumer.h)
#include "yapi.h"

class Consumer : public Process
{
public:
        Consumer(const Id& n, In<int>& i);
        const char* type() const;
        void main();

private:
        InPort<int> in;
};



Program 2.1.7   Consumer Process Implementation (consumer.cc)
#include "consumer.h"
#include <assert.h>
#include <iostream>

Consumer::Consumer(const Id& n, In<int>& i) :
        Process(n),
        in( id("in"), i)
{ }

const char* Consumer::type() const
{
        return "Consumer";
}

void Consumer::main()
{
        int n,j;

        std::cout << "Consumer started" << std::endl;
        
        read(in, n);

        for (int i=0; i<n; i++)
        {
                read(in, j);
                assert(i==j);
        }

        std::cout << type() << " " 
                  << fullName() << ": "
                  << n << " values read" 
                  << std::endl;
}


The definition of the consumer completes the Producer-Consumer example. If you are new to YAPI, and you wish to experiment with some toy YAPI program, we suggest that you start with the Producer-Consumer example, and add for example an extra process between the producer and the consumer. This process could simply pass the data, or do some ``real'' processing. You may also create an input process that reads data from a file, or an output process that writes data to a file.


next up previous contents index
Next: 2.2 Carrying On Up: 2. Application Programmer's Guide Previous: 2. Application Programmer's Guide   Contents   Index
© Copyright Koninklijke Philips Electronics NV 2006