📄 p4.tex
字号:
\end{example}\noindentreturns a BOOL value indicating whether the process has any messages availableor not. The parameters \code{req_type} and \code{req_from} are both pointersto integers; they are used as {\em both} input and output arguments. On input,\code{req_type} has a value that indicates the type of message that the userwishes to check for availability (-1 indicates any type). The variable\code{req_from} is used similarly to indicate who a message is desired from.\cindex{receiving messages} \findex{p4_recv}\begin{example}int p4_recv(req_type,req_from,msg,len_rcvd)int *req_type,*req_from,*len_rcvd;char **msg;\end{example}\noindenttakes four arguments. The \code{msg} argument is a pointer to apointer to a \code{char}. If this value is NULL, then p4 will allocate thebuffer for the message according to its length. That is, one need not knowahead of time the length of a message being received. If this value is notNULL, then it points to a p4 message buffer that the user has obtained via\code{p4_msg_alloc}. The \code{len_rcvd} argument is a pointer to an integerthat is assigned the length of the received message. \code{Req_type} and\code{req_from} are both pointers to integers; they are used as both input andarguments. On input, \code{req_type} has a value that indicates the type ofmessage that the user wishes to receive (-1 indicates any type). It willblock until a message of that type is available. \code{Req_from} is usedsimilarly to indicate who a message is desired from. One important note aboutthis procedure is that it obtains the area in which to place a message, andthe user must explicitly free that area when finished with it (see\code{p4_msg_free}). There is an option available with \code{p4_recv} inwhich the user can provide his own buffer rather than having p4 allocate it.To do this, the user points \code{msg} to a buffer that he must obtain via acall to \code{p4_msg_alloc} (see below). No \code{p4_msg_free} shouldbe performed if the same buffer is going to be re-used multiple times.\cindex{allocating buffers}\findex{p4_msg_alloc}\begin{example}char *p4_msg_alloc(len)int len;\end{example}\cindex{deallocating buffers}\findex{p4_msg_free}\begin{example}VOID p4_msg_free(m)char *m;\end{example}\noindentobtain and free a buffer area that can be used to receive a message. This procedure should be used for this task because a message has hidden information which the user is unaware of and therefore should not use \code{malloc} to obtain the area.\node Global Operations, , Explicit Sending and Receiving of Messages, Functions for Message Passing\subsection{Global Operations}\cindex{global operations}P4 supports a number of operations for dealing with all processes at once.\findex{p4_broadcast}\begin{example}p4_broadcast(type, data, data_len)int type;char *data;int data_len;\end{example}\findex{p4_broadcastx}\begin{example}p4_broadcastx(type, data, data_len, data_type)int type;char *data;int data_len, data_type;\end{example}\noindentprovide the ability to broadcast messages like \code{p4_send} and\code{p4_sendx}. These are semantically equivalent to a loop which uses\code{p4_send} or \code{p4_sendx} to individually send a message to each otherprocess (the sender is not included.) Messages sent by one of thesebroadcasts are received by normal \code{p4_recv}'s. The implementation of\code{p4_broadcast} is more efficient than such a loop, since it uses a``broadcast tree''. One situation to look out for is a normal\code{p4_broadcast} followed by a \code{p4_send}. It is possible for the firstmessage to arrive at its destination {\em after\/} the second one. The orderof messages in this situation can be enforced with the use of the \code{type}argument. \findex{p4_global_op}\begin{example}p4_global_op(type,x,nelem,size,op,data_type) int type;char *x;int size, nelem;int (*op)();int data_type;\end{example}\noindentwhere \code{op} is one of:\begin{example}p4_int_absmax_op()p4_int_absmin_op()p4_int_max_op()p4_int_min_op()p4_int_mult_op()p4_int_sum_op()p4_dbl_absmax_op()p4_dbl_absmin_op()p4_dbl_max_op()p4_dbl_min_op()p4_dbl_mult_op()p4_dbl_sum_op()p4_flt_absmax_op()p4_flt_absmin_op()p4_flt_max_op()p4_flt_min_op()p4_flt_mult_op()p4_flt_sum_op()\end{example}\noindentand \code{data_type} is one of \code{P4INT}, \code{P4LNG}, \code{P4FLT}, or\code{P4DBL}.This collection of routines provide the ability to do a variety of globaloperations. See the example program \file{p4/messages/systest.c}. They applythe commutative and associative operation \code{op} globally to \code{x} on anelement-by-element basis and broadcast the result to all nodes. That is, eachprocess ends up with\begin{example} for (i=0; i<n; i++) x[i] = x[node 0][i] op x[node 1][i] op x[node 2][i] op ...\end{example}\noindent\code{op} should be of the form\begin{example} VOID op(char *x, char *y, int nelem) \{ data_type *a = (data_type *) x; data_type *b = (data_type *) y; while (nelem--) *a++ operation= *b++; \}\end{example}\noindentwhere \code{data_type} and \code{operation} are chosen appropriately.The order in which nodes apply the operation is undefined (hence \code{op}must be commutative and associative). The communication may be internallysub-blocked so the function \code{op} should not be hardwired to specificvector lengths.This is still a relatively primitive version, which gathers the necessary dataup a balanced binary tree and then uses \code{p4_broadcast} to send theresults back. The \code{type} argument specifies the message type to be usedin the communication associated with this global operation.Strictly speaking, the \code{size} parameter, which is size in bytes of oneelement, is unnecessary. It is retained for backward compatibility.\cindex{barrier}\findex{p4_global_barrier}\begin{example}VOID p4_global_barrier(type)int type;\end{example}\noindentThis procedure takes one argument which is the message type to be used for internal message-passing. It causes the invoking process tohang until all processes specified in the procgroup file have invoked the procedure.\node Functions for Shared Memory, Functions for Timing p4 Programs, Functions for Message Passing, Top\section{Functions for Shared Memory}\cindex{shared memory functions}\cindex{shared memory example}Here is a simple example of a shared-memory program using monitors. In thisprogram, each process retrieves values from a shared loop index. A\dfn{monitor} is used to ensure that all values are retrieved exactly once.\begin{example}#include "p4.h"struct globmem \{ p4_getsub_monitor_t getsub;\} *glob;main(argc,argv)int argc;char **argv;\{ p4_initenv(&argc,argv); glob = (struct globmem *) p4_shmalloc(sizeof(struct globmem)); p4_getsub_init(&(glob->getsub)); p4_create_procgroup(); worker(); p4_wait_for_end();\}worker()\{ int i, nprocs; nprocs = p4_num_total_ids(); i = 0; while (i >= 0) \{ p4_getsub(&(glob->getsub),&i,10,nprocs); p4_dprintf("I got %d\verb+\+n",i); \}\}\end{example}\begin{menu}* Managing Shared and Local Memory::* Shared Memory Data Types::* Monitor-Building Primitives::* Some Useful Monitors::\end{menu}\node Managing Shared and Local Memory, Shared Memory Data Types, Functions for Shared Memory, Functions for Shared Memory\subsection{Managing Shared and Local Memory}The following functions are just basic memory management routines.\findex{p4_malloc}\begin{example}char *p4_malloc(n)int n;\end{example}\noindenttypically acts like the standard \code{malloc}, but may be rewritten for user systems that require different operation.\findex{p4_free}\begin{example}VOID p4_free(p)char *p;\end{example}\noindenttypically acts like the standard \code{free}, but may be rewritten foruser systems that require different operation.\findex{p4_shmalloc}\begin{example}char *p4_shmalloc(n)int n;\end{example}\noindentacts like the standard \code{malloc} except will obtain shared memory onmachines that support sharing memory among processes. Compare with\code{p4_malloc}.\findex{p4_shfree}\begin{example}VOID p4_shfree(p)char *p;\end{example}\noindentfrees memory obtained with \code{p4_shmalloc}. Compare with \code{p4_free}.\node Shared Memory Data Types, Monitor-Building Primitives, Managing Shared and Local Memory, Functions for Shared Memory\subsection{Shared Memory Data Types}\cindex{shared memory data types}\cindex{monitor data types}\cindex{data types for monitors}The abstraction provided by p4 for managing data in shared memory is\dfn{monitors}. Good places to learn about the monitor concept in general are\cite{pbh:architecture} and \cite{hoare:monitors}. The specific approachtaken by p4 is described in \cite{lusk-overbeek:p4-book}. P4 provides severaluseful monitors (\code{p4_barrier_t}, \code{p4_getsub_monitor_t},\code{p4_askfor_monitor_t}) as well as a general monitor type to help the userin constructing his own monitors (\code{p4_monitor_t}).\node Monitor-Building Primitives, Some Useful Monitors, Shared Memory Data Types, Functions for Shared Memory\subsection{Monitor-Building Primitives}\cindex{monitor primitives}The following functions can be used to construct monitors. A monitor soconstructed has the type \code{p4_monitor_t}.\findex{p4_moninit}\begin{example}int p4_moninit(m,i)p4_monitor_t *m;int i;\end{example}\noindentinitializes the monitor pointed to by \code{m} and gives it \code{i}queues for processes to wait on while they are blocked (see \code{p4_mdelay}).One queue is sufficient for most purposes. The queues are numbered beginningwith 0.\findex{p4_menter}\begin{example}VOID p4_menter(m)p4_monitor_t *m;\end{example}\noindententer the monitor pointed to by \code{m}. By the definition of a monitor,access is restricted to a single process in the monitor at a time (ifeverybody plays by the rules).\findex{p4_mexit}\begin{example}VOID p4_mexit(m)p4_monitor_t *m;\end{example}\noindentexits the monitor pointed to by \code{m}. You are of course assumed to havepreviously entered that monitor.\findex{p4_mcontinue}\begin{example}VOID p4_mcontinue(m,i)p4_monitor_t *m;int i;\end{example}\noindentchecks to see if there are any processes blocked on the \code{i}-th queue ofthe monitor \code{m} and causes one of them to be released for entry to themonitor if so. If there are no such processes, the invoking processsimply exits. Note that a process could have been blocked previouslyby invoking the procedure \code{p4_mdelay}. The queues are numbered beginning with 0.\findex{p4_mdelay}\begin{example}VOID p4_mdelay(m,i)p4_monitor_t *m;int i;\end{example}\noindentpermits a process to delay itself on the \code{i}-th queue of monitor\code{m} if the process wishes to release the monitor, but wants to bewaked up by another process later (via the procedure \code{p4_mcontinue}).The queues are numbered beginning with 0.\node Some Useful Monitors, , Monitor-Building Primitives, Functions for Shared Memory\subsection{Some Useful Monitors}\cindex{monitors}In this section we describe some of
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -