next up previous contents
Next: BIP utilization Up: BIP Messages User Manual Previous: BIP message-passing model and

Definition of BIP variables and functions

Each C module using BIP must include the file bip.h.

Basic primitives and variables of BIP

extern int bip_mynode,bip_numnodes

respectively give the logical number of the current process and the total number of processes.

void bip_init(void)

should be called once before any other BIP primitive except bip_taginit, and will initialize the system. Note that bip_mynode and bip_numnodes are only valid after this call.

int bip_tisend(int dst,int tag,int *buf, int length)

this is an asynchronous tagged send call, length is the size of the message to be sent in words (not bytes), buf points on the message data, the destination node number is given by dst, the message is sent to queue tag. This function returns immediately but the buffer should not be changed until the send has completed as ensured by bip_swait, in the meantime you cannot do any other send or isend communication calls.

void bip_swait(int id)

waits for the last send request to complete, it requires as argument the value returned by the last bip_tisend. When the function returns, the buffer can be used for something else, and a new send call can be done.

int bip_stest(int id)

tests if the last bip_tisend has completed, takes the id returned by isend. Returns 1 if the buffer can be reused, 0 otherwise.

int bip_tirecv(int tag,int *buf, int maxlength)

this is an asynchronous receive call. tag identifies the receive queue on which this call applies, buf gives the target buffer where the message will be stored at completion, maxlength is the maximum size the buffer is able to receive. The first message that arrives (or has already arrived) for this queue from the network will go into this buffer, it is an error if a message longer than this size arrives. The buffer contents are invalid until completion (as told by bip_rwait), and should not be modified until that. This function returns an identificator that should be passed to bip_rwait. This function returns immediately but you cannot do any other recv or irecv call with the same tag until the receive has completed (so after calling bip_rwait/bip_rtest).

int bip_rwait(int id)

waits for an asynchronous receive to complete, it requires as argument the value returned by the corresponding bip_tirecv. It returns the size (in words) of the message that has been received and stored in the user buffer.

int bip_rwaitx(int id,int *node)

same thing as bip_rwait but it returns the source node of the message in the variable pointed by node.

int bip_rtest(int id)

similar to bip_rwait, but if the reception has not completed, it does nothing and returns -1. It never blocks.

int bip_rtestx(int id,int *node)

similar to bip_rtest expect that if the receive has completed, it also gives the source node of the message in node.

int bip_tprobe(int tag)

if a short message can be received without blocking, the call return a non-null value else it returns 0. It cannot be used to detect the presence of a long message (will always return 0 if a long message is the first to arrive).

int bip_tnrecv(int tag, int *buf,int maxlength)

It is a non-blocking receive, if a short message is ready on the queue given by tag, it does not block and is equivalent to bip_trecv, else it is a ``no-op'' call and returns -1 (not zero because that is a valid message size). Warning: you cannot receive a long message with this call: it will always return -1 if a long message is arriving to the head of the queue

int bip_tnrecvx(int tag, int *buf,int maxlength,int *node)

similar to bip_tnrecv, expect that if a message is received, the source of the message is also returned via node.

int *bip_tgetmsg(int tag, int *length, int *node)

This function receives a message on queue tag and returns a pointer to the contents (the message is in a statically allocated buffer), the message size is returned via the parameter length, and the source of the message is returned in node. When the user has finished using the message contents, it must free it explicitely via bip_tfreemsg(tag).

int *bip_tngetmsg(int tag, int *length,int *node)

similar to bip_tgetmsg except it is non-blocking. If no message is available, it returns a null pointer and has no side-effect.

void bip_tfreemsg(int tag)

frees the older buffer received by bip_tgetmsg or bip_tngetmsg on queue tag. There is a static circular queue of buffers for each tag and buffers of a queue are freed, in the order they were received. You can receive several messages via bip_tgetmsg before freeing them (in the limit of the buffer queue for the corresponding tag. You can not do any other kind of receive call on this queue (such as bip_trecv) before having freed the buffers of all messages received via this call for the corresponding tag.

int bip_taginit(int tag, int nbufs, int size)

Allows to override the default buffer size allocated to the queue specified by tag, the buffer will be able to store nbufs messages of length size without any receive occuring. If the message are smaller, they can be more of them. But note that you have to take into account for each message not only the payload but also a few words (currently 4) of head information for internal purpose. This procedure can be called at most one time for each queue, and it must be called before the bip_init function. This procedure is optional, default values are taken, if not explicitely defined.

Blocking calls

The following functions can be semantically defined in terms of the previous one. They are provided both for convenience and also because their implementation is sometimes faster that using the basic primitives of BIP.

int bip_trecv(int tag, int *buf,int maxlength)

blocking receive, semantically equivalent to bip_rwait(bip_tirecv(tag,buf,maxlength).

int bip_trecvx(int tag, int *buf,int maxlength,int *node)

blocking receive, semantically equivalent to bip_rwaitx(bip_tirecv(tag, buf,maxlength).

int bip_tsend(int dst, int tag, int *buf,int length)

blocking send, semantically equivalent to bip_swait(bip_tisend(dst, tag, buf,length).

Non tagged message

There exists an ``untagged'' version of all BIP calls to maintain compatibility with previous versions, and for convenience for applications that just need one queue.

The functions are:

bip_isend(int dst, int *buf, int length)

equivalent to bip_tisend(dst,0,buf,length)

int bip_irecv(int *buf, int maxlength)

equivalent to bip_tirecv(0,buf,maxlength)

int bip_nrecv(int *buf,int maxlength)

equivalent to bip_tnrecv(0,buf,maxlength)

int bip_nrecvx(int *buf,int maxlength,int *node)

equivalent to bip_tnrecvx(0,buf,maxlength,node)

int *bip_getmsg(int *length, int *node)

equivalent to bip_tgetmsg(0,length,node)

int *bip_ngetmsg(int *length, int *node)

equivalent to bip_tngetmsg(0,length,node)

void bip_freemsg(void)

equivalent to bip_freemsg(0)

int bip_probe(void)

equivalent to bip_tprobe(0)

int bip_recv(int *buf,int maxlength)

equivalent to bip_trecv(0,buf,maxlength)

int bip_recvx(int *buf,int maxlength,int *node)

equivalent to bip_trecvx(0,buf,maxlength,node)

int bip_send(int dst, int *buf,int length)

equivalent to bip_tsend(dst, 0, buf,length).

Comments

Note that a bip_tirecv must be followed by a bip_rwait/bip_rtest. On the other hand, the bip_swait/bip_stest is not mandatory after a bip_tisend, but you should not reuse the buffer or issue another send before you are sure the message has been received at the other side (for example because you have received an answer).

Note that in the current implementation, passing a value of maxlength much larger than the final message length can have a significant impact on performance.


next up previous contents
Next: BIP utilization Up: BIP Messages User Manual Previous: BIP message-passing model and

Loic Prylli
Mon Jun 8 09:38:30 CEST 1998