Tutorial: Shared Memory
We will modify the HelloWorld server to make it use a shared memory. This shared memory will be used by its clients to make it say specific things.
In this example a single piece of shared memory is allocated by the server and access is given to the client.
Step 1: The IDL4 interface
Firstly we will add two function to the IDL4 file :
- get_shm to pass the shared memory's information to the client side
- say_this_shm to order the server to “say” whatever is in the shared buffer
> cat libs/hello/include/interfaces/hello.idl4
import "iguana/types.h";
[uuid(45)]
interface hello_
{
void say_this_shm(void);
void get_shm(out cap_t cap);
};
Step 2: The Server
We will add in the server part include to the necessary headers. We declare the needed variables. We modify the main function so it initialize the shared memory. Lastly we implement the functions get_shm and say this_shm previously declared in the IDL4 file.
> cat iguana/hello/src/hello_server.c
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <interfaces/hello_serverdecls.h>
#include <iguana/memsection.h>
#include <iguana/cap.h>
static cap_t cap;
static uintptr_t base;
int main(int argc, char **argv)
{
memsection_ref_t ms;
ms = memsection_create(0x1000, &base);
cap.ref.obj = ms;
cap.passwd = 0;
[...]
}
void hello__get_shm_impl(CORBA_Object _caller, cap_t *out_cap,
idl4_server_environment *enc)
{
memcpy(out_cap, &cap, sizeof(cap));
}
void hello__say_this_shm_impl(CORBA_Object _caller,
idl4_server_environment *env)
{
char *tmp_str = (char *)base;
printf("I can't resist to say (shared one): \"%s\"\n", tmp_str);
}
Step 3: The Client
Then we add in the client library the support of the shared memory to mask it use from the end user. To achieve that we create the wrapper function say_this_shm.
> cat libs/hello/include/hello.h #ifndef __HELLO_H__ #define __HELLO_H__ [...] void say_this_shm(char *); #endif
We implement the new wrapper function and we modify the hello_init function to make it use get_shm and get the shared memory.
> cat libs/hello/src/hello.c
#include <string.h>
#include <iguana/env.h>
#include <iguana/memsection.h>
#include <iguana/cap.h>
#include <iguana/thread.h>
#include <l4/thread.h>
#include <interfaces/hello_client.h>
#include <hello/hello.h>
#include <stdio.h>
static L4_ThreadId_t server_tid;
memsection_ref_t ms;
void *ms_base;
uintptr_t ms_size;
void hello_init(void)
{
thread_ref_t server_;
cap_t cap;
memsection_lookup((objref_t)
env_memsection_base(iguana_getenv("OKL4_HELLO_SERVER")),
&server_);
server_tid = thread_l4tid(server_);
hello__get_shm(server_tid, &cap, NULL);
clist_insert(default_clist, cap);
ms = (memsection_ref_t)cap.ref.obj;
ms_base = memsection_base(ms);
ms_size = memsection_size(ms);
}
void say_this_shm(char *in_str)
{
char *tmp;
tmp = (char *)ms_base;
strncpy(ms_base, in_str, ms_size);
hello__say_this_shm(server_tid, NULL);
}
Step 4: Using the Server
Using the server doesn't change much. We now got the say_this_shm function which make the server say the argument string. This string is passed to the server using a piece of shared memory. Of course we still need to call hello_init first to setup things.
Acknowledgement: Tutorial by Remy Gottschalk, via http://lists.okl4.org/pipermail/developer/2008-April/000961.html