ChorusOS 4.0 Hot Restart Programmer's Guide

3.2 A Simple Application

Before proceeding with a description of the different functions in the Persistent Memory Manager API, consider the following simple restartable application, an implementation of the familiar "hello world" example. When the actor is run for the first time, it displays the following message on the host console:

Hello world!

When the actor is restarted, it displays the following message on the target console:

Hello again! I have been restarted.

The basic flow of execution is as follows:


Example 3-1 The "Hello world" Restartable Actor

#include <stdio.h>
#include <pmm/chPmm.h>
#include <hr/hr.h>

#define HR_GROUP "HELLO_GROUP"

    int 
main()
{
	
	int res;
	int any = 1;
	int* counter_p;  /* It will be stored in persistent memory */
	long *p;
	PmmName name; 
	KnRgnDesc rgn;
	
            /* 
             * Initialize the name and medium fields 
             * to identify the persistent memory block in the system.
             */
	bzero(&name, sizeof(name));
	strcpy(name.medium,"RAM");
	strcpy(name.name,"PM1");
	
            /* 
             * Initialize the block fields
             */	
	bzero(&rgn, sizeof(rgn));
	rgn.options = K_ANYWHERE | K_RESERVED;
	rgn.size    = vmPageSize();
	res = rgnAllocate(K_MYACTOR, &rgn);
	if (res != K_OK) {
            printf("rgnAllocate() failed res=%d\n", res);
            HR_EXIT_HDL();
            exit(-1);
	}

	p = (long*) rgn.startAddr;

            /*
             * From now on p is a bad pointer, since 
             * VIRTUAL_ADDRESS_SPACE is true.
             */

            /* 
             * Allocate the persistent memory block that stores
             * counter_p.
             */
	res=pmmAllocate((VmAddr *)&counter_p,
                        &name,sizeof(int),
                        HR_GROUP,
                        sizeof(HR_GROUP));
	
	if (res != K_OK) {
            printf("Cannot allocate or map the persistent memory block called %s."
                   " Error = %d\n", name.name, res);
            HR_EXIT_HDL();
            exit(-1);
	}
	
            /* 
             * From the value of *counter_p the actor detects  
             * whether it has been hot restarted or not.
             */
	if ( *counter_p==0 ) {
                /*
                 * This is the first time the actor is run.
                 */
            printf("Hello world!\n");
		
                /* 
                 * Increment the counter
                 */
            (*counter_p)++;
		
                /*
                 * Normally the next instruction causes a core dump and
                 * a hot restart of the actor
                 */
            *p = 0xDeadBeef;

	} else {
                /* 
                 * The actor has been restarted
                 * NOTE: this message will appear on the console!
                 */
            printf("The actor has been restarted.\n");
		
                /*
                 * Free the persistent memory block before exiting
                 */
            res = pmmFree(&name);
            if (res != K_OK) {
                printf(" pmmFree failed, res=%d. Exit\n", res);
                HR_EXIT_HDL();
                exit(-1);
            }	
                /* 
                 * Terminate cleanly. 
                 */ 
            printf("Example finished. Exit.\n");
            HR_EXIT_HDL();
            exit(0);
	}
            /* Never reached */
}
	

The aspects of this program which are of interest for users of the Persistent Memory Manager API are discussed in the rest of this chapter.