Fusion:Shared Memory Example
From DirectFBWiki
fusionee_master.c
This program will create a simple process that will initialize an arena, allocate some shared memory and publish a pointer to it via the arena. The steps are quite straightforward :
- Initialize the fusion world
- Initialize the shared memory pool
- Initialize a new arena
- Allocate space for our data in the shared memory pool
- Fill this memory space with something
- Publish a pointer to it in our brand new arena
When shutdown the arena we'll have to :
- Get a pointer to the shared memory
- Free that memory
- Exit the arena
- Free the shared memory pool
- Exit the fusion world
#include <stdio.h>
#include <unistd.h>
#include <stdbool.h>
#include <linux/fusion.h>
#include <fusion/fusion.h>
#include <fusion/shmalloc.h>
#include <fusion/call.h>
#include <fusion/arena.h>
// ABI version for sanity check
#define DFB_ABI 70
enum {
NEW_WORLD = -1,
EXISTING_WORLD
} FusionWorldType;
// Shared memory pool size
#define SHM_POOL_SIZE 0x1000000
FusionWorld *world;
FusionSHMPoolShared *pool;
/*
* Callback function called from fusion_arena_enter()
* Add here all variables that live in shared memory
*/
int initialize(FusionArena *arena, void *ctx) {
char *str = NULL;
printf("\t\t\tAllocate SHM for field in Arena (%s)\n", __FUNCTION__);
str = (char *)SHMALLOC(pool, 1024);
sprintf(str, "String in Arena!!!");
fusion_arena_add_shared_field(arena, "string1", (void *)str);
printf("\t\t\tThe string is shared? ");
fusion_is_shared(world, str) ? printf("Yes") : printf("No");
printf(" (%s)\n", __FUNCTION__);
return 0;
}
/*
* Callback function called from fusion_arena_enter()
*/
int shutdown(FusionArena *arena, void *ctx, bool emergency) {
char *str = NULL;
fusion_arena_get_shared_field(arena, "string1", (void *)&str);
printf("\n\t\t\tFree shared memory (%s)\n\n", __FUNCTION__);
SHFREE(pool, str);
return 0;
}
int main () {
int ret;
char c;
void *ctx;
FusionArena *arena;
printf("Creating Fusion world (%s)\n", __FUNCTION__);
fusion_enter(NEW_WORLD, DFB_ABI, FER_MASTER, &world);
printf("Fusion world created with index %d (%s)\n",
fusion_world_index(world), __FUNCTION__);
printf("Is this the master? ");
fusion_master(world) ? printf("Yes") : printf("No");
printf(" (%s)\n", __FUNCTION__);
printf("\tCreating SHM pool (%s)\n", __FUNCTION__);
fusion_shm_pool_create(world, "WM SHM pool", SHM_POOL_SIZE, 0, &pool);
printf("\t\tCreating Arena (%s)\n", __FUNCTION__);
fusion_arena_enter(world, "WM Arena", initialize, NULL, &ctx, &arena, &ret);
printf("\n\t\tPress enter to exit (%s)\n", __FUNCTION__);
read(1, &c, 1);
printf("\t\tShutting down Arena (%s)\n", __FUNCTION__);
fusion_arena_exit(arena, shutdown, NULL, &ctx, 0, &ret);
printf("\tDestroying SHM pool (%s)\n", __FUNCTION__);
fusion_shm_pool_destroy(world, pool);
printf("Exiting Fusion world (%s)\n", __FUNCTION__);
fusion_exit(world, 0);
return 0;
}
fusionee_slave.c
Now we've got some shared memory that we can reach by entering the Arena. So let's write a little program that uses this arena to get the content of the shared memory. So we'll have to:
- Enter the existing fusion world
- Enter the arena using the join callback
- Get a pointer to the shared memory
- Leave the arena using the leave callback
- Leave the fusion world
#include <stdio.h>
#include <unistd.h>
#include <linux/fusion.h>
#include <fusion/fusion.h>
#include <fusion/shmalloc.h>
#include <fusion/arena.h>
// ABI version for sanity check
#define DFB_ABI 70
enum {
NEW_WORLD = -1,
EXISTING_WORLD
} FusionWorldType;
FusionWorld *world;
/*
* Callback function called from fusion_arena_enter()
*/
int join(FusionArena *arena, void *ctx) {
char *str = NULL;
printf("\t\tJoin Arena (%s)\n", __FUNCTION__);
fusion_arena_get_shared_field(arena, "string1", (void *)&str);
printf("\t\tString in SHM: %s\n", str);
return 0;
}
/*
* Callback function called from fusion_arena_exit()
*/
int leave(FusionArena *arena, void *ctx, bool emergency) {
printf("\t\tLeave Arena (%s)\n", __FUNCTION__);
return 0;
}
int main() {
int ret;
char c;
void *ctx;
FusionArena *arena;
printf("Join Fusion world (%s)\n", __FUNCTION__);
fusion_enter(EXISTING_WORLD, DFB_ABI, FER_SLAVE, &world);
printf("Fusion world joined with index: %d (%s)\n",
fusion_world_index(world), __FUNCTION__);
printf("Am I the master? ");
fusion_master(world) ? printf("Yes") : printf("No");
printf(" (%s)\n", __FUNCTION__);
printf("\tJoin Arena (%s)\n", __FUNCTION__);
fusion_arena_enter(world, "WM Arena", NULL, join, &ctx, &arena, &ret);
printf("\n\tPress enter to finish\n");
read(1, &c, 1);
printf("\tLeave Arena (%s)\n", __FUNCTION__);
fusion_arena_exit(arena, NULL, leave, &ctx, 0, &ret);
printf("Exit Fusion world (%s)\n", __FUNCTION__);
fusion_exit(world, 0);
return 0;
}
Compiling and running
For compiling both programs use :
gcc -Wall -O2 `pkg-config --cflags --libs fusion` fusionee_master.c -o fusionee_master gcc -Wall -O2 `pkg-config --cflags --libs fusion` fusionee_slave.c -o fusionee_slave
The environment variable $PKG_CONFIG_PATH must be set to something like ${INSTALL_PATH}/lib/pkgconfig
Now run fusionee_master on a terminal then fusionee_slave on another. You can run the client as many times as you want, until you press enter on the terminal runing fusionee_master.
Return to Fusion:Examples
