ChorusOS 4.0 Introduction

Allocating and Freeing Memory Regions

A memory region is allocated through the following call:

#include <chorus.h>

int rgnAllocate(KnCap*     actorCap,
                KnRgnDesc* rgnDesc);

This call creates a memory region as described by the rgnDesc parameter within the address space of the actor defined by the actorCap parameter. Most applications set actorCap to K_MYACTOR to manage their own address space.

An unused part of an address space may be freed by the following call:

#include <chorus.h>

int rgnFree(KnCap*     actorCap,
            KnRgnDesc* rgnDesc);

This call frees a memory region as described by the rgnDesc parameter within the address space of the actor defined by the actorCap parameter.

Figure 7-1 Memory Region Allocation and Deallocation

Graphic

Example 7-1 does the following:

The main steps of the example are illustrated in Figure 7-1. Refer to the rgnAllocate(2K) and rgnFree(2K) man pages.


Example 7-1 Allocating a Memory Region

(file: progov/rgnAlloc.c)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <chorus.h>

#define RGN_SIZE_1 (6 * vmPageSize())
#define RGN_SIZE_2 (3 * vmPageSize())
#define FREE_START (2 * vmPageSize())
#define FREE_SIZE  (4 * vmPageSize())
#define STILL_ALLOC_START (FREE_SIZE - (RGN_SIZE_2 - FREE_START))

int main(int argc, char** argv, char**envp)
{
  KnRgnDesc           rgnDesc;
  KnActorPrivilege    actorP;
  int                 res;
  VmFlags             rgnOpt = 0;
  char*               ptr1 = NULL;	/* Avoids "uninited" warning */
  char*               ptr2 = NULL;	/* Avoids "uninited" warning */

  printf("Starting rgnAllocate example\n");			      

  res = actorPrivilege(K_MYACTOR, &actorP, NULL);
  if (res != K_OK) {						      
    printf("Cannot get actor privilege, error %d\n", res);	      
    exit(1);							      
  }								      
								      
  if (actorP == K_SUPACTOR) {
    rgnOpt = K_SUPERVISOR;
  }

  rgnDesc.size = RGN_SIZE_1;
  rgnDesc.options = rgnOpt | K_WRITABLE | K_FILLZERO | K_ANYWHERE;
  rgnDesc.opaque1 = NULL;
  rgnDesc.opaque2 = NULL;

      /*
       * No need to set rgnDesc.startAddr
       * since we set the K_ANYWHERE flag
       */
  res = rgnAllocate(K_MYACTOR, &rgnDesc);

  if (res == K_OK) {
    printf("Successfully allocated memory starting at 0x%x\n", 
	   rgnDesc.startAddr);

    ptr1 = (char*) rgnDesc.startAddr;
  } else {
    printf("First rgnAllocate failed with error %d\n", res);
    exit(1);
  }

  strcpy(ptr1, "Fill the allocated memory with this string\n");

      /* 
       * Second allocate has a fixed address, such that
       * both memory areas will be contiguous. Hence
       * we do not want the K_ANYWHERE flag any more.
       */
  rgnDesc.size       = RGN_SIZE_2;
  rgnDesc.options   &= ~K_ANYWHERE;
  rgnDesc.startAddr -= RGN_SIZE_2;

  res = rgnAllocate(K_MYACTOR, &rgnDesc);

  if (res == K_OK) {
    printf("Successfully allocated memory starting at 0x%x)\n", 
	   rgnDesc.startAddr);
    ptr2 = (char*) rgnDesc.startAddr;
  } else {
    printf("Second rgnAllocate failed with error %d\n", res);
    exit(1);
  }

      /* Copy from first allocated area to second one */
  strcpy(ptr2, ptr1);

      /* 
       * Free a memory area spanning both areas 
       * previously created
       */
  rgnDesc.options = NULL;
  rgnDesc.startAddr = (VmAddr) (ptr2 + FREE_START);
  rgnDesc.size      = FREE_SIZE;

  res = rgnFree(K_MYACTOR, &rgnDesc);
								      
  if (res != K_OK) {						      
    printf("Cannot free memory, error %d\n", res);		      
    exit(1);							      
  }								      
								      
      /* 
       * Access to ptr2: beginning of secondly allocated area
       * is still valid.
       * Access to ptr1 is now invalid: memory has been freed.
       */
  printf("%s", ptr2);	

      /*
       * Access to "end" of first allocated area
       * is still valid
       */
  ptr1 += STILL_ALLOC_START;
  strcpy(ptr1, ptr2);
  
      /*
       * Remaining memory areas not yet freed will 
       * effectively be freed at actor termination time.
       */
  return 0;
}