SIONlib  1.6.2
Scalable I/O library for parallel access to task-local files
sion_buffer.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 #include <stdlib.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <time.h>
13 #include <assert.h>
14 
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 #include <fcntl.h>
18 #include <unistd.h>
19 
20 
21 #include "sion.h"
22 #include "sion_debug.h"
23 #include "sion_internal.h"
24 #include "sion_buffer.h"
25 
26 
27 #if defined(_SION_LINUX)
28 #elif defined(_SION_AIX)
29 #elif defined(_SION_BGL)
30 #elif defined(_SION_BGP)
31 #elif defined(_SION_XT)
32 #endif
33 
34 
49 #define DFUNCTION "_sion_buffer_check_env"
50 
57  const char *t;
58  int rc = SION_SUCCESS;
59  t = _sion_getenv("SION_BUFFERSIZE");
60  if(t) {
61  sion_filedesc->buffer_size=atoi(t);
62  if(sion_filedesc->buffer_size == -1) sion_filedesc->buffer_size=sion_filedesc->fsblksize;
63  }
64  DPRINTFP((2, DFUNCTION, -1, "buffersize=%d\n", sion_filedesc->buffer_size));
65  _sion_buffer_init(sion_filedesc);
66  return (rc);
67 }
68 #undef DFUNCTION
69 
70 #define DFUNCTION "_sion_buffer_init"
71 
77 int _sion_buffer_init(_sion_filedesc *sion_filedesc) {
78  int rc = SION_SUCCESS;
79 
80  /* allocation */
81  if(sion_filedesc->buffer_size>0) {
82  sion_filedesc->buffer = (char *) malloc(sion_filedesc->buffer_size);
83  if (sion_filedesc->buffer == NULL) {
84  return(_sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,"_sion_buffer_init: cannot allocate internal buffer of size %lu , aborting ...\n", (unsigned long) sion_filedesc->buffer_size));
85  }
86  sion_filedesc->usebuffer=1;
87  DPRINTFP((2, DFUNCTION, -1, "buffer with size=%d allocated\n", sion_filedesc->buffer_size));
88  }
89  return (rc);
90 }
91 #undef DFUNCTION
92 
93 #define DFUNCTION "_sion_buffer_push"
94 
102 sion_int64 _sion_buffer_push(_sion_filedesc *sion_filedesc,
103  const void *data, sion_int64 bytes) {
104  sion_int64 bytes_free;
105  sion_int64 bytes_stored;
106  ONLY_DEBUG(sion_int64 bytes_not_stored;)
107  /* allocation */
108  bytes_free=sion_filedesc->buffer_size-sion_filedesc->buffer_ptr;
109  if(bytes<bytes_free) { /* data fits in buffer */
110  bytes_stored=bytes;
111  ONLY_DEBUG(bytes_not_stored=0;)
112  } else {
113  bytes_stored=bytes_free;
114  ONLY_DEBUG(bytes_not_stored=bytes-bytes_stored;)
115  }
116  if(bytes_stored>0) {
117  memcpy(sion_filedesc->buffer+sion_filedesc->buffer_ptr,data,bytes_stored);
118  sion_filedesc->buffer_ptr+=bytes_stored;
119  }
120 
121  DPRINTFP((2, DFUNCTION, -1, "pushed %d of %d bytes into buffer -> ptr=%d ret=%d\n",
122  (int) bytes_stored,(int) bytes,
123  (int) sion_filedesc->buffer_ptr, (int) bytes_not_stored));
124  return (bytes_stored);
125 }
126 #undef DFUNCTION
127 
128 #define DFUNCTION "_sion_buffer_get_data_ptr"
129 
139  void **data, sion_int64 *bytes) {
140  int flag = 1;
141 
142  /* pointer to and size of actual buffer contents */
143  *data=sion_filedesc->buffer;
144  *bytes=sion_filedesc->buffer_ptr;
145  flag=(*bytes>0);
146 
147  /* empty buffer */
148  sion_filedesc->buffer_ptr=0;
149  DPRINTFP((2, DFUNCTION, -1, "returns data ptr to %d bytes, flag=%d\n",
150  (int) *bytes, flag));
151 
152  return (flag);
153 }
154 #undef DFUNCTION
155 
156 #define DFUNCTION "_sion_buffer_flush"
157 
163 int _sion_buffer_flush(_sion_filedesc *sion_filedesc) {
164  sion_int64 bbytes, frc, byteswritten;
165  void *bdata;
166 
167 
168  DPRINTFP((1, DFUNCTION, -1, "enter\n"));
169 
170  _sion_flush_block(sion_filedesc);
171 
172  byteswritten = sion_filedesc->blocksizes[sion_filedesc->currentblocknr];
173 
174  _sion_buffer_get_data_ptr(sion_filedesc,&bdata,&bbytes);
175 
176  if ((byteswritten + bbytes) > sion_filedesc->chunksize) {
177  /* not enough space for writing next data */
178  _sion_create_new_block(sion_filedesc);
179  }
180 
181  frc = _sion_file_write(bdata, bbytes, sion_filedesc->fileptr);
182  if(frc != bbytes) {
183  return(_sion_errorprint_on_rank(SION_ANSI_SIZE_NOT_VALID,_SION_ERROR_RETURN,sion_filedesc->rank,
184  "could not write data (%d bytes) to file (sid=%d) ...", (int) bbytes, sion_filedesc->sid));
185  }
186  sion_filedesc->currentpos+=bbytes;
187 
188  DPRINTFP((2, DFUNCTION, -1, "leave\n"));
189 
190  return (SION_SUCCESS);
191 }
192 #undef DFUNCTION
sion_int64 _sion_file_write(const void *data, sion_int64 bytes, _sion_fileptr *sion_fileptr)
Write data to file.
Definition: sion_file.c:147
int _sion_buffer_flush(_sion_filedesc *sion_filedesc)
Flush buffer.
Definition: sion_buffer.c:163
int _sion_flush_block(_sion_filedesc *sion_filedesc)
Update the internal data structure.
int _sion_buffer_get_data_ptr(_sion_filedesc *sion_filedesc, void **data, sion_int64 *bytes)
Pop all data from buffer.
Definition: sion_buffer.c:138
Sion File Descriptor Structure.
Definition: sion_filedesc.h:77
int _sion_buffer_init(_sion_filedesc *sion_filedesc)
Allocate and initalize the buffer.
Definition: sion_buffer.c:77
sion_int64 _sion_buffer_push(_sion_filedesc *sion_filedesc, const void *data, sion_int64 bytes)
Push data to buffer.
Definition: sion_buffer.c:102
char * _sion_getenv(const char *name)
int _sion_errorprint(int rc, int level, const char *format,...)
Internal SION error.
int _sion_buffer_check_env(_sion_filedesc *sion_filedesc)
Checks if environment variables are set to use buffer.
Definition: sion_buffer.c:56
sion_int64 * blocksizes
Definition: sion_filedesc.h:98
sion_int32 currentblocknr
Definition: sion_filedesc.h:95
int _sion_create_new_block(_sion_filedesc *sion_filedesc)
Create a new block for the internal data structure.
_sion_fileptr * fileptr
Definition: sion_filedesc.h:80