The following code example shows how to share memory between applications.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <chorus.h> #include <cx/afexec.h> AcParam param; #define RGN_SIZE (3 * vmPageSize()) #define SHARED_RGN_SIZE (1 * vmPageSize()) typedef struct sampleSharedArea { KnSem sem; char data[1]; } sharea_t; char capString[80]; char sharedAddr[20]; int main(int argc, char** argv, char**envp) { KnRgnDesc rgnDesc; sharea_t* ptr; KnCap spawningCap; KnCap spawnedCap; int res; VmFlags rgnOpt = 0; KnActorPrivilege actorP; res = actorPrivilege(K_MYACTOR, &actorP, NULL); if (res != K_OK) { printf("Cannot get privilege, error %d\n", res); exit(1); } if (actorP == K_SUPACTOR) { rgnOpt = K_SUPERVISOR; } if (argc == 1) { /* * This is the first actor (or spawning actor): * Allocate a memory region * Initialize a semaphore within the region * Spawn the second actor * Wait on the semaphore * Get data written in shared mem by spawned actor * Terminate */ rgnDesc.size = RGN_SIZE; rgnDesc.options = rgnOpt | K_ANYWHERE | K_WRITABLE | K_FILLZERO; rgnDesc.opaque1 = NULL; rgnDesc.opaque2 = NULL; res = rgnAllocate(K_MYACTOR, &rgnDesc); if (res != K_OK) { printf("Cannot allocate memory, error %d\n", res); exit(1); } ptr = (sharea_t*) rgnDesc.startAddr; strcpy(&ptr->data[0], "First actor initializing the shared mem\n"); res = semInit(&ptr->sem, 0); /* * Get my own capability and pass it as a string argument * to spawned actor, so that it may use it to share memory */ (void) actorSelf(&spawningCap); sprintf(capString, "0x%x 0x%x 0x%x 0x%x", spawningCap.ui.uiHead, spawningCap.ui.uiTail, spawningCap.key.keyHead, spawningCap.key.keyTail); /* * Pass address of memory to be shared as a string argument * to spawned actor. */ sprintf(sharedAddr, "0x%x", ptr); param.acFlags = (actorP == K_SUPACTOR)? AFX_SUPERVISOR_SPACE : AFX_USER_SPACE; res = afexeclp(argv[0], &spawnedCap, ¶m , argv[0], capString, sharedAddr, NULL); if (res == -1) { printf("cannot spawn second actor, error %d\n", errno); exit(1); } (void) semP(&ptr->sem, K_NOTIMEOUT); printf("%s", &ptr->data[0]); } else { KnRgnDesc srcRgn; KnRgnDesc tgtRgn; unsigned long uHead, uTail, kHead, kTail; /* * This is the spawned actor: * Get arguments * Set up the memory sharing * Write some string in shared memory * Wake up spawning actor * Terminate */ sscanf(argv[1], "0x%x 0x%x 0x%x 0x%x", &uHead, &uTail, &kHead, &kTail); spawningCap.ui.uiHead = uHead; spawningCap.ui.uiTail = uTail; spawningCap.key.keyHead = kHead; spawningCap.key.keyTail = kTail; sscanf(argv[2], "0x%x", &srcRgn.startAddr); if (actorP != K_SUPACTOR) { srcRgn.size = SHARED_RGN_SIZE; tgtRgn.startAddr = srcRgn.startAddr; tgtRgn.size = SHARED_RGN_SIZE; tgtRgn.options = rgnOpt | K_WRITABLE; tgtRgn.opaque1 = NULL; tgtRgn.opaque2 = NULL; res = rgnMapFromActor(K_MYACTOR, &tgtRgn, &spawningCap, &srcRgn); if (res != K_OK) { printf("Cannot share memory, error %d\n", res); exit(1); } ptr = (sharea_t*) tgtRgn.startAddr; } else { /* * Both actors are running in supervisor space, * There is no need to perform the rgnMapFromActor. * One may use the received shared address. */ ptr = (sharea_t*) srcRgn.startAddr; } /* Get data from spawning actor */ printf("Spawning actor sent: %s", &ptr->data[0]); /* Modify contents of shared memory */ sprintf(&ptr->data[0], "Spawned actor mapped shared memory at 0x%x\n", ptr); res = semV(&ptr->sem); if (res != K_OK) { printf("Spawned actor failed on semV, error %d\n", res); exit(1); } } return 0; }