Yet Another eXchange Tool  0.9.0
xt_handles.c
Go to the documentation of this file.
1 
12 /*
13  * Keywords:
14  * Maintainer: Jörg Behrens <behrens@dkrz.de>
15  * Moritz Hanke <hanke@dkrz.de>
16  * Thomas Jahns <jahns@dkrz.de>
17  * URL: https://doc.redmine.dkrz.de/yaxt/html/
18  *
19  * Redistribution and use in source and binary forms, with or without
20  * modification, are permitted provided that the following conditions are
21  * met:
22  *
23  * Redistributions of source code must retain the above copyright notice,
24  * this list of conditions and the following disclaimer.
25  *
26  * Redistributions in binary form must reproduce the above copyright
27  * notice, this list of conditions and the following disclaimer in the
28  * documentation and/or other materials provided with the distribution.
29  *
30  * Neither the name of the DKRZ GmbH nor the names of its contributors
31  * may be used to endorse or promote products derived from this software
32  * without specific prior written permission.
33  *
34  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
35  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
36  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
37  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
38  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
39  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
40  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
41  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
42  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
43  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
44  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45  */
46 #ifdef HAVE_CONFIG_H
47 #include <config.h>
48 #endif
49 
50 #include <assert.h>
51 #include <stdlib.h>
52 
53 #include "core/core.h"
54 #include "core/ppm_xfuncs.h"
55 #include "xt/xt_mpi.h"
56 #include "xt/xt_handles.h"
57 
58 
60  unsigned num; // number of used handles
61  unsigned cap; // capacity
62  unsigned hnf; // hint for next free entry
63  void **p; // vector of pointers to user data, p[handle] == pointer to user data
64 };
65 
66 static const unsigned default_handle_set_cap = 16;
67 
68 static void extend_handle_set(Xt_handle_set_type hset);
69 
71  if(!hset) return 0;
72  if (ih < 0 || (unsigned)ih >= hset->cap) return 0;
73  if (hset->p[ih]) return 1;
74  return 0;
75 }
76 
78  if (!xt_handle_is_valid(hset, ih)) return NULL;
79  return hset->p[ih];
80 }
81 
83  Xt_handle_set_type hset;
84  hset = malloc(sizeof (*hset));
85  assert(cap >= 0);
86  hset->p = malloc((unsigned)cap * sizeof(void*));
87  hset->num = 0;
88  hset->cap = (unsigned)cap;
89  if (hset->cap < 1) hset->cap = default_handle_set_cap;
90  hset->hnf = 0;
91  for (unsigned i=0; i<(unsigned)cap; i++) {
92  hset->p[i] = NULL;
93  }
94 
95  return hset;
96 }
97 
98 
100  if (!hset) {
102  return;
103  }
104 
105  unsigned old_cap, new_cap;
106  old_cap = hset->cap;
107  if (old_cap < 2) {
108  new_cap = default_handle_set_cap;
109  } else {
110  new_cap = old_cap*2;
111  }
112 
113  hset->p = xrealloc(hset->p, (unsigned)new_cap * sizeof(void*));
114 
115  for (unsigned i=old_cap; i<new_cap; i++) {
116  hset->p[i] = NULL;
117  }
118  hset->hnf = old_cap;
119  hset->cap = new_cap;
120 }
121 
122 
124  free(hset->p);
125  free(hset);
126  hset=NULL;
127 }
128 
129 
130 int xt_handle_new(Xt_handle_set_type hset, void *p) {
131  if (p == NULL) return -1;
132 
133  if (hset->num >= hset->cap) extend_handle_set(hset);
134  for (unsigned j=0; j<hset->cap; j++) {
135  unsigned i = (hset->hnf + j) % hset->cap;
136  if (!hset->p[i]) {
137  hset->p[i] = p;
138  hset->hnf = (i+1) % hset->cap;
139  hset->num++;
140  return (int)i;
141  }
142  }
143 
144  die("internal error");
145  /* GNU C realizes die does not return, other compilers lack this smart */
146 #ifndef __GNUC__
147  return 0;
148 #endif
149 }
150 
151 void xt_handle_delete(Xt_handle_set_type hset, int handle) {
152  if (!xt_handle_is_valid(hset, handle)) die("delete_handle: invalid handle");
153  hset->p[handle]=NULL;
154  if (hset->num == 0) die("delete_handle: internal error - negative occupation count");
155  hset->num--;
156  if (hset->p[hset->hnf]) hset->hnf = (unsigned)handle;
157 }
158 
159 
160 /*
161  * Local Variables:
162  * c-basic-offset: 2
163  * coding: utf-8
164  * indent-tabs-mode: nil
165  * show-trailing-whitespace: t
166  * require-trailing-newline: t
167  * End:
168  */
#define die(msg)
Definition: core.h:131
add versions of standard API functions not returning on error
#define xrealloc(ptr, size)
Definition: ppm_xfuncs.h:71
int xt_handle_is_valid(Xt_handle_set_type hset, int ih)
Definition: xt_handles.c:70
Xt_handle_set_type xt_handle_set_new(int cap)
Definition: xt_handles.c:82
void xt_handle_set_delete(Xt_handle_set_type hset)
Definition: xt_handles.c:123
static void extend_handle_set(Xt_handle_set_type hset)
Definition: xt_handles.c:99
int xt_handle_new(Xt_handle_set_type hset, void *p)
Definition: xt_handles.c:130
void xt_handle_delete(Xt_handle_set_type hset, int handle)
Definition: xt_handles.c:151
static const unsigned default_handle_set_cap
Definition: xt_handles.c:66
void * xt_handle2pointer(Xt_handle_set_type hset, int ih)
Definition: xt_handles.c:77
maps integers to data pointers
utility routines for MPI