SIONlib  1.7.1
Scalable I/O library for parallel access to task-local files
sion_fd.c
Go to the documentation of this file.
1 /****************************************************************************
2 ** SIONLIB http://www.fz-juelich.de/jsc/sionlib **
3 *****************************************************************************
4 ** Copyright (c) 2008-2016 **
5 ** Forschungszentrum Juelich, Juelich Supercomputing Centre **
6 ** **
7 ** See the file COPYRIGHT in the package base directory for details **
8 ****************************************************************************/
9 
17 #include <stdlib.h>
18 #include <stdio.h>
19 #include <string.h>
20 #include <stdarg.h>
21 #include <assert.h>
22 #include "sion_lock.h"
23 #include "sion_fd.h"
24 
25 #define sion_assert(expr, args) (assert(expr))
26 
27 #define SION_FDDATA_INITIALIZER {0,0,-1,NULL}
28 
29 /************************/
30 static struct _sion_fddata {
31  int size;
32  int nfree;
33  int last_freed;
34  struct _sion_fd *list;
35 } sion_fd_data = SION_FDDATA_INITIALIZER;
36 
37 static char *text; /* just a temp hack */
38 
39 /* some abbreviations for fd functions */
41 int _sion_newvcd(void *data, int type)
42 {
43  return _sion_new_fd(&sion_fd_data, data, type);
44 }
46 int _sion_freevcd(int sid)
47 {
48  return _sion_free_fd(&sion_fd_data, sid, text);
49 }
51 void *_sion_vcdtovcon(int sid)
52 {
53  return _sion_fd2ptr(&sion_fd_data, sid);
54 }
56 int _sion_vcdtype(int sid)
57 {
58  return _sion_fd2type(&sion_fd_data, sid, text);
59 }
61 int _sion_reassignvcd(int sid, void *data, int type)
62 {
63  return _sion_reassign_fd(&sion_fd_data, sid, data, type, text);
64 }
65 /************************/
66 
67 
68 
74 int _sion_new_fd(sion_fddata *fdd, void *data, int type)
75 {
76  int i;
77 
78  _sion_lock();
79 
80  /* if we are sure that we have at least 2 free descriptors,
81  * we can guarantee, that we don't need to reuse a freed
82  * one immediately
83  * so enlarge array of descriptors if we have less than 2 free ones
84  */
85  if (fdd->nfree < 2) {
86  int new_size;
87 
88  new_size = fdd->size + SION_FD_CHUNK;
89 
90  if (fdd->list) {
91  fdd->list = realloc(fdd->list, new_size * sizeof(struct _sion_fd));
92  }
93  else {
94  fdd->list = malloc(new_size * sizeof(struct _sion_fd));
95  }
96  sion_assert(fdd->list, ("out of memory"));
97 
98  for (i = fdd->size; i < new_size; i++) {
99  fdd->list[i].state = 0; /* free */
100  fdd->list[i].type = 0;
101  fdd->list[i].data = NULL;
102  }
103 
104  fdd->size = new_size;
105  fdd->nfree += SION_FD_CHUNK;
106  }
107 
108  /* use first 'fresh' index */
109  for (i = 0; i < fdd->size; i++) {
110  if (fdd->list[i].state == 0) {
111  fdd->list[i].data = data;
112  fdd->list[i].type = type;
113  fdd->list[i].state = 1;
114  fdd->nfree--;
115  _sion_unlock();
116  return i;
117  }
118  }
119 
120  /* if all have been used before, use a 'closed' one,
121  * start seraching a new one AFTER the last freed
122  * so this one will not be reused immediately
123  */
124  for (i = fdd->last_freed + 1; i < fdd->last_freed + 1 + fdd->size; i++) {
125  int imod = i % fdd->size;
126  if (fdd->list[imod].state == -1) {
127  fdd->list[imod].data = data;
128  fdd->list[imod].type = type;
129  fdd->list[imod].state = 1;
130  fdd->nfree--;
131  _sion_unlock();
132  return imod;
133  }
134  }
135  sion_assert(0, ("oops - we should never get here"));
136  return -1;
137 }
138 
139 
146 int _sion_set_fd(sion_fddata *fdd, int fd, void *data, int type, char *text)
147 {
148 
149  if (text && (!*text))
150  text = "_sion_set_fd";
151 
152  if (fd < 0) {
153  if (text) {
154  fprintf(stderr, "%s: trying to set an invalid descriptor fd=%d.\n", text, fd);
155  }
156  return 0;
157  }
158 
159  _sion_lock();
160 
161  if (fd >= fdd->size) {
162  /*
163  * enlarge descriptor array if neccessary
164  *
165  */
166  int i, new_size;
167 
168  new_size = fdd->size + SION_FD_CHUNK;
169  while (fd >= new_size) {
170  new_size += SION_FD_CHUNK;
171  }
172 
173  if (fdd->list) {
174  fdd->list = realloc(fdd->list, new_size * sizeof(struct _sion_fd));
175  }
176  else {
177  fdd->list = malloc(new_size * sizeof(struct _sion_fd));
178  }
179  sion_assert(fdd->list, ("out of memory"));
180 
181  for (i = fdd->size; i < new_size; i++) {
182  fdd->list[i].state = 0; /* free */
183  fdd->list[i].type = 0;
184  fdd->list[i].data = NULL;
185  }
186 
187  fdd->nfree += new_size - fdd->size;
188  fdd->size = new_size;
189  }
190  else if (fdd->list[fd].state == 1) {
191  if (text) {
192  fprintf(stderr, "%s: trying to set a descriptor that is in use fd=%d.\n", text, fd);
193  }
194  _sion_unlock();
195  return 0;
196  }
197 
198  fdd->list[fd].data = data;
199  fdd->list[fd].type = type;
200  fdd->list[fd].state = 1;
201  fdd->nfree--;
202 
203  _sion_unlock();
204  return 1;
205 }
206 
207 
211 int _sion_free_fd(sion_fddata *fdd, int fd, char *text)
212 {
213 
214  _sion_lock();
215  if ((fd < fdd->size) && (fd >= 0) && (fdd->list) && (fdd->list[fd].state == 1)) {
216  fdd->list[fd].state = -1;
217  fdd->nfree++;
218  fdd->last_freed = fd; /* remember this one to avoid immediate reuse */
219 
220  if (fdd->nfree == fdd->size) {
221  free(fdd->list);
222  fdd->list = NULL;
223  fdd->nfree = 0;
224  fdd->size = 0;
225  }
226 
227  _sion_unlock();
228  return 1;
229  }
230  else {
231  if (text) {
232  if (!*text)
233  text = "_sion_free_fd";
234  fprintf(stderr, "%s: trying to free an invalid descriptor fd=%d.\n", text, fd);
235  }
236  _sion_unlock();
237  return 0;
238  }
239 }
240 
241 
245 void *_sion_fd2ptr(sion_fddata *fdd, int fd)
246 {
247  _sion_lock();
248  if ((fd < fdd->size) && (fd >= 0) && (fdd->list[fd].state == 1)) {
249  void *ptr = fdd->list[fd].data;
250  _sion_unlock();
251  return ptr;
252  }
253  else {
254  _sion_unlock();
255  return NULL;
256  }
257 }
258 
259 
263 int _sion_fd2type(sion_fddata *fdd, int fd, char *text)
264 {
265  _sion_lock();
266  if ((fd < fdd->size) && (fd >= 0) && (fdd->list[fd].state == 1)) {
267  int type = fdd->list[fd].type;
268  _sion_unlock();
269  return type;
270  }
271  else {
272  if (text) {
273  if (!*text)
274  text = "_sion_fd2type";
275  fprintf(stderr, "%s: invalid descriptor fd=%d.\n", text, fd);
276  }
277  _sion_unlock();
278  return -1;
279  }
280 }
281 
282 
287 int _sion_ptr2fd(sion_fddata *fdd, void *ptr, char *text)
288 {
289  int i;
290 
291  _sion_lock();
292  for (i = 0; i < fdd->size; i++) {
293  if ((fdd->list[i].state == 1) && (fdd->list[i].data == ptr)) {
294  _sion_unlock();
295  return i;
296  }
297  }
298  if (text) {
299  if (!*text)
300  text = "_sion_ptr2fd";
301  fprintf(stderr, "%s: invalid pointer ptr=%x.\n", text, (unsigned) (size_t) ptr);
302  }
303  _sion_unlock();
304  return -1;
305 }
306 
307 
313 int _sion_reassign_fd(sion_fddata *fdd, int fd, void *data, int type, char *text)
314 {
315  _sion_lock();
316  if ((fd < fdd->size) && (fd >= 0) && (fdd->list[fd].state == 1)) {
317  fdd->list[fd].data = data;
318  fdd->list[fd].type = type;
319  _sion_unlock();
320  return 1;
321  }
322  else {
323  if (text) {
324  if (!*text)
325  text = "_sion_reassign_fd";
326  fprintf(stderr, "%s: invalid descriptor fd=%d.\n", text, fd);
327  }
328  _sion_unlock();
329  return 0;
330  }
331 }
332 
333 
337 int _sion_fd_size(sion_fddata *fdd)
338 {
339  /* should be atomic */
340  return fdd->size;
341 }
int _sion_reassignvcd(int sid, void *data, int type)
Definition: sion_fd.c:61
int _sion_new_fd(sion_fddata *fdd, void *data, int type)
Definition: sion_fd.c:74
int _sion_vcdtype(int sid)
Definition: sion_fd.c:56
void * _sion_fd2ptr(sion_fddata *fdd, int fd)
Definition: sion_fd.c:245
void * _sion_vcdtovcon(int sid)
Definition: sion_fd.c:51
int _sion_reassign_fd(sion_fddata *fdd, int fd, void *data, int type, char *text)
Definition: sion_fd.c:313
int _sion_newvcd(void *data, int type)
Definition: sion_fd.c:41
int _sion_fd2type(sion_fddata *fdd, int fd, char *text)
Definition: sion_fd.c:263
int _sion_ptr2fd(sion_fddata *fdd, void *ptr, char *text)
Definition: sion_fd.c:287
int _sion_free_fd(sion_fddata *fdd, int fd, char *text)
Definition: sion_fd.c:211
int _sion_fd_size(sion_fddata *fdd)
Definition: sion_fd.c:337
int _sion_freevcd(int sid)
Definition: sion_fd.c:46
int _sion_set_fd(sion_fddata *fdd, int fd, void *data, int type, char *text)
Definition: sion_fd.c:146