GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: fx_utility_logical_sector_cache_entry_read.c Lines: 126 126 100.0 %
Date: 2024-01-10 21:53:23 Branches: 28 28 100.0 %

Line Branch Exec Source
1
/**************************************************************************/
2
/*                                                                        */
3
/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
4
/*                                                                        */
5
/*       This software is licensed under the Microsoft Software License   */
6
/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
7
/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
8
/*       and in the root directory of this software.                      */
9
/*                                                                        */
10
/**************************************************************************/
11
12
13
/**************************************************************************/
14
/**************************************************************************/
15
/**                                                                       */
16
/** FileX Component                                                       */
17
/**                                                                       */
18
/**   Utility                                                             */
19
/**                                                                       */
20
/**************************************************************************/
21
/**************************************************************************/
22
23
#define FX_SOURCE_CODE
24
25
26
/* Include necessary system files.  */
27
28
#include "fx_api.h"
29
#include "fx_system.h"
30
#include "fx_utility.h"
31
32
33
/**************************************************************************/
34
/*                                                                        */
35
/*  FUNCTION                                               RELEASE        */
36
/*                                                                        */
37
/*    _fx_utility_logical_sector_cache_entry_read         PORTABLE C      */
38
/*                                                           6.1.10       */
39
/*  AUTHOR                                                                */
40
/*                                                                        */
41
/*    William E. Lamie, Microsoft Corporation                             */
42
/*                                                                        */
43
/*  DESCRIPTION                                                           */
44
/*                                                                        */
45
/*    This function handles logical sector cache read requests for the    */
46
/*    logical sector read function. If the function finds the requested   */
47
/*    sector in the cache, it setup the appropriate pointers and          */
48
/*    returns a FX_NULL.                                                  */
49
/*                                                                        */
50
/*  INPUT                                                                 */
51
/*                                                                        */
52
/*    media_ptr                             Media control block pointer   */
53
/*    logical_sector                        Logical sector number         */
54
/*    previous_cache_entry                  Pointer to previous entry in  */
55
/*                                            non-hashed cache            */
56
/*                                                                        */
57
/*  OUTPUT                                                                */
58
/*                                                                        */
59
/*    FX_CACHED_SECTOR *                    Cache entry to setup          */
60
/*                                                                        */
61
/*  CALLS                                                                 */
62
/*                                                                        */
63
/*    None                                                                */
64
/*                                                                        */
65
/*  CALLED BY                                                             */
66
/*                                                                        */
67
/*    _fx_utility_logical_sector_read       Logical sector read function  */
68
/*                                                                        */
69
/*  RELEASE HISTORY                                                       */
70
/*                                                                        */
71
/*    DATE              NAME                      DESCRIPTION             */
72
/*                                                                        */
73
/*  05-19-2020     William E. Lamie         Initial Version 6.0           */
74
/*  09-30-2020     William E. Lamie         Modified comment(s), and      */
75
/*                                            added conditional to        */
76
/*                                            disable cache,              */
77
/*                                            resulting in version 6.1    */
78
/*  01-31-2022     William E. Lamie         Modified comment(s), fixed    */
79
/*                                            errors without cache,       */
80
/*                                            resulting in version 6.1.10 */
81
/*                                                                        */
82
/**************************************************************************/
83
9703907
FX_CACHED_SECTOR  *_fx_utility_logical_sector_cache_entry_read(FX_MEDIA *media_ptr, ULONG64 logical_sector,
84
                                                               FX_CACHED_SECTOR **previous_cache_entry)
