StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
daq_dta.cxx
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <assert.h>
4 #include <string.h>
5 
6 
7 #include <rtsLog.h>
8 
9 #include "daq_dta.h"
10 
11 daq_dta::daq_dta()
12 {
13  bytes_alloced = 0 ;
14  store = 0 ;
15  store_cur = 0 ;
16  do_swap = 0 ; // obviosly
17  nitems = 0 ;
18 
19  mode = 0 ;
20  meta = 0 ;
21 } ;
22 
23 
24 daq_dta::~daq_dta() {
25  release() ;
26 }
27 
28 int daq_dta::iterate()
29 {
30  if(nitems==0) return 0 ; // done!
31 
32 
33  sec = (store_cur->sec) ;
34  row = (store_cur->row) ;
35  pad = (store_cur->pad) ;
36  ncontent = (store_cur->nitems) ;
37 
38 
39  store_cur++ ; // skip this standard header...
40  Byte = (unsigned char *) store_cur ; // ...point to start of data!
41 
42  // and advance for next
43  store_cur = (daq_store *)((char *)store_cur + ncontent * hdr->obj_bytes) ;
44  nitems-- ;
45 
46  return 1 ; // return as "have data"
47 }
48 
49 
50 void daq_dta::release()
51 {
52  if(store && bytes_alloced) {
53  LOG(DBG,"freeing store") ;
54  free(store) ;
55  store = 0 ;
56  bytes_alloced = 0 ;
57  }
58 
59 }
60 
61 /*
62  objects is a first guess as to what we'll need, it is best that it is good!
63 */
64 daq_store *daq_dta::create(u_int bytes, const char *name, int rts_id, const char *o_name, u_int obj_size)
65 {
66  u_int requested ;
67 
68  // size of the store's header
69  requested = sizeof(daq_store) + sizeof(daq_store_hdr) ; // first "object" is the header
70 
71  // if I asked for less bytes than 1 object, I will overrule
72  if(bytes < obj_size) bytes = obj_size ;
73  // otherwise I will abide
74 
75  requested += sizeof(daq_store) + bytes ;
76 
77 
78  if(bytes_alloced < requested) {
79  u_int b_all_cache = bytes_alloced ;
80 
81  release() ; // free current store...
82 
83  // allocate new one
84  bytes_alloced = requested ;
85  store = (daq_store *) valloc(bytes_alloced) ;
86  assert(store) ;
87  LOG(DBG,"Allocated %d bytes for %d bytes required (%d was available)",bytes_alloced,bytes,b_all_cache) ;
88  }
89  else {
90  LOG(DBG,"Reusing %d bytes for %d bytes required",bytes_alloced,bytes) ;
91  }
92 
93 
94  // put header
95  store->sec = rts_id ;
96 
97  store->nitems = 1 ; // header
98  nitems = store->nitems ; // copy used for the iterator()!
99 
100  hdr = (daq_store_hdr *) (store + 1) ;
101 
102  hdr->hdr_bytes = sizeof(daq_store_hdr) ;
103  hdr->hdr_version = DAQ_DTA_C_VERSION ;
104  hdr->endianess = DAQ_DTA_ENDIANESS ;
105  hdr->obj_bytes = obj_size ;
106  hdr->bytes_used = sizeof(daq_store) + hdr->hdr_bytes ;
107  strncpy(hdr->obj_name,o_name,sizeof(hdr->obj_name)-1) ;
108  sprintf(hdr->describe,"%s[%d]:%s[%d bytes]:%s",name,rts_id,o_name,obj_size,__DATE__) ;
109 
110  mode = 0 ;
111 
112  LOG(DBG,"CREATE:%s: nitems %d, bytes %u/%u",hdr->describe,store->nitems,hdr->bytes_used,bytes_alloced) ;
113 
114  store_cur = (daq_store *)((char *)store + hdr->bytes_used) ; // set to next item...
115 
116  return store ; // not meant to be used except for a free!
117 }
118 
119 int daq_dta::is_empty()
120 {
121  if(store == 0) return 1 ;
122 
123  if(store->nitems <= 1) return 1 ;
124 
125  return 0 ;
126 }
127 
128 /*
129  Keeps the header, object types etc but just zaps them
130 */
131 void daq_dta::clear()
132 {
133  assert(store) ;
134 
135  store->nitems = 1 ; //the header
136  nitems = store->nitems ;
137 
138  hdr = (daq_store_hdr *) (store + 1) ;
139  hdr->bytes_used = sizeof(daq_store) + hdr->hdr_bytes ;
140 
141 
142  store_cur = (daq_store *)((char *)store + hdr->bytes_used) ;
143 
144 
145 }
146 
147 
148 void *daq_dta::request(u_int obj_cou)
149 {
150  daq_store *tmp_store ;
151 
152  LOG(DBG,"Requesting %d objects",obj_cou) ;
153 
154  if(obj_cou <= 0) obj_cou = 16 ; // ad hoc rule...
155 
156  tmp_store = get(obj_cou) ;
157 
158  LOG(DBG,"get returns %p",tmp_store) ;
159 
160  return (void *)(tmp_store + 1) ;
161 
162 }
163 
164 void daq_dta::finalize(u_int obj_cou, int sec, int row, int pad)
165 {
166 // if(obj_cou==0) {
167 // daq_store_hdr *hdr = (daq_store_hdr *)(store + 1 ) ;
168 //
169 // LOG(NOTE,"%s: finalize with obj cou 0?",hdr->describe) ;
170 // return ; // didn't find anything so just do nothing...
171 // }
172 
173 
174 // LOG(DBG,"Finilizing %d objects for sec %d, row %d, pad %d",obj_cou,sec,row,pad) ;
175 
176  store_cur->sec = sec ;
177  store_cur->row = row ;
178  store_cur->pad = pad ;
179  store_cur->nitems = obj_cou ;
180 
181 
182  LOG(DBG,"Finilizing %d objects for sec %d, row %d, pad %d [%d]",obj_cou,sec,row,pad,store_cur->pad) ;
183 
184  int bytes = sizeof(daq_store) + store_cur->nitems * hdr->obj_bytes ;
185  commit(bytes) ;
186 
187 
188  return ;
189 }
190 
191 
192 //daq_store *daq_dta::get(u_int *ret_avail)
193 daq_store *daq_dta::get(u_int obj_cou)
194 {
195  int do_realloc = 0 ;
196  u_int avail ;
197  u_int need ;
198 
199  // how much to we need
200  if(obj_cou==0) obj_cou = 16 ; // is not specified, as for 16...
201 
202  assert(hdr) ;
203 
204  need = sizeof(daq_store) + (obj_cou * hdr->obj_bytes) ;
205 
206  // attempt heuristics for storage reallocation
207  avail = bytes_alloced - hdr->bytes_used ;
208 
209  if(avail < need) do_realloc = 1 ;
210 
211 
212  LOG(DBG,"get(): avail bytes %d, need %d, objects %d requested of %d bytes each",avail, need, obj_cou,hdr->obj_bytes) ;
213 
214  if(do_realloc) {
215  char *new_store ;
216 
217  // round to 16 kB
218  const int chunk = 16*1024 ;
219  int cou16 = need/chunk ;
220  cou16++ ;
221  need = cou16 * chunk ;
222 
223  u_int old_alloced = bytes_alloced ;
224 
225  bytes_alloced = hdr->bytes_used + need ;
226 
227  LOG(DBG,"Reallocing from %d to %d",old_alloced,bytes_alloced) ;
228 
229  // remember pointers!
230  u_int hdr_off = (char *)hdr-(char *)store ;
231  u_int Byte_off = (char *)Byte - (char *)store ;
232  u_int store_cur_off = (char *)store_cur - (char *)store ;
233 
234 #define USE_REALLOC
235 #ifdef USE_REALLOC
236  new_store = (char *) realloc(store, bytes_alloced) ;
237  if(new_store == 0) {
238  LOG(WARN,"realloc failed!") ;
239  assert(new_store) ;
240 
241  }
242 #else
243 
244  LOG(DBG,"Before valloc %d",bytes_alloced) ;
245  new_store = (char *)valloc(bytes_alloced) ;
246  assert(new_store) ;
247  LOG(DBG,"Before memcopy of %d",hdr->bytes_used) ;
248  memcpy(new_store,store,hdr->bytes_used) ;
249 
250  free(store) ;
251 #endif
252 
253 
254 
255  // apply ptrs
256  hdr = (daq_store_hdr *) ((char *)new_store + hdr_off) ;
257  Byte = (u_char *)new_store + Byte_off ;
258  store_cur = (daq_store *) ((char *)new_store + store_cur_off) ;
259 
260  store = (daq_store *) new_store ;
261 
262  LOG(DBG,"Realloc done") ;
263 
264  }
265  avail = bytes_alloced - hdr->bytes_used ;
266 
267  store_cur->sec = 0xFF ;
268  store_cur->nitems = 0 ;
269 
270 
271  return store_cur ;
272 }
273 
274 void daq_dta::commit(u_int bytes)
275 {
276  char *mem = (char *)store_cur ;
277  if(bytes == 0) {
278  bytes = sizeof(daq_store) + store_cur->nitems * hdr->obj_bytes ;
279  }
280 
281  mem += bytes ;
282 
283  store->nitems++ ;
284  nitems = store->nitems ;
285  hdr->bytes_used = mem - (char *)store ;
286 
287  store_cur = (daq_store *) mem ;
288 
289  LOG(DBG,"commit: %dth nitem, bytes %d, bytes_used %d/%d",store->nitems,bytes,hdr->bytes_used,bytes_alloced) ;
290 
291  if(hdr->bytes_used > bytes_alloced) {
292  LOG(CRIT,"Storage overrun: %d > %d",hdr->bytes_used, bytes_alloced) ;
293  }
294 
295 
296  return ;
297 }
298 
299 /*
300  At the end of fillling, before we return the daq_det to the
301  user, we must rewind so the user can start reading from the start!
302 */
303 void daq_dta::rewind()
304 {
305  if(store == 0) return ; // not yet created!
306 
307  store_cur = store ;
308  nitems = store->nitems ;
309 
310  if(nitems <= 0) {
311  LOG(NOTE,"No items %d???",nitems) ;
312  return ;
313  assert(nitems>0) ;
314  }
315 
316  // adjust for the next so that iterate has something to do
317  nitems-- ;
318  store_cur = (daq_store *)((char *)hdr + hdr->hdr_bytes) ;
319  assert(store_cur) ;
320 
321 
322  LOG(DBG,"READY:%s: nitems %d, bytes %u/%u",hdr->describe,store->nitems,hdr->bytes_used,bytes_alloced) ;
323 
324  return ;
325 }
326