26.02.2014 Views

Getting Started with QNX Neutrino - QNX Software Systems

Getting Started with QNX Neutrino - QNX Software Systems

Getting Started with QNX Neutrino - QNX Software Systems

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Using message passing<br />

© 2009, <strong>QNX</strong> <strong>Software</strong> <strong>Systems</strong> GmbH & Co. KG.<br />

Multipart messages<br />

Until now, we’ve shown only message transfers happening from one buffer in the<br />

client’s address space into another buffer in the server’s address space. (And one<br />

buffer in the server’s space into another buffer in the client’s space during the reply.)<br />

While this approach is good enough for most applications, it can lead to inefficiencies.<br />

Recall that our write() C library code took the buffer that you passed to it, and stuck a<br />

small header on the front of it. Using what we’ve learned so far, you’d expect that the<br />

C library would implement write() something like this (this isn’t the real source):<br />

ssize_t write (int fd, const void *buf, size_t nbytes)<br />

{<br />

char *newbuf;<br />

io_write_t *wptr;<br />

int<br />

nwritten;<br />

}<br />

newbuf = malloc (nbytes + sizeof (io_write_t));<br />

// fill in the write_header at the beginning<br />

wptr = (io_write_t *) newbuf;<br />

wptr -> type = _IO_WRITE;<br />

wptr -> nbytes = nbytes;<br />

// store the actual data from the client<br />

memcpy (newbuf + sizeof (io_write_t), buf, nbytes);<br />

// send the message to the server<br />

nwritten = MsgSend (fd,<br />

newbuf,<br />

nbytes + sizeof (io_write_t),<br />

newbuf,<br />

sizeof (io_write_t));<br />

free (newbuf);<br />

return (nwritten);<br />

See what happened? A few bad things:<br />

• The write() now has to be able to malloc() a buffer big enough for both the client<br />

data (which can be fairly big) and the header. The size of the header isn’t the issue<br />

— in this case, it was 12 bytes.<br />

• We had to copy the data twice: once via the memcpy(), and then again during the<br />

message transfer.<br />

• We had to establish a pointer to the io_write_t type and point it to the beginning<br />

of the buffer, rather than access it natively (this is a minor annoyance).<br />

Since the kernel is going to copy the data anyway, it would be nice if we could tell it<br />

that one part of the data (the header) is located at a certain address, and that the other<br />

part (the data itself) is located somewhere else, <strong>with</strong>out the need for us to manually<br />

assemble the buffers and to copy the data.<br />

As luck would have it, <strong>Neutrino</strong> implements a mechanism that lets us do just that! The<br />

mechanism is something called an IOV, standing for “Input/Output Vector.”<br />

Let’s look at some code first, then we’ll discuss what happens:<br />

108 Chapter 2 • Message Passing April 30, 2009

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!