source: CONFIG_DEVT/IPSLCM6.5_work_ENSEMBLES/oasis3-mct/BLD/build/lib/mctdir/mpi-serial/handles.c @ 5725

Last change on this file since 5725 was 5725, checked in by aclsce, 3 years ago

Added new oasis3-MCT version to be used to handle ensembles simulations with XIOS.

File size: 5.1 KB
Line 
1
2/*
3 * 5/20/2005 RML
4 *
5 */
6
7
8#include "mpiP.h"
9#include "type.h"
10/*
11 * handles.c
12 *
13 * handle management
14 * based on code from mpich-1.x/ptrcvt.c
15 * --> simplified and store item directly in the struct
16 * rather than as pointer to separately allocated object.
17 *
18 * CAVEAT:
19 * as in mpich-1, storage will grow as needed and will
20 * remain at the high water mark since it is likely that
21 * the user code will repeat the use.
22 *
23 */
24
25
26typedef struct _Handleitem
27{
28  int handle;
29  struct _Handleitem *next;
30
31  union
32  {
33    void *anything;           /* At least size of void *  */
34    Comm comm;
35    Req req;
36    Datatype* type;
37
38  } data;
39
40
41} Handleitem;
42
43
44/*
45 * These must be consistent with each other
46 *
47 */
48
49#define BLOCK_ITEMS          (256)
50#define HANDLE_TO_BLOCK(x)   ( (x) >> 8)
51#define HANDLE_TO_INDEX(x)   ( (x) & 0xff )
52#define HANDLE(block,index)  ( (block << 8) | (index) )
53
54
55/*
56 * The first block of handle items will be statically allocated.
57 * Subsequent ones will be added if necessary.
58 * blocks[0..nblocks-1] are allocated at any given time.
59 *
60 * Increase MAX_BLOCKS if you *really* need more active request
61 * (Although probably something is wrong if you need more than 256k !!!)
62 *
63 */
64
65
66#define MAX_BLOCKS (1024)
67
68static Handleitem block0[BLOCK_ITEMS];     /* array of handleitems */
69static Handleitem *(blocks[MAX_BLOCKS]);   /* array of pointers to blocks */
70static int nblocks;
71
72
73static int need_to_init=1;
74static Handleitem *nextfree;
75
76
77/************************************************************************/
78
79void *mpi_malloc(int size)
80{
81  void *ret;
82
83  ret=malloc(size);
84
85  if (!ret)
86    {
87      fprintf(stderr,"mpi_malloc: failed to allocate %d bytes\n",size);
88      abort();
89    }
90
91  return(ret);
92}
93
94
95void mpi_free(void *ptr)
96{
97  free(ptr);
98}
99
100
101/************************************************************************/
102
103
104/*
105 * initialize a block s.t. handles are set and
106 * 0 -> 1 -> 2 ... -> (BLOCK_ITEMS-1) -> NULL
107 *
108 */
109
110static Handleitem *init_block(int block, Handleitem *b)
111{
112  int i;
113
114  for (i=0; i<BLOCK_ITEMS-1; i++)
115    {
116      b[i].handle= HANDLE(block,i);
117      b[i].next = &b[i+1];
118    }
119
120  b[BLOCK_ITEMS-1].handle= HANDLE(block,BLOCK_ITEMS-1);
121  b[BLOCK_ITEMS-1].next=0;
122
123  return( &(b[0]) );
124}
125
126
127
128
129static void init_handles(void)
130{
131  int i;
132  Handleitem *new;
133
134  /*
135   * item 0 will not be used  (handle 0 maps to NULL)
136   *
137   */
138
139  new=init_block(0,block0);
140
141  nextfree=new->next;             /* Skip over using item 0 */
142  new->next=NULL;
143
144  /*
145   * initialize the array of blocks
146   *
147   */
148
149  blocks[0]=block0;
150  nblocks=1;
151
152  for (i=1; i<MAX_BLOCKS; i++)
153    blocks[i]=NULL;
154
155
156  need_to_init=0;
157}
158
159
160
161void mpi_destroy_handles(void)
162{
163  int i;
164
165  if (need_to_init)
166    return;
167
168  for (i=1; i<nblocks; i++)          /* blocks[0] is statically allocated */
169    mpi_free(blocks[i]);
170
171  need_to_init=1;
172}
173
174
175/************************************************************************/
176
177
178void mpi_alloc_handle(int *handle, void **data)
179{
180  Handleitem *new;
181  int i;
182
183  if (need_to_init)
184    init_handles();
185
186  if (nextfree)
187    {
188      new= nextfree;
189      nextfree= nextfree->next;
190      new->next=NULL;
191
192      *handle= new->handle;
193      *data= &(new->data);
194
195      return;
196    }
197
198  /* there is nothing free, so allocate a new block and add it
199   * to blocks[]
200   */
201
202  if (nblocks==MAX_BLOCKS)
203    {
204      fprintf(stderr,"mpi_allocate_handle: max %d active handles exceeded\n",
205              MAX_BLOCKS*BLOCK_ITEMS);
206      abort();
207    }
208
209  blocks[nblocks]= (Handleitem *)mpi_malloc(sizeof(Handleitem)* BLOCK_ITEMS);
210  new=init_block(nblocks,blocks[nblocks]);
211
212  nextfree= new->next;
213  new->next=NULL;
214
215  *handle= new->handle;
216  *data= &(new->data);
217
218  nblocks++;  /* DON'T FORGET THIS!!!! */
219
220#ifdef HANDLE_INFO
221  fflush(stdout);
222  fprintf(stderr,"mpi_alloc_handle: allocation %d blocks (%d handles)\n",
223          nblocks,nblocks*BLOCK_ITEMS);
224#endif
225
226}
227
228
229
230
231static void verify_handle(int handle, int block, int index)
232{
233  if (block>=nblocks || block<0 ||
234      index>=BLOCK_ITEMS || index<0)
235    {
236      fprintf(stderr,"mpi_verify_handle: bad handle\n");
237      abort();
238    }
239
240  if (blocks[block][index].handle != handle)
241    {
242      fprintf(stderr,"mpi_verify_handle: handle mismatch\n");
243      abort();
244    }
245}
246
247void *mpi_handle_to_ptr(int handle)
248{
249  int block;
250  int index;
251
252  if (need_to_init)
253    init_handles();
254
255  if (!handle)     /* Handle 0 -> NULL */
256    return(NULL);
257
258  block=HANDLE_TO_BLOCK(handle);
259  index=HANDLE_TO_INDEX(handle);
260
261#ifdef CHECKS
262  verify_handle(handle,block,index);
263#endif
264
265  return( &(blocks[block][index].data) );
266}
267
268
269
270void mpi_free_handle(int handle)
271{
272  int block;
273  int index;
274  Handleitem *item;
275
276  if (!handle)                         /* ignore null handle */
277    return;
278
279  if (need_to_init)
280    {
281      fprintf(stderr,"mpi_free_handle: handles not initialized\n");
282      abort();
283    }
284
285  block=HANDLE_TO_BLOCK(handle);
286  index=HANDLE_TO_INDEX(handle);
287
288#ifdef CHECKS
289  verify_handle(handle,block,index);
290#endif
291
292  item=&(blocks[block][index]);
293
294#ifdef CHECKS
295  if (item->next)
296    {
297      fprintf(stderr,"mpi_free_handle: handle still in use\n");
298      abort();
299    }
300#endif
301
302
303  /* just return it to the free list.
304   * space is not reclaimed.
305   */
306
307  item->next=nextfree;
308  nextfree=item;
309}
Note: See TracBrowser for help on using the repository browser.