#include <errno.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/resource.h>#include <netcdf.h>#include "nco_netcdf.h"#include "nco.h"#include "nco_ctl.h"Include dependency graph for nco_mmr.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.
Functions | |
| void * | nco_calloc (const size_t lmn_nbr, const size_t lmn_sz) |
| void * | nco_free (void *vp) |
| void * | nco_malloc (const size_t size) |
| void * | nco_malloc_flg (const size_t size) |
| void * | nco_malloc_dbg (const size_t sz, const char *fnc_nm, const char *msg) |
| void | nco_malloc_err_hnt_prn (void) |
| long | nco_mmr_rusage_prn (const int rusage_who) |
| long | nco_mmr_stt (const nco_mmr_typ_enm nco_mmr_typ, const size_t sz) |
| const char * | nco_mmr_typ_sng (const nco_mmr_typ_enm nco_mmr_typ) |
| void * | nco_realloc (void *ptr, const size_t size) |
|
||||||||||||
|
Definition at line 32 of file nco_mmr.c. References EXIT_FAILURE, nco_exit(), nco_mmr_calloc, nco_mmr_stt(), and prg_nm_get(). Referenced by nco_msa_rec_clc(), and nco_var_lst_mk(). 00034 { 00035 /* Purpose: Custom wrapper for calloc(), modified from nco_malloc() 00036 Routine prints error when calloc() returns a NULL pointer 00037 Routine does not call calloc() when lmn_sz == 0 or lmn_nbr == 0 */ 00038 00039 void *ptr; /* [ptr] Pointer to new buffer */ 00040 00041 /* Circumvent calloc() calls when lmn_sz == 0 */ 00042 if(lmn_sz == 0 || lmn_nbr == 0) return NULL; 00043 00044 ptr=calloc(lmn_nbr,lmn_sz); /* [ptr] Pointer to new buffer */ 00045 if(ptr == NULL){ 00046 (void)fprintf(stdout,"%s: ERROR nco_calloc() unable to allocate %lu elements of %lu bytes = %lu bytes\n",prg_nm_get(),(unsigned long)lmn_nbr,(unsigned long)lmn_sz,(unsigned long)(lmn_nbr*lmn_sz)); 00047 nco_exit(EXIT_FAILURE); 00048 } /* endif */ 00049 #ifdef NCO_MMR_DBG 00050 (void)nco_mmr_stt(nco_mmr_calloc,lmn_nbr*lmn_sz); /* fxm dbg */ 00051 #endif /* !NCO_MMR_DBG */ 00052 return ptr; /* [ptr] Pointer to new buffer */ 00053 } /* nco_calloc() */
|
|
|
|
||||||||||||||||
|
Definition at line 139 of file nco_mmr.c. References EXIT_FAILURE, nco_exit(), nco_malloc_err_hnt_prn(), nco_mmr_malloc, nco_mmr_stt(), and prg_nm_get(). Referenced by ncap_var_stretch(), nco_cpy_var_val(), nco_cpy_var_val_lmt(), nco_var_dpl(), and nco_var_get(). 00142 { 00143 /* Purpose: Custom wrapper for malloc(), non-plugin, receives and prints more diagnostics 00144 Top of nco_mmr.c explains usage of nco_malloc(), nco_malloc_flg(), and nco_malloc_dbg() */ 00145 00146 #ifndef __GNUG__ 00147 extern int errno; /* [enm] Error code in errno.h */ 00148 #endif /* __GNUG__ */ 00149 00150 void *ptr; /* [ptr] Pointer to new buffer */ 00151 00152 /* malloc(0) is ANSI-legal, albeit unnecessary 00153 NCO sometimes employs this degenerate case behavior of malloc() to simplify code 00154 Some debugging tools like Electric Fence consider any NULL returned by malloc() to be an error 00155 So circumvent malloc() calls when sz == 0 */ 00156 if(sz == 0) return NULL; 00157 00158 ptr=malloc(sz); /* [ptr] Pointer to new buffer */ 00159 if(ptr == NULL){ 00160 (void)fprintf(stdout,"%s: ERROR malloc() returns error on %s request for %lu bytes\n",prg_nm_get(),fnc_nm,(unsigned long)sz); 00161 #ifndef __GNUG__ 00162 /* 20051205: Triggers G++ error: undefined reference to `__errno_location()' */ 00163 (void)fprintf(stdout,"%s: malloc() error is \"%s\"\n",prg_nm_get(),strerror(errno)); 00164 #endif /* __GNUG__ */ 00165 (void)fprintf(stdout,"%s: User-supplied supplemental error message is \"%s\"\n",prg_nm_get(),msg); 00166 (void)nco_malloc_err_hnt_prn(); 00167 nco_exit(EXIT_FAILURE); 00168 } /* endif */ 00169 #ifdef NCO_MMR_DBG 00170 (void)nco_mmr_stt(nco_mmr_malloc,sz); /* fxm dbg */ 00171 #endif /* !NCO_MMR_DBG */ 00172 return ptr; /* [ptr] Pointer to new buffer */ 00173 } /* nco_malloc_dbg() */
|
|
|
Definition at line 177 of file nco_mmr.c. References prg_nm_get(). Referenced by nco_malloc(), nco_malloc_dbg(), and nco_malloc_flg(). 00178 { 00179 /* Purpose: Explain meaning and workarounds for malloc() failures */ 00180 (void)fprintf(stdout,"%s: INFO NCO has reported a malloc() failure. malloc() failures usually indicate that your machine does not have enough free memory (RAM+swap) to perform the requested operation. As such, malloc() failures result from the physical limitations imposed by your hardware. Read http://nco.sf.net/nco.html#mmr for a description of NCO memory usage. There are two workarounds in this scenario. One is to process your data in smaller chunks. The other is to use a machine with more free memory.\n\nLarge tasks may uncover memory leaks in NCO. This is likeliest to occur with ncap. ncap scripts are completely dynamic and may be of arbitrary length and complexity. A script that contains many thousands of operations may uncover a slow memory leak even though each single operation consumes little additional memory. Memory leaks are usually identifiable by their memory usage signature. Leaks cause peak memory usage to increase monotonically with time regardless of script complexity. Slow leaks are very difficult to find. Sometimes a malloc() failure is the only noticeable clue to their existance. If you have good reasons to believe that your malloc() failure is ultimately due to an NCO memory leak (rather than inadequate RAM on your system), then we would be very interested in receiving a detailed bug report.",prg_nm_get()); 00181 } /* nco_malloc_err_hnt_prn() */
|
|
|
Definition at line 100 of file nco_mmr.c. References EXIT_FAILURE, nco_exit(), nco_malloc_err_hnt_prn(), nco_mmr_malloc, nco_mmr_stt(), and prg_nm_get(). Referenced by main(), ncap_mk_cst(), and nco_aed_prc(). 00101 { 00102 /* Purpose: Custom plugin wrapper for malloc() that allows ENOMEM errors 00103 Top of nco_mmr.c explains usage of nco_malloc(), nco_malloc_flg(), and nco_malloc_dbg() */ 00104 00105 #ifndef __GNUG__ 00106 extern int errno; /* [enm] Error code in errno.h */ 00107 #endif /* __GNUG__ */ 00108 00109 void *ptr; /* [ptr] Pointer to new buffer */ 00110 00111 /* malloc(0) is ANSI-legal, albeit unnecessary 00112 NCO sometimes employs this degenerate case behavior of malloc() to simplify code 00113 Some debugging tools like Electric Fence consider any NULL returned by malloc() to be an error 00114 So circumvent malloc() calls when sz == 0 */ 00115 if(sz == 0) return NULL; 00116 00117 ptr=malloc(sz); /* [ptr] Pointer to new buffer */ 00118 if(ptr == NULL){ 00119 (void)fprintf(stdout,"%s: WARNING nco_malloc_flg() unable to allocate %lu bytes\n",prg_nm_get(),(unsigned long)sz); 00120 #ifndef __GNUG__ 00121 /* 20051205: Triggers G++ error: undefined reference to `__errno_location()' */ 00122 (void)fprintf(stdout,"%s: malloc() error is \"%s\"\n",prg_nm_get(),strerror(errno)); 00123 if(errno == ENOMEM) return NULL; /* Unlike nco_malloc(), allow simple OOM errors */ 00124 #else 00125 return NULL; /* Unlike nco_malloc(), allow simple OOM errors */ 00126 #endif /* __GNUG__ */ 00127 (void)fprintf(stdout,"%s: ERROR is not ENOMEM, exiting...\n",prg_nm_get()); 00128 (void)nco_malloc_err_hnt_prn(); 00129 nco_exit(EXIT_FAILURE); 00130 } /* endif */ 00131 #ifdef NCO_MMR_DBG 00132 (void)nco_mmr_stt(nco_mmr_malloc,sz); /* fxm dbg */ 00133 #endif /* !NCO_MMR_DBG */ 00134 return ptr; /* [ptr] Pointer to new buffer */ 00135 } /* nco_malloc_flg() */
|
|
|
Definition at line 309 of file nco_mmr.c. References prg_nm_get(). Referenced by ncap_var_write(). 00310 { 00311 /* Purpose: Track memory statistics */ 00312 /* NB: As of kernel 2.6.9, Linux only maintains the fields ru_utime, ru_stime, ru_minflt, ru_majflt, and ru_nswap */ 00313 int rcd; 00314 int sz_pg; /* [B] Page size in Bytes */ 00315 struct rusage usg; 00316 00317 /* Get page size */ 00318 sz_pg=getpagesize(); 00319 00320 /* fxm: CEWI, not necessary */ 00321 rcd=rusage_who; 00322 /* fxm: use input argument rusage_who instead or RUSAGE_SELF */ 00323 rcd=getrusage(RUSAGE_SELF,&usg); 00324 00325 #ifdef AIX 00326 (void)fprintf(stdout,"%s: INFO nco_mmr_rusage_prn() reports system type is AIX so rusage uses kilobytes [kB] for size and seconds [s] for time. Page size is %d B.\n",prg_nm_get(),sz_pg); 00327 #endif /* !AIX */ 00328 #ifdef LINUX 00329 (void)fprintf(stdout,"%s: INFO nco_mmr_rusage_prn() reports system type is LINUX so rusage does not implement ru_maxrss, ru_ixrss, ru_idrss, and ru_idrss. Page size is %d B.\n",prg_nm_get(),sz_pg); 00330 #endif /* !LINUX */ 00331 #ifdef SUNMP 00332 (void)fprintf(stdout,"%s: INFO nco_mmr_rusage_prn() reports system type is SUNMP so rusage uses pages [pg] for size and ticks [tck] for time. Page size is %d B.\n",prg_nm_get(),sz_pg); 00333 #endif /* !SUNMP */ 00334 00335 /* rusage reports size and time in OS-dependent units: 00336 AIX uses kilobytes [kB] for size [sz] and seconds [s] for time [tm]: 00337 ru_maxrss [kB], ru_ixrss [kB s], ru_idrss [kB], ru_idrss [kB] 00338 http://publib.boulder.ibm.com/infocenter/pseries/index.jsp?topic=/com.ibm.aix.doc/libs/basetrf1/getrusage_64.htm 00339 00340 Linux does not implement these fields yet 00341 ru_maxrss, ru_ixrss, ru_idrss, ru_idrss 00342 00343 Solaris uses pages [pg] for size and ticks [tck] for time: 00344 ru_maxrss [pg], ru_ixrss [pg tck], ru_idrss [pg], ru_idrss [pg] 00345 http://docs.sun.com/app/docs/doc/816-5168/6mbb3hr9o?a=view */ 00346 00347 (void)fprintf(stdout,"%s: INFO nco_mmr_rusage_prn() reports: rusage.ru_utime.tv_sec = user time used = %li s, rusage.ru_utime.tv_usec = user time used = %li us, rusage.ru_stime.tv_sec = system time used = %li s, rusage.ru_stime.tv_usec = system time used = %li us, rusage.ru_maxrss = maximum resident set size = %li [sz], rusage.ru_ixrss = integral shared memory size = %li [sz tm], rusage.ru_idrss = integral unshared data size = %li [sz], rusage.ru_isrss = integral unshared stack size = %li [sz], rusage.ru_minflt = page reclaims = %li, rusage.ru_majflt = page faults = %li, rusage.ru_nswap = swaps = %li\n",prg_nm_get(),usg.ru_utime.tv_sec,usg.ru_utime.tv_usec,usg.ru_stime.tv_sec,usg.ru_stime.tv_usec,usg.ru_maxrss,usg.ru_ixrss,usg.ru_idrss,usg.ru_isrss,usg.ru_minflt,usg.ru_majflt,usg.ru_nswap); 00348 00349 return (long)usg.ru_maxrss; /* [B] Maximum resident set size */ 00350 } /* nco_mmr_rusage_prn() */
|
|
||||||||||||
|
Definition at line 262 of file nco_mmr.c. References EXIT_FAILURE, nco_exit(), nco_mmr_calloc, nco_mmr_free, nco_mmr_malloc, nco_mmr_realloc, nco_mmr_typ_sng(), prg_nm_get(), and True. Referenced by nco_calloc(), nco_free(), nco_malloc(), nco_malloc_dbg(), nco_malloc_flg(), and nco_realloc(). 00264 { 00265 /* Purpose: Track memory statistics */ 00266 static long mll_nbr=0L; /* [nbr] Number of malloc() invocations */ 00267 static long fre_nbr=0L; /* [nbr] Number of free() invocations */ 00268 static long mmr_mll_ttl=0L; /* [B] Total memory malloc()'d */ 00269 static long mmr_fre_ttl=0L; /* [B] Total memory free()'d */ 00270 static long mmr_net_crr=0L; /* [B] Net memory currently allocated */ 00271 long sz_lng; /* [B] Bytes allocated, deallocated, or reallocated, long */ 00272 00273 sz_lng=(long)sz; /* [B] Bytes allocated, deallocated, or reallocated */ 00274 switch(nco_mmr_typ){ 00275 case nco_mmr_calloc: 00276 mll_nbr++; /* [nbr] Number of malloc() invocations */ 00277 mmr_mll_ttl+=sz_lng; /* [B] Total memory malloc()'d */ 00278 mmr_net_crr+=sz_lng; /* [B] Net memory currently allocated */ 00279 break; 00280 case nco_mmr_free: 00281 fre_nbr++; /* [nbr] Number of free() invocations */ 00282 mmr_fre_ttl-=sz_lng; /* [B] Total memory free()'d */ 00283 mmr_net_crr-=sz_lng; /* [B] Net memory currently allocated */ 00284 break; 00285 case nco_mmr_malloc: 00286 mll_nbr++; /* [nbr] Number of malloc() invocations */ 00287 mmr_mll_ttl+=sz_lng; /* [B] Total memory malloc()'d */ 00288 mmr_net_crr+=sz_lng; /* [B] Net memory currently allocated */ 00289 break; 00290 case nco_mmr_realloc: 00291 mll_nbr++; /* [nbr] Number of malloc() invocations */ 00292 mmr_mll_ttl+=sz_lng; /* [B] Total memory malloc()'d */ 00293 mmr_net_crr+=sz_lng; /* [B] Net memory currently allocated */ 00294 break; 00295 default: 00296 nco_exit(EXIT_FAILURE); 00297 break; 00298 } /* end case */ 00299 00300 if(True){ 00301 (void)fprintf(stdout,"%s: INFO nco_mmr_stt() called by %s(): fre_nbr=%li, mll_nbr=%li, mmr_mll_ttl=%li, mmr_fre_ttl=%li, mmr_net_crr=%li bytes\n",prg_nm_get(),nco_mmr_typ_sng(nco_mmr_typ),fre_nbr,mll_nbr,mmr_mll_ttl,mmr_fre_ttl,mmr_net_crr); 00302 } /* endif */ 00303 00304 return mmr_net_crr; /* [B] Net memory currently allocated */ 00305 } /* nco_mmr_stt() */
|
|
|
Definition at line 186 of file nco_mmr.c. References nco_dfl_case_nc_type_err(), nco_mmr_calloc, nco_mmr_free, nco_mmr_malloc, and nco_mmr_realloc. Referenced by nco_mmr_stt(). 00187 { 00188 /* Purpose: Return name of memory function invoked */ 00189 switch(nco_mmr_typ){ 00190 case nco_mmr_calloc: 00191 return "nco_mmr_calloc"; 00192 case nco_mmr_free: 00193 return "nco_mmr_free"; 00194 case nco_mmr_malloc: 00195 return "nco_mmr_malloc"; 00196 case nco_mmr_realloc: 00197 return "nco_mmr_realloc"; 00198 default: nco_dfl_case_nc_type_err(); break; 00199 } /* end switch */ 00200 00201 /* fxm: any advantage to this form? defining with file scope in header? 00202 static const char * const nco_mmr_calloc_sng="nco_mmr_calloc_sng"; 00203 static const char * const nco_mmr_free_sng="nco_mmr_free_sng"; 00204 static const char * const nco_mmr_malloc_sng="nco_mmr_malloc_sng"; 00205 static const char * const nco_mmr_realloc_sng="nco_mmr_realloc_sng"; 00206 00207 switch(nco_mmr_typ){ 00208 case nco_mmr_calloc: 00209 return nco_mmr_calloc_sng; 00210 case nco_mmr_free: 00211 return nco_mmr_free_sng; 00212 case nco_mmr_malloc: 00213 return nco_mmr_malloc_sng; 00214 case nco_mmr_realloc: 00215 return nco_mmr_realloc_sng; 00216 default: nco_dfl_case_nc_type_err(); break; 00217 } *//* end switch */ 00218 00219 /* Some compilers, e.g., SGI cc, need return statement to end non-void functions */ 00220 return (char *)NULL; 00221 } /* end nco_mmr_typ_sng() */
|
|
||||||||||||
|
Definition at line 225 of file nco_mmr.c. References EXIT_FAILURE, nco_exit(), nco_free(), nco_malloc(), nco_mmr_realloc, nco_mmr_stt(), and prg_nm_get(). Referenced by glb_init_free(), main(), nco_att_lst_mk(), nco_dmn_lst_ass_var(), nco_dmn_out_grow(), nco_fl_lst_mk(), nco_fl_mk_lcl(), nco_msa_wrp_splt(), nco_mss_val_cp(), nco_mss_val_get(), nco_nm_id_lst_crd_make(), nco_var_avg(), nco_var_lst_add(), nco_var_lst_add_crd(), nco_var_lst_ass_crd_add(), nco_var_lst_crd_xcl(), nco_var_lst_dvd(), nco_var_lst_mk(), nco_var_lst_mrg(), nco_var_lst_sub(), and nco_var_lst_xcl(). 00227 { 00228 /* Purpose: Custom wrapper for realloc() 00229 Routine prints error when realloc() returns a NULL pointer 00230 Routine does not call realloc() when sz == 0 */ 00231 00232 void *new_ptr; /* [ptr] Pointer to new buffer */ 00233 00234 /* This degenerate case sometimes occurs 00235 Performing realloc() call here would be ANSI-legal but would trigger Electric Fence */ 00236 if(ptr == NULL && sz == 0) return ptr; 00237 if(ptr != NULL && sz == 0){ 00238 ptr=nco_free(ptr); 00239 ptr=NULL; 00240 return ptr; 00241 } /* endif */ 00242 00243 /* Passing NULL to realloc() is ANSI-legal, but may cause portability problems */ 00244 if(ptr == NULL && sz != 0){ 00245 new_ptr=nco_malloc(sz); /* [ptr] Pointer to new buffer */ 00246 }else{ 00247 new_ptr=realloc(ptr,sz); /* [ptr] Pointer to new buffer */ 00248 } /* endif */ 00249 if(new_ptr == NULL && sz != 0){ 00250 (void)fprintf(stdout,"%s: ERROR nco_realloc() unable to realloc() %lu bytes\n",prg_nm_get(),(unsigned long)sz); 00251 /* fxm: Should be exit(8) on ENOMEM errors? */ 00252 nco_exit(EXIT_FAILURE); 00253 } /* endif */ 00254 #ifdef NCO_MMR_DBG 00255 (void)nco_mmr_stt(nco_mmr_realloc,sz); /* fxm dbg */ 00256 #endif /* !NCO_MMR_DBG */ 00257 return new_ptr; /* [ptr] Pointer to new buffer */ 00258 } /* nco_realloc() */
|
1.4.4