00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <assert.h>
00004 #include <string.h>
00005
00006
00007 #include <rtsLog.h>
00008
00009 #include "daq_dta.h"
00010
00011 daq_dta::daq_dta()
00012 {
00013 bytes_alloced = 0 ;
00014 store = 0 ;
00015 store_cur = 0 ;
00016 do_swap = 0 ;
00017 nitems = 0 ;
00018 } ;
00019
00020
00021 daq_dta::~daq_dta() {
00022 release() ;
00023 }
00024
00025 int daq_dta::iterate()
00026 {
00027 if(nitems==0) return 0 ;
00028
00029
00030 sec = (store_cur->sec) ;
00031 row = (store_cur->row) ;
00032 pad = (store_cur->pad) ;
00033 ncontent = (store_cur->nitems) ;
00034
00035
00036 store_cur++ ;
00037 Byte = (unsigned char *) store_cur ;
00038
00039
00040 store_cur = (daq_store *)((char *)store_cur + ncontent * hdr->obj_bytes) ;
00041 nitems-- ;
00042
00043 return 1 ;
00044 }
00045
00046
00047 void daq_dta::release()
00048 {
00049 if(store && bytes_alloced) {
00050 LOG(DBG,"freeing store") ;
00051 free(store) ;
00052 store = 0 ;
00053 bytes_alloced = 0 ;
00054 }
00055
00056 }
00057
00058
00059
00060
00061 daq_store *daq_dta::create(u_int bytes, const char *name, int rts_id, const char *o_name, u_int obj_size)
00062 {
00063 u_int requested ;
00064
00065
00066 requested = sizeof(daq_store) + sizeof(daq_store_hdr) ;
00067
00068
00069 if(bytes < obj_size) bytes = obj_size ;
00070
00071
00072 requested += sizeof(daq_store) + bytes ;
00073
00074
00075 if(bytes_alloced < requested) {
00076 u_int b_all_cache = bytes_alloced ;
00077
00078 release() ;
00079
00080
00081 bytes_alloced = requested ;
00082 store = (daq_store *) valloc(bytes_alloced) ;
00083 assert(store) ;
00084 LOG(DBG,"Allocated %d bytes for %d bytes required (%d was available)",bytes_alloced,bytes,b_all_cache) ;
00085 }
00086 else {
00087 LOG(DBG,"Reusing %d bytes for %d bytes required",bytes_alloced,bytes) ;
00088 }
00089
00090
00091 store->sec = rts_id ;
00092
00093 store->nitems = 1 ;
00094 nitems = store->nitems ;
00095
00096 hdr = (daq_store_hdr *) (store + 1) ;
00097
00098 hdr->hdr_bytes = sizeof(daq_store_hdr) ;
00099 hdr->hdr_version = DAQ_DTA_C_VERSION ;
00100 hdr->endianess = DAQ_DTA_ENDIANESS ;
00101 hdr->obj_bytes = obj_size ;
00102 hdr->bytes_used = sizeof(daq_store) + hdr->hdr_bytes ;
00103 strncpy(hdr->obj_name,o_name,sizeof(hdr->obj_name)-1) ;
00104 sprintf(hdr->describe,"%s[%d]:%s[%d bytes]:%s",name,rts_id,o_name,obj_size,__DATE__) ;
00105
00106
00107 LOG(DBG,"CREATE:%s: nitems %d, bytes %u/%u",hdr->describe,store->nitems,hdr->bytes_used,bytes_alloced) ;
00108
00109 store_cur = (daq_store *)((char *)store + hdr->bytes_used) ;
00110
00111 return store ;
00112 }
00113
00114 int daq_dta::is_empty()
00115 {
00116 if(store == 0) return 1 ;
00117
00118 if(store->nitems <= 1) return 1 ;
00119
00120 return 0 ;
00121 }
00122
00123
00124
00125
00126 void daq_dta::clear()
00127 {
00128 assert(store) ;
00129
00130 store->nitems = 1 ;
00131 nitems = store->nitems ;
00132
00133 hdr = (daq_store_hdr *) (store + 1) ;
00134 hdr->bytes_used = sizeof(daq_store) + hdr->hdr_bytes ;
00135
00136 store_cur = (daq_store *)((char *)store + hdr->bytes_used) ;
00137
00138
00139 }
00140
00141
00142 void *daq_dta::request(u_int obj_cou)
00143 {
00144 daq_store *tmp_store ;
00145
00146 LOG(DBG,"Requesting %d objects",obj_cou) ;
00147
00148 if(obj_cou == 0) obj_cou = 16 ;
00149
00150 tmp_store = get(obj_cou) ;
00151
00152 LOG(DBG,"get returns %p",tmp_store) ;
00153
00154 return (void *)(tmp_store + 1) ;
00155
00156 }
00157
00158 void daq_dta::finalize(u_int obj_cou, int sec, int row, int pad)
00159 {
00160 if(obj_cou==0) {
00161 daq_store_hdr *hdr = (daq_store_hdr *)(store + 1 ) ;
00162
00163 LOG(WARN,"%s: finalize with obj cou 0?",hdr->describe) ;
00164 return ;
00165 }
00166
00167
00168 LOG(DBG,"Finilizing %d objects for sec %d, row %d, pad %d",obj_cou,sec,row,pad) ;
00169
00170 store_cur->sec = sec ;
00171 store_cur->row = row ;
00172 store_cur->pad = pad ;
00173 store_cur->nitems = obj_cou ;
00174
00175 int bytes = sizeof(daq_store) + store_cur->nitems * hdr->obj_bytes ;
00176 commit(bytes) ;
00177
00178
00179 return ;
00180 }
00181
00182
00183
00184 daq_store *daq_dta::get(u_int obj_cou)
00185 {
00186 int do_realloc = 0 ;
00187 u_int avail ;
00188 u_int need ;
00189
00190
00191 if(obj_cou==0) obj_cou = 16 ;
00192
00193 assert(hdr) ;
00194
00195 need = sizeof(daq_store) + (obj_cou * hdr->obj_bytes) ;
00196
00197
00198 avail = bytes_alloced - hdr->bytes_used ;
00199
00200 if(avail < need) do_realloc = 1 ;
00201
00202
00203 LOG(DBG,"get(): avail bytes %d, need %d, objects %d requested of %d bytes each",avail, need, obj_cou,hdr->obj_bytes) ;
00204
00205 if(do_realloc) {
00206 char *new_store ;
00207
00208
00209 const int chunk = 16*1024 ;
00210 int cou16 = need/chunk ;
00211 cou16++ ;
00212 need = cou16 * chunk ;
00213
00214 u_int old_alloced = bytes_alloced ;
00215
00216 bytes_alloced = hdr->bytes_used + need ;
00217
00218 LOG(DBG,"Reallocing from %d to %d",old_alloced,bytes_alloced) ;
00219
00220
00221 u_int hdr_off = (char *)hdr-(char *)store ;
00222 u_int Byte_off = (char *)Byte - (char *)store ;
00223 u_int store_cur_off = (char *)store_cur - (char *)store ;
00224
00225 #define USE_REALLOC
00226 #ifdef USE_REALLOC
00227 new_store = (char *) realloc(store, bytes_alloced) ;
00228 if(new_store == 0) {
00229 LOG(WARN,"realloc failed!") ;
00230 assert(new_store) ;
00231
00232 }
00233 #else
00234
00235 LOG(DBG,"Before valloc %d",bytes_alloced) ;
00236 new_store = (char *)valloc(bytes_alloced) ;
00237 assert(new_store) ;
00238 LOG(DBG,"Before memcopy of %d",hdr->bytes_used) ;
00239 memcpy(new_store,store,hdr->bytes_used) ;
00240
00241 free(store) ;
00242 #endif
00243
00244
00245
00246
00247 hdr = (daq_store_hdr *) ((char *)new_store + hdr_off) ;
00248 Byte = (u_char *)new_store + Byte_off ;
00249 store_cur = (daq_store *) ((char *)new_store + store_cur_off) ;
00250
00251 store = (daq_store *) new_store ;
00252
00253 LOG(DBG,"Realloc done") ;
00254
00255 }
00256 avail = bytes_alloced - hdr->bytes_used ;
00257
00258 store_cur->sec = 0xFF ;
00259 store_cur->nitems = 0 ;
00260
00261
00262 return store_cur ;
00263 }
00264
00265 void daq_dta::commit(u_int bytes)
00266 {
00267 char *mem = (char *)store_cur ;
00268 if(bytes == 0) {
00269 bytes = sizeof(daq_store) + store_cur->nitems * hdr->obj_bytes ;
00270 }
00271
00272 mem += bytes ;
00273
00274 store->nitems++ ;
00275 nitems = store->nitems ;
00276 hdr->bytes_used = mem - (char *)store ;
00277
00278 store_cur = (daq_store *) mem ;
00279
00280 LOG(DBG,"commit: %dth nitem, bytes %d, bytes_used %d/%d",store->nitems,bytes,hdr->bytes_used,bytes_alloced) ;
00281
00282 if(hdr->bytes_used > bytes_alloced) {
00283 LOG(CRIT,"Storage overrun: %d > %d",hdr->bytes_used, bytes_alloced) ;
00284 }
00285
00286
00287 return ;
00288 }
00289
00290
00291
00292
00293
00294 void daq_dta::rewind()
00295 {
00296 if(store == 0) return ;
00297
00298 store_cur = store ;
00299 nitems = store->nitems ;
00300
00301 if(nitems <= 0) {
00302 assert(nitems>0) ;
00303 }
00304
00305
00306 nitems-- ;
00307 store_cur = (daq_store *)((char *)hdr + hdr->hdr_bytes) ;
00308 assert(store_cur) ;
00309
00310
00311 LOG(DBG,"READY:%s: nitems %d, bytes %u/%u",hdr->describe,store->nitems,hdr->bytes_used,bytes_alloced) ;
00312
00313 return ;
00314 }
00315