Loading...
Searching...
No Matches
examples/sys/ipc/ipc_example.c

This example shows how two threads can exchange data using the L4 IPC mechanism.

This example shows how two threads can exchange data using the L4 IPC mechanism. One thread is sending an integer to the other thread which is returning the square of the integer. Both values are printed.

/*
* (c) 2008-2009 Author(s)
* economic rights: Technische Universität Dresden (Germany)
*
* This file is part of TUD:OS and distributed under the terms of the
* GNU General Public License 2.
* Please see the COPYING-GPL-2 file for details.
*/
#include <l4/sys/ipc.h>
#include <pthread-l4.h>
#include <unistd.h>
#include <stdio.h>
static pthread_t t2;
/* Thread1 is the initiator thread, i.e. it initiates the IPC calls. In
* other words, it takes the client role. It uses L4 IPC mechanisms to send
* an integer value to thread2 and received a calculation result back. */
static void *thread1_fn(void *arg)
{
l4_msgtag_t tag;
int ipc_error;
unsigned long value = 1;
(void)arg;
while (1)
{
printf("Sending: %ld\n", value);
/* Store the value which we want to have squared in the first message
* register of our UTCB. */
l4_utcb_mr()->mr[0] = value;
/* To an L4 IPC call, i.e. send a message to thread2 and wait for a
* reply from thread2. The '1' in the msgtag denotes that we want to
* transfer one word of our message registers (i.e. MR0). No timeout. */
tag = l4_ipc_call(pthread_l4_cap(t2), l4_utcb(),
l4_msgtag(0, 1, 0, 0), L4_IPC_NEVER);
/* Check for IPC error, if yes, print out the IPC error code, if not,
* print the received result. */
ipc_error = l4_ipc_error(tag, l4_utcb());
if (ipc_error)
fprintf(stderr, "thread1: IPC error: %x\n", ipc_error);
else
printf("Received: %ld\n", l4_utcb_mr()->mr[0]);
/* Wait some time and increment our value. */
sleep(1);
value++;
}
return NULL;
}
/* Thread2 is in the server role, i.e. it waits for requests from others and
* sends back the calculation results. */
static void *thread2_fn(void *arg)
{
l4_msgtag_t tag;
l4_umword_t label;
int ipc_error;
(void)arg;
/* Wait for requests from any thread. No timeout, i.e. wait forever. */
tag = l4_ipc_wait(l4_utcb(), &label, L4_IPC_NEVER);
while (1)
{
/* Check if we had any IPC failure, if yes, print the error code
* and just wait again. */
ipc_error = l4_ipc_error(tag, l4_utcb());
if (ipc_error)
{
fprintf(stderr, "thread2: IPC error: %x\n", ipc_error);
tag = l4_ipc_wait(l4_utcb(), &label, L4_IPC_NEVER);
continue;
}
/* So, the IPC was ok, now take the value out of message register 0
* of the UTCB and store the square of it back to it. */
l4_utcb_mr()->mr[0] = l4_utcb_mr()->mr[0] * l4_utcb_mr()->mr[0];
/* Send the reply and wait again for new messages.
* The '1' in the msgtag indicated that we want to transfer 1 word in
* the message registers (i.e. MR0) */
tag = l4_ipc_reply_and_wait(l4_utcb(), l4_msgtag(0, 1, 0, 0),
&label, L4_IPC_NEVER);
}
return NULL;
}
int main(void)
{
// We will have two threads, one is already running the main function, the
// other (thread2) will be created using pthread_create.
if (pthread_create(&t2, NULL, thread2_fn, NULL))
{
fprintf(stderr, "Thread creation failed\n");
return 1;
}
// Just run thread1 in the main thread
thread1_fn(NULL);
return 0;
}
l4_umword_t
unsigned long l4_umword_t
Unsigned machine word.
Definition l4int.h:40
l4_ipc_reply_and_wait
l4_msgtag_t l4_ipc_reply_and_wait(l4_utcb_t *utcb, l4_msgtag_t tag, l4_umword_t *label, l4_timeout_t timeout) L4_NOTHROW
Reply and wait operation (uses the reply capability).
Definition ipc.h:572
l4_ipc_call
l4_msgtag_t l4_ipc_call(l4_cap_idx_t object, l4_utcb_t *utcb, l4_msgtag_t tag, l4_timeout_t timeout) L4_NOTHROW
Object call (usual invocation).
Definition ipc.h:565
l4_ipc_wait
l4_msgtag_t l4_ipc_wait(l4_utcb_t *utcb, l4_umword_t *label, l4_timeout_t timeout) L4_NOTHROW
Wait for an incoming message from any possible sender.
Definition ipc.h:593
l4_ipc_error
l4_umword_t l4_ipc_error(l4_msgtag_t tag, l4_utcb_t *utcb) L4_NOTHROW
Get the IPC error code for an IPC operation.
Definition ipc.h:629
l4_msgtag
l4_msgtag_t l4_msgtag(long label, unsigned words, unsigned items, unsigned flags) L4_NOTHROW
Create a message tag from the specified values.
Definition types.h:405
L4_IPC_NEVER
#define L4_IPC_NEVER
never timeout
Definition __timeout.h:76
l4_utcb_mr
l4_msg_regs_t * l4_utcb_mr(void) L4_NOTHROW L4_PURE
Get the message-register block of a UTCB.
Definition utcb.h:358
l4_utcb
l4_utcb_t * l4_utcb(void) L4_NOTHROW L4_PURE
Get the UTCB address.
Definition utcb.h:346
l4_msgtag_t
Message tag data structure.
Definition types.h:154
l4_msg_regs_t::mr
l4_umword_t mr[L4_UTCB_GENERIC_DATA_SIZE]
Message registers.
Definition utcb.h:69