1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * Copyright by The HDF Group.                                               *
3  * Copyright by the Board of Trustees of the University of Illinois.         *
4  * All rights reserved.                                                      *
5  *                                                                           *
6  * This file is part of HDF5.  The full HDF5 copyright notice, including     *
7  * terms governing use, modification, and redistribution, is contained in    *
8  * the COPYING file, which can be found at the root of the source code       *
9  * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases.  *
10  * If you do not have access to either file, you may request a copy from     *
11  * help@hdfgroup.org.                                                        *
12  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13 
14 /*-------------------------------------------------------------------------
15  *
16  * Created:     H5Cquery.c
17  *              May 30 2016
18  *              Quincey Koziol
19  *
20  * Purpose:     Routines which query different components of the generic
21  *              cache structure or entries.
22  *
23  *-------------------------------------------------------------------------
24  */
25 
26 /****************/
27 /* Module Setup */
28 /****************/
29 
30 #include "H5Cmodule.h"          /* This source code file is part of the H5C module */
31 #define H5F_FRIEND		/*suppress error about including H5Fpkg	  */
32 
33 
34 /***********/
35 /* Headers */
36 /***********/
37 #include "H5private.h"		/* Generic Functions			*/
38 #include "H5Cpkg.h"		/* Cache				*/
39 #include "H5Eprivate.h"		/* Error handling		  	*/
40 #include "H5Fpkg.h"		/* Files				*/
41 
42 
43 /****************/
44 /* Local Macros */
45 /****************/
46 
47 
48 /******************/
49 /* Local Typedefs */
50 /******************/
51 
52 
53 /********************/
54 /* Local Prototypes */
55 /********************/
56 
57 
58 /*********************/
59 /* Package Variables */
60 /*********************/
61 
62 
63 /*****************************/
64 /* Library Private Variables */
65 /*****************************/
66 
67 
68 /*******************/
69 /* Local Variables */
70 /*******************/
71 
72 
73 
74 /*-------------------------------------------------------------------------
75  * Function:    H5C_get_cache_auto_resize_config
76  *
77  * Purpose:	Copy the current configuration of the cache automatic
78  *		re-sizing function into the instance of H5C_auto_size_ctl_t
79  *		pointed to by config_ptr.
80  *
81  * Return:      SUCCEED on success, and FAIL on failure.
82  *
83  * Programmer:  John Mainzer
84  *		10/8/04
85  *
86  *-------------------------------------------------------------------------
87  */
88 herr_t
H5C_get_cache_auto_resize_config(const H5C_t * cache_ptr,H5C_auto_size_ctl_t * config_ptr)89 H5C_get_cache_auto_resize_config(const H5C_t * cache_ptr,
90                                  H5C_auto_size_ctl_t *config_ptr)
91 {
92     herr_t ret_value = SUCCEED;      /* Return value */
93 
94     FUNC_ENTER_NOAPI(FAIL)
95 
96     if((cache_ptr == NULL) || (cache_ptr->magic != H5C__H5C_T_MAGIC))
97         HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Bad cache_ptr on entry.")
98     if(config_ptr == NULL)
99         HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Bad config_ptr on entry.")
100 
101     *config_ptr = cache_ptr->resize_ctl;
102 
103     config_ptr->set_initial_size = FALSE;
104     config_ptr->initial_size = cache_ptr->max_cache_size;
105 
106 done:
107     FUNC_LEAVE_NOAPI(ret_value)
108 } /* H5C_get_cache_auto_resize_config() */
109 
110 
111 /*-------------------------------------------------------------------------
112  * Function:    H5C_get_cache_size
113  *
114  * Purpose:	Return the cache maximum size, the minimum clean size, the
115  *		current size, and the current number of entries in
116  *              *max_size_ptr, *min_clean_size_ptr, *cur_size_ptr, and
117  *		*cur_num_entries_ptr respectively.  If any of these
118  *		parameters are NULL, skip that value.
119  *
120  * Return:      SUCCEED on success, and FAIL on failure.
121  *
122  * Programmer:  John Mainzer
123  *		10/8/04
124  *
125  *-------------------------------------------------------------------------
126  */
127 herr_t
H5C_get_cache_size(H5C_t * cache_ptr,size_t * max_size_ptr,size_t * min_clean_size_ptr,size_t * cur_size_ptr,uint32_t * cur_num_entries_ptr)128 H5C_get_cache_size(H5C_t * cache_ptr,
129                    size_t * max_size_ptr,
130                    size_t * min_clean_size_ptr,
131                    size_t * cur_size_ptr,
132                    uint32_t * cur_num_entries_ptr)
133 {
134     herr_t ret_value = SUCCEED;      /* Return value */
135 
136     FUNC_ENTER_NOAPI(FAIL)
137 
138     if((cache_ptr == NULL) || (cache_ptr->magic != H5C__H5C_T_MAGIC))
139         HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Bad cache_ptr on entry.")
140 
141     if(max_size_ptr != NULL)
142         *max_size_ptr = cache_ptr->max_cache_size;
143 
144     if(min_clean_size_ptr != NULL)
145         *min_clean_size_ptr = cache_ptr->min_clean_size;
146 
147     if(cur_size_ptr != NULL)
148         *cur_size_ptr = cache_ptr->index_size;
149 
150     if(cur_num_entries_ptr != NULL)
151         *cur_num_entries_ptr = cache_ptr->index_len;
152 
153 done:
154     FUNC_LEAVE_NOAPI(ret_value)
155 } /* H5C_get_cache_size() */
156 
157 
158 /*-------------------------------------------------------------------------
159  * Function:    H5C_get_cache_hit_rate
160  *
161  * Purpose:	Compute and return the current cache hit rate in
162  *              *hit_rate_ptr.  If there have been no accesses since the
163  *              last time the cache hit rate stats were reset, set
164  *		*hit_rate_ptr to 0.0.  On error, *hit_rate_ptr is
165  *		undefined.
166  *
167  * Return:      SUCCEED on success, and FAIL on failure.
168  *
169  * Programmer:  John Mainzer
170  *		10/7/04
171  *
172  *-------------------------------------------------------------------------
173  */
174 herr_t
H5C_get_cache_hit_rate(H5C_t * cache_ptr,double * hit_rate_ptr)175 H5C_get_cache_hit_rate(H5C_t * cache_ptr, double * hit_rate_ptr)
176 {
177     herr_t ret_value = SUCCEED;      /* Return value */
178 
179     FUNC_ENTER_NOAPI(FAIL)
180 
181     if((cache_ptr == NULL) || (cache_ptr->magic != H5C__H5C_T_MAGIC))
182         HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Bad cache_ptr on entry.")
183     if(hit_rate_ptr == NULL)
184         HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Bad hit_rate_ptr on entry.")
185 
186     HDassert(cache_ptr->cache_hits >= 0);
187     HDassert(cache_ptr->cache_accesses >= cache_ptr->cache_hits);
188 
189     if(cache_ptr->cache_accesses > 0)
190         *hit_rate_ptr = ((double)(cache_ptr->cache_hits)) /
191                          ((double)(cache_ptr->cache_accesses));
192     else
193         *hit_rate_ptr = 0.0f;
194 
195 done:
196     FUNC_LEAVE_NOAPI(ret_value)
197 } /* H5C_get_cache_hit_rate() */
198 
199 
200 /*-------------------------------------------------------------------------
201  *
202  * Function:    H5C_get_entry_status
203  *
204  * Purpose:     This function is used to determine whether the cache
205  *		contains an entry with the specified base address.  If
206  *		the entry exists, it also reports some status information
207  *		on the entry.
208  *
209  *		Status information is reported in the locations pointed
210  *		to by the size_ptr, in_cache_ptr, is_dirty_ptr, and
211  *		is_protected_ptr.  While in_cache_ptr must be defined,
212  *		the remaining pointers may be NULL, in which case the
213  *		associated data is not reported.
214  *
215  * Return:      Non-negative on success/Negative on failure
216  *
217  * Programmer:  John Mainzer
218  *              7/1/05
219  *
220  *-------------------------------------------------------------------------
221  */
222 herr_t
H5C_get_entry_status(const H5F_t * f,haddr_t addr,size_t * size_ptr,hbool_t * in_cache_ptr,hbool_t * is_dirty_ptr,hbool_t * is_protected_ptr,hbool_t * is_pinned_ptr,hbool_t * is_corked_ptr,hbool_t * is_flush_dep_parent_ptr,hbool_t * is_flush_dep_child_ptr,hbool_t * image_up_to_date_ptr)223 H5C_get_entry_status(const H5F_t *f,
224                      haddr_t   addr,
225                      size_t *  size_ptr,
226                      hbool_t * in_cache_ptr,
227                      hbool_t * is_dirty_ptr,
228                      hbool_t * is_protected_ptr,
229 		     hbool_t * is_pinned_ptr,
230 		     hbool_t * is_corked_ptr,
231 		     hbool_t * is_flush_dep_parent_ptr,
232                      hbool_t * is_flush_dep_child_ptr,
233 		     hbool_t * image_up_to_date_ptr)
234 {
235     H5C_t             * cache_ptr;
236     H5C_cache_entry_t *	entry_ptr = NULL;
237     herr_t		ret_value = SUCCEED;      /* Return value */
238 
239     FUNC_ENTER_NOAPI(FAIL)
240 
241     /* Sanity checks */
242     HDassert(f);
243     HDassert(f->shared);
244 
245     cache_ptr = f->shared->cache;
246 
247     HDassert(cache_ptr != NULL);
248     HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
249     HDassert(H5F_addr_defined(addr));
250     HDassert(in_cache_ptr != NULL);
251 
252     /* this test duplicates two of the above asserts, but we need an
253      * invocation of HGOTO_ERROR to keep the compiler happy.
254      */
255     if((cache_ptr == NULL) || (cache_ptr->magic != H5C__H5C_T_MAGIC))
256         HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Bad cache_ptr on entry.")
257 
258     H5C__SEARCH_INDEX(cache_ptr, addr, entry_ptr, FAIL)
259 
260     if(entry_ptr == NULL) {
261         /* the entry doesn't exist in the cache -- report this
262          * and quit.
263          */
264         *in_cache_ptr = FALSE;
265     } /* end if */
266     else {
267         *in_cache_ptr = TRUE;
268         if(size_ptr != NULL)
269             *size_ptr = entry_ptr->size;
270         if(is_dirty_ptr != NULL)
271             *is_dirty_ptr = entry_ptr->is_dirty;
272         if(is_protected_ptr != NULL)
273             *is_protected_ptr = entry_ptr->is_protected;
274         if(is_pinned_ptr != NULL)
275             *is_pinned_ptr = entry_ptr->is_pinned;
276         if(is_corked_ptr != NULL)
277             *is_corked_ptr = entry_ptr->tag_info ? entry_ptr->tag_info->corked : FALSE;
278         if(is_flush_dep_parent_ptr != NULL)
279             *is_flush_dep_parent_ptr = (entry_ptr->flush_dep_nchildren > 0);
280         if(is_flush_dep_child_ptr != NULL)
281             *is_flush_dep_child_ptr = (entry_ptr->flush_dep_nparents > 0);
282         if(image_up_to_date_ptr != NULL )
283             *image_up_to_date_ptr = entry_ptr->image_up_to_date;
284     } /* end else */
285 
286 done:
287     FUNC_LEAVE_NOAPI(ret_value)
288 } /* H5C_get_entry_status() */
289 
290 
291 /*-------------------------------------------------------------------------
292  * Function:    H5C_get_evictions_enabled()
293  *
294  * Purpose:     Copy the current value of cache_ptr->evictions_enabled into
295  *              *evictions_enabled_ptr.
296  *
297  * Return:      SUCCEED on success, and FAIL on failure.
298  *
299  * Programmer:  John Mainzer
300  *              7/27/07
301  *
302  *-------------------------------------------------------------------------
303  */
304 herr_t
H5C_get_evictions_enabled(const H5C_t * cache_ptr,hbool_t * evictions_enabled_ptr)305 H5C_get_evictions_enabled(const H5C_t *cache_ptr,
306                           hbool_t * evictions_enabled_ptr)
307 {
308     herr_t ret_value = SUCCEED;      /* Return value */
309 
310     FUNC_ENTER_NOAPI(FAIL)
311 
312     if((cache_ptr == NULL ) || (cache_ptr->magic != H5C__H5C_T_MAGIC))
313         HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Bad cache_ptr on entry.")
314 
315     if(evictions_enabled_ptr == NULL)
316         HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Bad evictions_enabled_ptr on entry.")
317 
318     *evictions_enabled_ptr = cache_ptr->evictions_enabled;
319 
320 done:
321     FUNC_LEAVE_NOAPI(ret_value)
322 } /* H5C_get_evictions_enabled() */
323 
324 
325 /*-------------------------------------------------------------------------
326  * Function:    H5C_get_aux_ptr
327  *
328  * Purpose:     Get the aux_ptr field from the cache.
329  *
330  *              This field will either be NULL (when accessing a file serially)
331  *              or contains a pointer to the auxiliary info for parallel I/O.
332  *
333  * Return:      NULL/non-NULL (can't fail)
334  *
335  * Programmer:  Quincey Koziol
336  *              6/29/15
337  *
338  *-------------------------------------------------------------------------
339  */
340 void *
H5C_get_aux_ptr(const H5C_t * cache_ptr)341 H5C_get_aux_ptr(const H5C_t *cache_ptr)
342 {
343     FUNC_ENTER_NOAPI_NOERR
344 
345     /* Check arguments */
346     HDassert(cache_ptr);
347     HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
348 
349     FUNC_LEAVE_NOAPI(cache_ptr->aux_ptr)
350 } /* H5C_get_aux_ptr() */
351 
352 
353 /*-------------------------------------------------------------------------
354  * Function:    H5C_get_trace_file_ptr
355  *
356  * Purpose:     Get the trace_file_ptr field from the cache.
357  *
358  *              This field will either be NULL (which indicates that trace
359  *              file logging is turned off), or contain a pointer to the
360  *              open file to which trace file data is to be written.
361  *
362  * Return:      Non-NULL trace file pointer (can't fail)
363  *
364  * Programmer:  John Mainzer
365  *              1/20/06
366  *
367  *-------------------------------------------------------------------------
368  */
369 FILE *
H5C_get_trace_file_ptr(const H5C_t * cache_ptr)370 H5C_get_trace_file_ptr(const H5C_t *cache_ptr)
371 {
372     FUNC_ENTER_NOAPI_NOERR
373 
374     /* Check arguments */
375     HDassert(cache_ptr);
376     HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
377 
378     FUNC_LEAVE_NOAPI(cache_ptr->trace_file_ptr)
379 } /* H5C_get_trace_file_ptr() */
380 
381 
382 /*-------------------------------------------------------------------------
383  * Function:    H5C_get_trace_file_ptr_from_entry
384  *
385  * Purpose:     Get the trace_file_ptr field from the cache, via an entry.
386  *
387  *              This field will either be NULL (which indicates that trace
388  *              file logging is turned off), or contain a pointer to the
389  *              open file to which trace file data is to be written.
390  *
391  * Return:      Non-NULL trace file pointer (can't fail)
392  *
393  * Programmer:  Quincey Koziol
394  *              6/9/08
395  *
396  *-------------------------------------------------------------------------
397  */
398 FILE *
H5C_get_trace_file_ptr_from_entry(const H5C_cache_entry_t * entry_ptr)399 H5C_get_trace_file_ptr_from_entry(const H5C_cache_entry_t *entry_ptr)
400 {
401     FUNC_ENTER_NOAPI_NOERR
402 
403     /* Sanity checks */
404     HDassert(entry_ptr);
405     HDassert(entry_ptr->cache_ptr);
406 
407     FUNC_LEAVE_NOAPI(H5C_get_trace_file_ptr(entry_ptr->cache_ptr))
408 } /* H5C_get_trace_file_ptr_from_entry() */
409 
410 
411 /*-------------------------------------------------------------------------
412  * Function:    H5C_get_entry_ring
413  *
414  * Purpose:     Given a file address, retrieve the ring for an entry at that
415  *              address.
416  *
417  * 		On error, the value of *ring is not modified.
418  *
419  * Return:      Non-negative on success/Negative on failure
420  *
421  * Programmer:  Quincey Koziol
422  *              9/8/15
423  *
424  *-------------------------------------------------------------------------
425  */
426 herr_t
H5C_get_entry_ring(const H5F_t * f,haddr_t addr,H5C_ring_t * ring)427 H5C_get_entry_ring(const H5F_t *f, haddr_t addr, H5C_ring_t *ring)
428 {
429     H5C_t *cache_ptr;                   /* Pointer to cache */
430     H5C_cache_entry_t *entry_ptr;       /* Pointer to cache entry at address */
431     herr_t ret_value = SUCCEED;         /* Return value */
432 
433     FUNC_ENTER_NOAPI(FAIL)
434 
435     /* Sanity checks */
436     HDassert(f);
437     HDassert(f->shared);
438     cache_ptr = f->shared->cache;
439     HDassert(cache_ptr);
440     HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
441     HDassert(H5F_addr_defined(addr));
442 
443     /* Locate the entry at the address */
444     H5C__SEARCH_INDEX(cache_ptr, addr, entry_ptr, FAIL)
445     if(entry_ptr == NULL)
446         HGOTO_ERROR(H5E_CACHE, H5E_NOTFOUND, FAIL, "can't find entry in index")
447 
448     /* Return the ring value */
449     *ring = entry_ptr->ring;
450 
451 done:
452     FUNC_LEAVE_NOAPI(ret_value)
453 } /* H5C_get_entry_ring() */
454 
455 /*-------------------------------------------------------------------------
456  * Function:    H5C_get_mdc_image_info
457  *
458  * Purpose:	    To retrieve the address and size of the cache image in the file.
459  *
460  * Return:      SUCCEED on success, and FAIL on failure.
461  *
462  * Programmer:  Vailin Choi; March 2017
463  *
464  *-------------------------------------------------------------------------
465  */
466 herr_t
H5C_get_mdc_image_info(H5C_t * cache_ptr,haddr_t * image_addr,hsize_t * image_len)467 H5C_get_mdc_image_info(H5C_t * cache_ptr, haddr_t *image_addr, hsize_t *image_len)
468 {
469     herr_t ret_value = SUCCEED;      /* Return value */
470 
471     FUNC_ENTER_NOAPI(FAIL)
472 
473     if((cache_ptr == NULL) || (cache_ptr->magic != H5C__H5C_T_MAGIC))
474         HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "bad cache_ptr on entry")
475     if(image_addr == NULL || image_len == NULL)
476         HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "bad image_addr or image_len on entry")
477 
478     *image_addr = cache_ptr->image_addr;
479     *image_len = cache_ptr->image_len;
480 
481 done:
482     FUNC_LEAVE_NOAPI(ret_value)
483 } /* H5C_get_mdc_image_info() */
484 
485