85
{
86
87
#ifndef FX_DISABLE_CACHE
88
FX_CACHED_SECTOR *cache_entry;
89
FX_CACHED_SECTOR  temp_storage;
90
ULONG             cache_size;
91
ULONG             index;
92
93
94
    /* Determine if the logical sector cache access should use the hash function.  */
95
9703907
    if (media_ptr -> fx_media_sector_cache_hashed)
96
    {
97
98
        /* Calculate the area of the cache for this logical sector.  */
99
100
        /* First compute the hashed value of this index by simply using the lower bits of
101
           the sector number.  */
102
2827822
        index =  (ULONG)(logical_sector & media_ptr -> fx_media_sector_cache_hash_mask);
103
104
        /* Set the bit indicating there is one or more valid sectors at this cache index.  */
105
2827822
        media_ptr -> fx_media_sector_cache_hashed_sector_valid |=  ((ULONG)1) << (index % 32);
106
107
        /* Compute the actual array index by multiplying by the cache depth.  */
108
2827822
        index =  index * FX_SECTOR_CACHE_DEPTH;
109
110
        /* Build a pointer to the cache entry.  */
111
2827822
        cache_entry =  &(media_ptr -> fx_media_sector_cache[index]);
112
113
        /* Determine if the logical sector is in the cache - assuming the depth of the
114
           sector cache is 4 entries.  */
115

2827822
        if ((cache_entry -> fx_cached_sector_valid) && (cache_entry -> fx_cached_sector == logical_sector))
116
        {
117
118
            /* Yes, we found a match.  Simply setup the pointer to this
119
               buffer and return.  */
120
2657552
            media_ptr -> fx_media_memory_buffer =  cache_entry -> fx_cached_sector_memory_buffer;
121
122
#ifndef FX_MEDIA_STATISTICS_DISABLE
123
124
            /* Increment the number of logical sectors cache read hits.  */
125
2657552
            media_ptr -> fx_media_logical_sector_cache_read_hits++;
126
#endif
127
            /* Success, return to caller immediately!  */
128
2657552
            return(FX_NULL);
129
        }
130

170270
        else if (((cache_entry + 1) -> fx_cached_sector_valid) && ((cache_entry + 1) -> fx_cached_sector == logical_sector))
131
        {
132
133
            /* Yes, we found a match.  Simply setup the pointer to this
134
               buffer and return.  */
135
15171
            media_ptr -> fx_media_memory_buffer =  (cache_entry + 1) -> fx_cached_sector_memory_buffer;
136
137
#ifndef FX_MEDIA_STATISTICS_DISABLE
138
139
            /* Increment the number of logical sectors cache read hits.  */
140
15171
            media_ptr -> fx_media_logical_sector_cache_read_hits++;
141
#endif
142
143
            /* Swap the first and second cache entries to keep the most recently used
144
               at the top.  */
145
15171
            temp_storage.fx_cached_sector_memory_buffer =           (cache_entry) -> fx_cached_sector_memory_buffer;
146
15171
            temp_storage.fx_cached_sector =                         (cache_entry) -> fx_cached_sector;
147
15171
            temp_storage.fx_cached_sector_buffer_dirty =            (cache_entry) -> fx_cached_sector_buffer_dirty;
148
15171
            temp_storage.fx_cached_sector_valid =                   (cache_entry) -> fx_cached_sector_valid;
149
15171
            temp_storage.fx_cached_sector_type =                    (cache_entry) -> fx_cached_sector_type;
150
151
15171
            (cache_entry) -> fx_cached_sector_memory_buffer =       (cache_entry + 1) -> fx_cached_sector_memory_buffer;
152
15171
            (cache_entry) -> fx_cached_sector =                     (cache_entry + 1) -> fx_cached_sector;
153
15171
            (cache_entry) -> fx_cached_sector_buffer_dirty =        (cache_entry + 1) -> fx_cached_sector_buffer_dirty;
154
15171
            (cache_entry) -> fx_cached_sector_valid =               (cache_entry + 1) -> fx_cached_sector_valid;
155
15171
            (cache_entry) -> fx_cached_sector_type =                (cache_entry + 1) -> fx_cached_sector_type;
156
157
15171
            (cache_entry + 1) -> fx_cached_sector_memory_buffer =   temp_storage.fx_cached_sector_memory_buffer;
158
15171
            (cache_entry + 1) -> fx_cached_sector =                 temp_storage.fx_cached_sector;
159
15171
            (cache_entry + 1) -> fx_cached_sector_buffer_dirty =    temp_storage.fx_cached_sector_buffer_dirty;
160
15171
            (cache_entry + 1) -> fx_cached_sector_valid =           temp_storage.fx_cached_sector_valid;
161
15171
            (cache_entry + 1) -> fx_cached_sector_type =            temp_storage.fx_cached_sector_type;
162
163
            /* Success, return to caller immediately!  */
164
15171
            return(FX_NULL);
165
        }
166

155099
        else if (((cache_entry + 2) -> fx_cached_sector_valid) && ((cache_entry + 2) -> fx_cached_sector == logical_sector))
167
        {
168
169
            /* Yes, we found a match.  Simply setup the pointer to this
170
               buffer and return.  */
171
1492
            media_ptr -> fx_media_memory_buffer =  (cache_entry + 2) -> fx_cached_sector_memory_buffer;
172
173
#ifndef FX_MEDIA_STATISTICS_DISABLE
174
175
            /* Increment the number of logical sectors cache read hits.  */
176
1492
            media_ptr -> fx_media_logical_sector_cache_read_hits++;
177
#endif
178
179
            /* Move the third entry to the top and the first two entries down.  */
180
1492
            temp_storage.fx_cached_sector_memory_buffer =           (cache_entry) -> fx_cached_sector_memory_buffer;
181
1492
            temp_storage.fx_cached_sector =                         (cache_entry) -> fx_cached_sector;
182
1492
            temp_storage.fx_cached_sector_buffer_dirty =            (cache_entry) -> fx_cached_sector_buffer_dirty;
183
1492
            temp_storage.fx_cached_sector_valid =                   (cache_entry) -> fx_cached_sector_valid;
184
1492
            temp_storage.fx_cached_sector_type =                    (cache_entry) -> fx_cached_sector_type;
185
186
1492
            (cache_entry) -> fx_cached_sector_memory_buffer =       (cache_entry + 2) -> fx_cached_sector_memory_buffer;
187
1492
            (cache_entry) -> fx_cached_sector =                     (cache_entry + 2) -> fx_cached_sector;
188
1492
            (cache_entry) -> fx_cached_sector_buffer_dirty =        (cache_entry + 2) -> fx_cached_sector_buffer_dirty;
189
1492
            (cache_entry) -> fx_cached_sector_valid =               (cache_entry + 2) -> fx_cached_sector_valid;
190
1492
            (cache_entry) -> fx_cached_sector_type =                (cache_entry + 2) -> fx_cached_sector_type;
191
192
1492
            (cache_entry + 2) -> fx_cached_sector_memory_buffer =   (cache_entry + 1) -> fx_cached_sector_memory_buffer;
193
1492
            (cache_entry + 2) -> fx_cached_sector =                 (cache_entry + 1) -> fx_cached_sector;
194
1492
            (cache_entry + 2) -> fx_cached_sector_buffer_dirty =    (cache_entry + 1) -> fx_cached_sector_buffer_dirty;
195
1492
            (cache_entry + 2) -> fx_cached_sector_valid =           (cache_entry + 1) -> fx_cached_sector_valid;
196
1492
            (cache_entry + 2) -> fx_cached_sector_type =            (cache_entry + 1) -> fx_cached_sector_type;
197
198
1492
            (cache_entry + 1) -> fx_cached_sector_memory_buffer =   temp_storage.fx_cached_sector_memory_buffer;
199
1492
            (cache_entry + 1) -> fx_cached_sector =                 temp_storage.fx_cached_sector;
200
1492
            (cache_entry + 1) -> fx_cached_sector_buffer_dirty =    temp_storage.fx_cached_sector_buffer_dirty;
201
1492
            (cache_entry + 1) -> fx_cached_sector_valid =           temp_storage.fx_cached_sector_valid;
202
1492
            (cache_entry + 1) -> fx_cached_sector_type =            temp_storage.fx_cached_sector_type;
203
204
            /* Success, return to caller immediately!  */
205
1492
            return(FX_NULL);
206
        }
207

153607
        else if (((cache_entry + 3) -> fx_cached_sector_valid) && ((cache_entry + 3) -> fx_cached_sector == logical_sector))
208
        {
209
210
            /* Yes, we found a match.  Simply setup the pointer to this
211
               buffer and return.  */
212
1299
            media_ptr -> fx_media_memory_buffer =  (cache_entry + 3) -> fx_cached_sector_memory_buffer;
213
214
#ifndef FX_MEDIA_STATISTICS_DISABLE
215
216
            /* Increment the number of logical sectors cache read hits.  */
217
1299
            media_ptr -> fx_media_logical_sector_cache_read_hits++;
218
#endif
219
220
            /* Move the last entry to the top and the first three entries down.  */
221
1299
            temp_storage.fx_cached_sector_memory_buffer =           (cache_entry) -> fx_cached_sector_memory_buffer;
222
1299
            temp_storage.fx_cached_sector =                         (cache_entry) -> fx_cached_sector;
223
1299
            temp_storage.fx_cached_sector_buffer_dirty =            (cache_entry) -> fx_cached_sector_buffer_dirty;
224
1299
            temp_storage.fx_cached_sector_valid =                   (cache_entry) -> fx_cached_sector_valid;
225
1299
            temp_storage.fx_cached_sector_type =                    (cache_entry) -> fx_cached_sector_type;
226
227
1299
            (cache_entry) -> fx_cached_sector_memory_buffer =       (cache_entry + 3) -> fx_cached_sector_memory_buffer;
228
1299
            (cache_entry) -> fx_cached_sector =                     (cache_entry + 3) -> fx_cached_sector;
229
1299
            (cache_entry) -> fx_cached_sector_buffer_dirty =        (cache_entry + 3) -> fx_cached_sector_buffer_dirty;
230
1299
            (cache_entry) -> fx_cached_sector_valid =               (cache_entry + 3) -> fx_cached_sector_valid;
231
1299
            (cache_entry) -> fx_cached_sector_type =                (cache_entry + 3) -> fx_cached_sector_type;
232
233
1299
            (cache_entry + 3) -> fx_cached_sector_memory_buffer =   (cache_entry + 2) -> fx_cached_sector_memory_buffer;
234
1299
            (cache_entry + 3) -> fx_cached_sector =                 (cache_entry + 2) -> fx_cached_sector;
235
1299
            (cache_entry + 3) -> fx_cached_sector_buffer_dirty =    (cache_entry + 2) -> fx_cached_sector_buffer_dirty;
236
1299
            (cache_entry + 3) -> fx_cached_sector_valid =           (cache_entry + 2) -> fx_cached_sector_valid;
237
1299
            (cache_entry + 3) -> fx_cached_sector_type =            (cache_entry + 2) -> fx_cached_sector_type;
238
239
1299
            (cache_entry + 2) -> fx_cached_sector_memory_buffer =   (cache_entry + 1) -> fx_cached_sector_memory_buffer;
240
1299
            (cache_entry + 2) -> fx_cached_sector =                 (cache_entry + 1) -> fx_cached_sector;
241
1299
            (cache_entry + 2) -> fx_cached_sector_buffer_dirty =    (cache_entry + 1) -> fx_cached_sector_buffer_dirty;
242
1299
            (cache_entry + 2) -> fx_cached_sector_valid =           (cache_entry + 1) -> fx_cached_sector_valid;
243
1299
            (cache_entry + 2) -> fx_cached_sector_type =            (cache_entry + 1) -> fx_cached_sector_type;
244
245
1299
            (cache_entry + 1) -> fx_cached_sector_memory_buffer =   temp_storage.fx_cached_sector_memory_buffer;
246
1299
            (cache_entry + 1) -> fx_cached_sector =                 temp_storage.fx_cached_sector;
247
1299
            (cache_entry + 1) -> fx_cached_sector_buffer_dirty =    temp_storage.fx_cached_sector_buffer_dirty;
248
1299
            (cache_entry + 1) -> fx_cached_sector_valid =           temp_storage.fx_cached_sector_valid;
249
1299
            (cache_entry + 1) -> fx_cached_sector_type =            temp_storage.fx_cached_sector_type;
250
251
            /* Success, return to caller immediately!  */
252
1299
            return(FX_NULL);
253
        }
254
255
        /* At this point we have a cache miss.  We need to move all of the sectors down one slot, swapping
256
           the 4th entry with the first.  */
257
152308
        temp_storage.fx_cached_sector_memory_buffer =           (cache_entry + 3) -> fx_cached_sector_memory_buffer;
258
152308
        temp_storage.fx_cached_sector =                         (cache_entry + 3) -> fx_cached_sector;
259
152308
        temp_storage.fx_cached_sector_buffer_dirty =            (cache_entry + 3) -> fx_cached_sector_buffer_dirty;
260
152308
        temp_storage.fx_cached_sector_valid =                   (cache_entry + 3) -> fx_cached_sector_valid;
261
152308
        temp_storage.fx_cached_sector_type =                    (cache_entry + 3) -> fx_cached_sector_type;
262
263
152308
        (cache_entry + 3) -> fx_cached_sector_memory_buffer =   (cache_entry + 2) -> fx_cached_sector_memory_buffer;
264
152308
        (cache_entry + 3) -> fx_cached_sector =                 (cache_entry + 2) -> fx_cached_sector;
265
152308
        (cache_entry + 3) -> fx_cached_sector_buffer_dirty =    (cache_entry + 2) -> fx_cached_sector_buffer_dirty;
266
152308
        (cache_entry + 3) -> fx_cached_sector_valid =           (cache_entry + 2) -> fx_cached_sector_valid;
267
152308
        (cache_entry + 3) -> fx_cached_sector_type =            (cache_entry + 2) -> fx_cached_sector_type;
268
269
152308
        (cache_entry + 2) -> fx_cached_sector_memory_buffer =   (cache_entry + 1) -> fx_cached_sector_memory_buffer;
270
152308
        (cache_entry + 2) -> fx_cached_sector =                 (cache_entry + 1) -> fx_cached_sector;
271
152308
        (cache_entry + 2) -> fx_cached_sector_buffer_dirty =    (cache_entry + 1) -> fx_cached_sector_buffer_dirty;
272
152308
        (cache_entry + 2) -> fx_cached_sector_valid =           (cache_entry + 1) -> fx_cached_sector_valid;
273
152308
        (cache_entry + 2) -> fx_cached_sector_type =            (cache_entry + 1) -> fx_cached_sector_type;
274
275
152308
        (cache_entry + 1) -> fx_cached_sector_memory_buffer =   (cache_entry) -> fx_cached_sector_memory_buffer;
276
152308
        (cache_entry + 1) -> fx_cached_sector =                 (cache_entry) -> fx_cached_sector;
277
152308
        (cache_entry + 1) -> fx_cached_sector_buffer_dirty =    (cache_entry) -> fx_cached_sector_buffer_dirty;
278
152308
        (cache_entry + 1) -> fx_cached_sector_valid =           (cache_entry) -> fx_cached_sector_valid;
279
152308
        (cache_entry + 1) -> fx_cached_sector_type =            (cache_entry) -> fx_cached_sector_type;
280
281
152308
        (cache_entry) -> fx_cached_sector_memory_buffer =       temp_storage.fx_cached_sector_memory_buffer;
282
152308
        (cache_entry) -> fx_cached_sector =                     temp_storage.fx_cached_sector;
283
152308
        (cache_entry) -> fx_cached_sector_buffer_dirty =        temp_storage.fx_cached_sector_buffer_dirty;
284
152308
        (cache_entry) -> fx_cached_sector_valid =               temp_storage.fx_cached_sector_valid;
285
152308
        (cache_entry) -> fx_cached_sector_type =                temp_storage.fx_cached_sector_type;
286
287
        /* Set the previous pointer to NULL to avoid the linked list update below.  */
288
152308
        *previous_cache_entry =  FX_NULL;
289
    }
290
    else
291
    {
292
293
        /* Search for an entry in the cache that matches this request.  */
294
6876085
        cache_size =            media_ptr -> fx_media_sector_cache_size;
295
6876085
        cache_entry =           media_ptr -> fx_media_sector_cache_list_ptr;
296
6876085
        *previous_cache_entry =  FX_NULL;
297
298
        /* Look at the cache entries until a match is found or the end of
299
           the cache is reached.  */
300
49382853
        while (cache_size--)
301
        {
302
303
            /* Determine if the requested sector has been found.  */
304

46856837
            if ((cache_entry -> fx_cached_sector_valid) && (cache_entry -> fx_cached_sector == logical_sector))
305
            {
306
307
                /* Yes, we found a match.  Simply setup the pointer to this
308
                   buffer and return.  */
309
4350069
                media_ptr -> fx_media_memory_buffer =  cache_entry -> fx_cached_sector_memory_buffer;
310
311
                /* Determine if we need to update the last used list.  */
312
4350069
                if (*previous_cache_entry)
313
                {
314
315
                    /* Yes, the current entry is not at the front of the list
316
                       so we need to change the order.  */
317
318
                    /* Link the previous entry to this entry's next pointer.  */
319
2085927
                    (*previous_cache_entry) -> fx_cached_sector_next_used =
320
2085927
                        cache_entry -> fx_cached_sector_next_used;
321
322
                    /* Place this entry at the head of the list.  */
323
2085927
                    cache_entry -> fx_cached_sector_next_used =
324
2085927
                        media_ptr -> fx_media_sector_cache_list_ptr;
325
2085927
                    media_ptr -> fx_media_sector_cache_list_ptr =  cache_entry;
326
                }
327
328
#ifndef FX_MEDIA_STATISTICS_DISABLE
329
330
                /* Increment the number of logical sectors cache read hits.  */
331
4350069
                media_ptr -> fx_media_logical_sector_cache_read_hits++;
332
#endif
333
334
                /* Success, return to caller immediately!  */
335
4350069
                return(FX_NULL);
336
            }
337
338
            /* Otherwise, we have not found the cached entry yet.  */
339
340
            /* If there are more entries, move to the next one.  */
341
42506768
            if (cache_entry -> fx_cached_sector_next_used)
342
            {
343
344
39980752
                *previous_cache_entry =  cache_entry;
345
39980752
                cache_entry =           cache_entry -> fx_cached_sector_next_used;
346
            }
347
        }
348
    }
349
350
    /* The requested sector is not in cache, return the last cache entry.  */
351
2678324
    return(cache_entry);
352
#else
353
    FX_PARAMETER_NOT_USED(media_ptr);
354
    FX_PARAMETER_NOT_USED(logical_sector);
355
    FX_PARAMETER_NOT_USED(previous_cache_entry);
356
    return(FX_NULL);
357
#endif /* FX_DISABLE_CACHE */
358
}
359