ef721fba899bbe1189363d5133d481e66f74f560
[alexxy/gromacs.git] / src / gmxlib / thread_mpi / p2p.c
1 /*
2 This source code file is part of thread_mpi.  
3 Written by Sander Pronk, Erik Lindahl, and possibly others. 
4
5 Copyright (c) 2009, Sander Pronk, Erik Lindahl.
6 All rights reserved.
7
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions are met:
10 1) Redistributions of source code must retain the above copyright
11    notice, this list of conditions and the following disclaimer.
12 2) Redistributions in binary form must reproduce the above copyright
13    notice, this list of conditions and the following disclaimer in the
14    documentation and/or other materials provided with the distribution.
15 3) Neither the name of the copyright holders nor the
16    names of its contributors may be used to endorse or promote products
17    derived from this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY US ''AS IS'' AND ANY
20 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 DISCLAIMED. IN NO EVENT SHALL WE BE LIABLE FOR ANY
23 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30 If you want to redistribute modifications, please consider that
31 scientific software is very special. Version control is crucial -
32 bugs must be traceable. We will be happy to consider code for
33 inclusion in the official distribution, but derived work should not
34 be called official thread_mpi. Details are found in the README & COPYING
35 files.
36 */
37
38 #ifdef HAVE_TMPI_CONFIG_H
39 #include "tmpi_config.h"
40 #endif
41
42 #ifdef HAVE_CONFIG_H
43 #include "config.h"
44 #endif
45
46
47 #ifdef HAVE_UNISTD_H
48 #include <unistd.h>
49 #endif
50
51 #include <errno.h>
52 #include <stdlib.h>
53 #include <stdio.h>
54 #include <stdarg.h>
55 #include <string.h>
56
57
58 #include "impl.h"
59
60
61
62 /* free envelopes: */
63 static struct envelope *tMPI_Free_env_list_fetch_recv(struct free_envelope_list 
64                                                       *evl);
65
66 /* return an envelope to the free envelopes list */
67 static void tMPI_Free_env_list_return_recv(struct free_envelope_list *evl,
68                                            struct envelope *rev);
69
70
71
72 /* send envelopes: */
73 /* get a new envelope from the send list's free envelope list */
74 static struct envelope*
75 tMPI_Send_env_list_fetch_new(struct send_envelope_list *evl);
76
77 /* return a send envelope to the send list's free envelope list, 
78     (to be used by the sending thread, who owns the send_envelope_list) */
79 static void tMPI_Send_env_list_return(struct envelope *ev);
80 #ifdef USE_SEND_RECV_COPY_BUFFER
81 /* return a send envelope to the sender's send list. 
82     (to be used by the receiving thread). */
83 static void tMPI_Send_env_list_rts(struct envelope *sev);
84 #endif
85
86 /* remove a send envelope from the old list. Does not lock */
87 static void tMPI_Send_env_list_remove_old(struct envelope *sev);
88
89
90
91 /* remove a send envelope from its head_old list. Does not lock */
92 static void tMPI_Send_env_list_remove_old(struct envelope *sev);
93
94 /* add a send envelope to the new envelopes queue in a list */
95 static void tMPI_Send_env_list_add_new(struct tmpi_thread *cur, 
96                                        struct send_envelope_list *evl,
97                                        struct envelope *sev);
98 /* move a send envelope to the old envelopes queue in a list. 
99    Assumes that this is safe to do without interference
100    from other threads, i.e. the list it's in must have been
101    detached. */
102 static void tMPI_Send_env_list_move_to_old(struct envelope *sev);
103
104
105 /* receive envelopes: */
106 /* add a receive envelope to a list */
107 static void tMPI_Recv_env_list_add(struct recv_envelope_list *evl,
108                                    struct envelope *ev);
109 /* remove a receive envelope from its list */
110 static void tMPI_Recv_env_list_remove(struct envelope *ev);
111
112
113
114
115 /* request list: */
116 /* get a request from the thread's pre-allocated request list */
117 static struct tmpi_req_ *tMPI_Get_req(struct req_list *rl);
118 /* return a request to the thread's pre-allocated request list */
119 static void tMPI_Return_req(struct req_list *rl, struct tmpi_req_ *req);
120
121 /* initialize a request with sensible values */
122 static void tMPI_Req_init(struct tmpi_req_ *rq, struct envelope *ev);
123
124 /* wait for incoming connections (and the completion of outgoing connections
125    if spin locks are disabled), and handle them. */
126 static void tMPI_Wait_process_incoming(struct tmpi_thread *th);
127
128 /* do the actual point-to-point transfer */
129 static void tMPI_Xfer(struct tmpi_thread *cur, struct envelope *sev, 
130                       struct envelope *rev);
131
132
133 /* check for the completion of a single request */
134 static bool tMPI_Test_single(struct tmpi_thread *cur, struct tmpi_req_ *rq);
135 /* check and wait for the completion of a single request */
136 static void tMPI_Wait_single(struct tmpi_thread *cur, struct tmpi_req_ *rq);
137
138 /* check for the completion of a NULL-delimited doubly linked list of 
139    requests */
140 static bool tMPI_Test_multi(struct tmpi_thread *cur, struct tmpi_req_ *rqs,
141                             bool *any_done);
142
143
144
145 #include "p2p_protocol.h"
146 #include "p2p_send_recv.h"
147 #include "p2p_wait.h"
148