OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [acpi/] [utilities/] [utalloc.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/******************************************************************************
2
 *
3
 * Module Name: utalloc - local cache and memory allocation routines
4
 *
5
 *****************************************************************************/
6
 
7
/*
8
 * Copyright (C) 2000 - 2004, R. Byron Moore
9
 * All rights reserved.
10
 *
11
 * Redistribution and use in source and binary forms, with or without
12
 * modification, are permitted provided that the following conditions
13
 * are met:
14
 * 1. Redistributions of source code must retain the above copyright
15
 *    notice, this list of conditions, and the following disclaimer,
16
 *    without modification.
17
 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18
 *    substantially similar to the "NO WARRANTY" disclaimer below
19
 *    ("Disclaimer") and any redistribution must be conditioned upon
20
 *    including a substantially similar Disclaimer requirement for further
21
 *    binary redistribution.
22
 * 3. Neither the names of the above-listed copyright holders nor the names
23
 *    of any contributors may be used to endorse or promote products derived
24
 *    from this software without specific prior written permission.
25
 *
26
 * Alternatively, this software may be distributed under the terms of the
27
 * GNU General Public License ("GPL") version 2 as published by the Free
28
 * Software Foundation.
29
 *
30
 * NO WARRANTY
31
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35
 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41
 * POSSIBILITY OF SUCH DAMAGES.
42
 */
43
 
44
 
45
#include <acpi/acpi.h>
46
 
47
#define _COMPONENT          ACPI_UTILITIES
48
         ACPI_MODULE_NAME    ("utalloc")
49
 
50
 
51
/******************************************************************************
52
 *
53
 * FUNCTION:    acpi_ut_release_to_cache
54
 *
55
 * PARAMETERS:  list_id             - Memory list/cache ID
56
 *              Object              - The object to be released
57
 *
58
 * RETURN:      None
59
 *
60
 * DESCRIPTION: Release an object to the specified cache.  If cache is full,
61
 *              the object is deleted.
62
 *
63
 ******************************************************************************/
64
 
65
void
66
acpi_ut_release_to_cache (
67
        u32                             list_id,
68
        void                            *object)
69
{
70
        struct acpi_memory_list         *cache_info;
71
 
72
 
73
        ACPI_FUNCTION_ENTRY ();
74
 
75
 
76
        /* If walk cache is full, just free this wallkstate object */
77
 
78
        cache_info = &acpi_gbl_memory_lists[list_id];
79
        if (cache_info->cache_depth >= cache_info->max_cache_depth) {
80
                ACPI_MEM_FREE (object);
81
                ACPI_MEM_TRACKING (cache_info->total_freed++);
82
        }
83
 
84
        /* Otherwise put this object back into the cache */
85
 
86
        else {
87
                if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_CACHES))) {
88
                        return;
89
                }
90
 
91
                /* Mark the object as cached */
92
 
93
                ACPI_MEMSET (object, 0xCA, cache_info->object_size);
94
                ACPI_SET_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_CACHED);
95
 
96
                /* Put the object at the head of the cache list */
97
 
98
                * (ACPI_CAST_INDIRECT_PTR (char, &(((char *) object)[cache_info->link_offset]))) = cache_info->list_head;
99
                cache_info->list_head = object;
100
                cache_info->cache_depth++;
101
 
102
                (void) acpi_ut_release_mutex (ACPI_MTX_CACHES);
103
        }
104
}
105
 
106
 
107
/******************************************************************************
108
 *
109
 * FUNCTION:    acpi_ut_acquire_from_cache
110
 *
111
 * PARAMETERS:  list_id             - Memory list ID
112
 *
113
 * RETURN:      A requested object.  NULL if the object could not be
114
 *              allocated.
115
 *
116
 * DESCRIPTION: Get an object from the specified cache.  If cache is empty,
117
 *              the object is allocated.
118
 *
119
 ******************************************************************************/
120
 
121
void *
122
acpi_ut_acquire_from_cache (
123
        u32                             list_id)
124
{
125
        struct acpi_memory_list         *cache_info;
126
        void                            *object;
127
 
128
 
129
        ACPI_FUNCTION_NAME ("ut_acquire_from_cache");
130
 
131
 
132
        cache_info = &acpi_gbl_memory_lists[list_id];
133
        if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_CACHES))) {
134
                return (NULL);
135
        }
136
 
137
        ACPI_MEM_TRACKING (cache_info->cache_requests++);
138
 
139
        /* Check the cache first */
140
 
141
        if (cache_info->list_head) {
142
                /* There is an object available, use it */
143
 
144
                object = cache_info->list_head;
145
                cache_info->list_head = *(ACPI_CAST_INDIRECT_PTR (char, &(((char *) object)[cache_info->link_offset])));
146
 
147
                ACPI_MEM_TRACKING (cache_info->cache_hits++);
148
                cache_info->cache_depth--;
149
 
150
#ifdef ACPI_DBG_TRACK_ALLOCATIONS
151
                ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Object %p from %s\n",
152
                        object, acpi_gbl_memory_lists[list_id].list_name));
153
#endif
154
 
155
                if (ACPI_FAILURE (acpi_ut_release_mutex (ACPI_MTX_CACHES))) {
156
                        return (NULL);
157
                }
158
 
159
                /* Clear (zero) the previously used Object */
160
 
161
                ACPI_MEMSET (object, 0, cache_info->object_size);
162
        }
163
 
164
        else {
165
                /* The cache is empty, create a new object */
166
 
167
                /* Avoid deadlock with ACPI_MEM_CALLOCATE */
168
 
169
                if (ACPI_FAILURE (acpi_ut_release_mutex (ACPI_MTX_CACHES))) {
170
                        return (NULL);
171
                }
172
 
173
                object = ACPI_MEM_CALLOCATE (cache_info->object_size);
174
                ACPI_MEM_TRACKING (cache_info->total_allocated++);
175
        }
176
 
177
        return (object);
178
}
179
 
180
 
181
/******************************************************************************
182
 *
183
 * FUNCTION:    acpi_ut_delete_generic_cache
184
 *
185
 * PARAMETERS:  list_id         - Memory list ID
186
 *
187
 * RETURN:      None
188
 *
189
 * DESCRIPTION: Free all objects within the requested cache.
190
 *
191
 ******************************************************************************/
192
 
193
void
194
acpi_ut_delete_generic_cache (
195
        u32                             list_id)
196
{
197
        struct acpi_memory_list         *cache_info;
198
        char                            *next;
199
 
200
 
201
        ACPI_FUNCTION_ENTRY ();
202
 
203
 
204
        cache_info = &acpi_gbl_memory_lists[list_id];
205
        while (cache_info->list_head) {
206
                /* Delete one cached state object */
207
 
208
                next = *(ACPI_CAST_INDIRECT_PTR (char, &(((char *) cache_info->list_head)[cache_info->link_offset])));
209
                ACPI_MEM_FREE (cache_info->list_head);
210
 
211
                cache_info->list_head = next;
212
                cache_info->cache_depth--;
213
        }
214
}
215
 
216
 
217
/*******************************************************************************
218
 *
219
 * FUNCTION:    acpi_ut_validate_buffer
220
 *
221
 * PARAMETERS:  Buffer              - Buffer descriptor to be validated
222
 *
223
 * RETURN:      Status
224
 *
225
 * DESCRIPTION: Perform parameter validation checks on an struct acpi_buffer
226
 *
227
 ******************************************************************************/
228
 
229
acpi_status
230
acpi_ut_validate_buffer (
231
        struct acpi_buffer              *buffer)
232
{
233
 
234
        /* Obviously, the structure pointer must be valid */
235
 
236
        if (!buffer) {
237
                return (AE_BAD_PARAMETER);
238
        }
239
 
240
        /* Special semantics for the length */
241
 
242
        if ((buffer->length == ACPI_NO_BUFFER)              ||
243
                (buffer->length == ACPI_ALLOCATE_BUFFER)        ||
244
                (buffer->length == ACPI_ALLOCATE_LOCAL_BUFFER)) {
245
                return (AE_OK);
246
        }
247
 
248
        /* Length is valid, the buffer pointer must be also */
249
 
250
        if (!buffer->pointer) {
251
                return (AE_BAD_PARAMETER);
252
        }
253
 
254
        return (AE_OK);
255
}
256
 
257
 
258
/*******************************************************************************
259
 *
260
 * FUNCTION:    acpi_ut_initialize_buffer
261
 *
262
 * PARAMETERS:  required_length     - Length needed
263
 *              Buffer              - Buffer to be validated
264
 *
265
 * RETURN:      Status
266
 *
267
 * DESCRIPTION: Validate that the buffer is of the required length or
268
 *              allocate a new buffer.
269
 *
270
 ******************************************************************************/
271
 
272
acpi_status
273
acpi_ut_initialize_buffer (
274
        struct acpi_buffer              *buffer,
275
        acpi_size                       required_length)
276
{
277
        acpi_status                     status = AE_OK;
278
 
279
 
280
        switch (buffer->length) {
281
        case ACPI_NO_BUFFER:
282
 
283
                /* Set the exception and returned the required length */
284
 
285
                status = AE_BUFFER_OVERFLOW;
286
                break;
287
 
288
 
289
        case ACPI_ALLOCATE_BUFFER:
290
 
291
                /* Allocate a new buffer */
292
 
293
                buffer->pointer = acpi_os_allocate (required_length);
294
                if (!buffer->pointer) {
295
                        return (AE_NO_MEMORY);
296
                }
297
 
298
                /* Clear the buffer */
299
 
300
                ACPI_MEMSET (buffer->pointer, 0, required_length);
301
                break;
302
 
303
 
304
        case ACPI_ALLOCATE_LOCAL_BUFFER:
305
 
306
                /* Allocate a new buffer with local interface to allow tracking */
307
 
308
                buffer->pointer = ACPI_MEM_ALLOCATE (required_length);
309
                if (!buffer->pointer) {
310
                        return (AE_NO_MEMORY);
311
                }
312
 
313
                /* Clear the buffer */
314
 
315
                ACPI_MEMSET (buffer->pointer, 0, required_length);
316
                break;
317
 
318
 
319
        default:
320
 
321
                /* Validate the size of the buffer */
322
 
323
                if (buffer->length < required_length) {
324
                        status = AE_BUFFER_OVERFLOW;
325
                }
326
                break;
327
        }
328
 
329
        buffer->length = required_length;
330
        return (status);
331
}
332
 
333
 
334
/*******************************************************************************
335
 *
336
 * FUNCTION:    acpi_ut_allocate
337
 *
338
 * PARAMETERS:  Size                - Size of the allocation
339
 *              Component           - Component type of caller
340
 *              Module              - Source file name of caller
341
 *              Line                - Line number of caller
342
 *
343
 * RETURN:      Address of the allocated memory on success, NULL on failure.
344
 *
345
 * DESCRIPTION: The subsystem's equivalent of malloc.
346
 *
347
 ******************************************************************************/
348
 
349
void *
350
acpi_ut_allocate (
351
        acpi_size                       size,
352
        u32                             component,
353
        char                            *module,
354
        u32                             line)
355
{
356
        void                            *allocation;
357
 
358
 
359
        ACPI_FUNCTION_TRACE_U32 ("ut_allocate", size);
360
 
361
 
362
        /* Check for an inadvertent size of zero bytes */
363
 
364
        if (!size) {
365
                _ACPI_REPORT_ERROR (module, line, component,
366
                                ("ut_allocate: Attempt to allocate zero bytes\n"));
367
                size = 1;
368
        }
369
 
370
        allocation = acpi_os_allocate (size);
371
        if (!allocation) {
372
                /* Report allocation error */
373
 
374
                _ACPI_REPORT_ERROR (module, line, component,
375
                                ("ut_allocate: Could not allocate size %X\n", (u32) size));
376
 
377
                return_PTR (NULL);
378
        }
379
 
380
        return_PTR (allocation);
381
}
382
 
383
 
384
/*******************************************************************************
385
 *
386
 * FUNCTION:    acpi_ut_callocate
387
 *
388
 * PARAMETERS:  Size                - Size of the allocation
389
 *              Component           - Component type of caller
390
 *              Module              - Source file name of caller
391
 *              Line                - Line number of caller
392
 *
393
 * RETURN:      Address of the allocated memory on success, NULL on failure.
394
 *
395
 * DESCRIPTION: Subsystem equivalent of calloc.
396
 *
397
 ******************************************************************************/
398
 
399
void *
400
acpi_ut_callocate (
401
        acpi_size                       size,
402
        u32                             component,
403
        char                            *module,
404
        u32                             line)
405
{
406
        void                            *allocation;
407
 
408
 
409
        ACPI_FUNCTION_TRACE_U32 ("ut_callocate", size);
410
 
411
 
412
        /* Check for an inadvertent size of zero bytes */
413
 
414
        if (!size) {
415
                _ACPI_REPORT_ERROR (module, line, component,
416
                                ("ut_callocate: Attempt to allocate zero bytes\n"));
417
                return_PTR (NULL);
418
        }
419
 
420
        allocation = acpi_os_allocate (size);
421
        if (!allocation) {
422
                /* Report allocation error */
423
 
424
                _ACPI_REPORT_ERROR (module, line, component,
425
                                ("ut_callocate: Could not allocate size %X\n", (u32) size));
426
                return_PTR (NULL);
427
        }
428
 
429
        /* Clear the memory block */
430
 
431
        ACPI_MEMSET (allocation, 0, size);
432
        return_PTR (allocation);
433
}
434
 
435
 
436
#ifdef ACPI_DBG_TRACK_ALLOCATIONS
437
/*
438
 * These procedures are used for tracking memory leaks in the subsystem, and
439
 * they get compiled out when the ACPI_DBG_TRACK_ALLOCATIONS is not set.
440
 *
441
 * Each memory allocation is tracked via a doubly linked list.  Each
442
 * element contains the caller's component, module name, function name, and
443
 * line number.  acpi_ut_allocate and acpi_ut_callocate call
444
 * acpi_ut_track_allocation to add an element to the list; deletion
445
 * occurs in the body of acpi_ut_free.
446
 */
447
 
448
 
449
/*******************************************************************************
450
 *
451
 * FUNCTION:    acpi_ut_allocate_and_track
452
 *
453
 * PARAMETERS:  Size                - Size of the allocation
454
 *              Component           - Component type of caller
455
 *              Module              - Source file name of caller
456
 *              Line                - Line number of caller
457
 *
458
 * RETURN:      Address of the allocated memory on success, NULL on failure.
459
 *
460
 * DESCRIPTION: The subsystem's equivalent of malloc.
461
 *
462
 ******************************************************************************/
463
 
464
void *
465
acpi_ut_allocate_and_track (
466
        acpi_size                       size,
467
        u32                             component,
468
        char                            *module,
469
        u32                             line)
470
{
471
        struct acpi_debug_mem_block     *allocation;
472
        acpi_status                     status;
473
 
474
 
475
        allocation = acpi_ut_allocate (size + sizeof (struct acpi_debug_mem_block), component,
476
                          module, line);
477
        if (!allocation) {
478
                return (NULL);
479
        }
480
 
481
        status = acpi_ut_track_allocation (ACPI_MEM_LIST_GLOBAL, allocation, size,
482
                          ACPI_MEM_MALLOC, component, module, line);
483
        if (ACPI_FAILURE (status)) {
484
                acpi_os_free (allocation);
485
                return (NULL);
486
        }
487
 
488
        acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].total_allocated++;
489
        acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].current_total_size += (u32) size;
490
 
491
        return ((void *) &allocation->user_space);
492
}
493
 
494
 
495
/*******************************************************************************
496
 *
497
 * FUNCTION:    acpi_ut_callocate_and_track
498
 *
499
 * PARAMETERS:  Size                - Size of the allocation
500
 *              Component           - Component type of caller
501
 *              Module              - Source file name of caller
502
 *              Line                - Line number of caller
503
 *
504
 * RETURN:      Address of the allocated memory on success, NULL on failure.
505
 *
506
 * DESCRIPTION: Subsystem equivalent of calloc.
507
 *
508
 ******************************************************************************/
509
 
510
void *
511
acpi_ut_callocate_and_track (
512
        acpi_size                       size,
513
        u32                             component,
514
        char                            *module,
515
        u32                             line)
516
{
517
        struct acpi_debug_mem_block     *allocation;
518
        acpi_status                     status;
519
 
520
 
521
        allocation = acpi_ut_callocate (size + sizeof (struct acpi_debug_mem_block), component,
522
                          module, line);
523
        if (!allocation) {
524
                /* Report allocation error */
525
 
526
                _ACPI_REPORT_ERROR (module, line, component,
527
                                ("ut_callocate: Could not allocate size %X\n", (u32) size));
528
                return (NULL);
529
        }
530
 
531
        status = acpi_ut_track_allocation (ACPI_MEM_LIST_GLOBAL, allocation, size,
532
                           ACPI_MEM_CALLOC, component, module, line);
533
        if (ACPI_FAILURE (status)) {
534
                acpi_os_free (allocation);
535
                return (NULL);
536
        }
537
 
538
        acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].total_allocated++;
539
        acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].current_total_size += (u32) size;
540
 
541
        return ((void *) &allocation->user_space);
542
}
543
 
544
 
545
/*******************************************************************************
546
 *
547
 * FUNCTION:    acpi_ut_free_and_track
548
 *
549
 * PARAMETERS:  Allocation          - Address of the memory to deallocate
550
 *              Component           - Component type of caller
551
 *              Module              - Source file name of caller
552
 *              Line                - Line number of caller
553
 *
554
 * RETURN:      None
555
 *
556
 * DESCRIPTION: Frees the memory at Allocation
557
 *
558
 ******************************************************************************/
559
 
560
void
561
acpi_ut_free_and_track (
562
        void                            *allocation,
563
        u32                             component,
564
        char                            *module,
565
        u32                             line)
566
{
567
        struct acpi_debug_mem_block     *debug_block;
568
        acpi_status                     status;
569
 
570
 
571
        ACPI_FUNCTION_TRACE_PTR ("ut_free", allocation);
572
 
573
 
574
        if (NULL == allocation) {
575
                _ACPI_REPORT_ERROR (module, line, component,
576
                        ("acpi_ut_free: Attempt to delete a NULL address\n"));
577
 
578
                return_VOID;
579
        }
580
 
581
        debug_block = ACPI_CAST_PTR (struct acpi_debug_mem_block,
582
                          (((char *) allocation) - sizeof (struct acpi_debug_mem_header)));
583
 
584
        acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].total_freed++;
585
        acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].current_total_size -= debug_block->size;
586
 
587
        status = acpi_ut_remove_allocation (ACPI_MEM_LIST_GLOBAL, debug_block,
588
                          component, module, line);
589
        if (ACPI_FAILURE (status)) {
590
                ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not free memory, %s\n",
591
                        acpi_format_exception (status)));
592
        }
593
 
594
        acpi_os_free (debug_block);
595
 
596
        ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p freed\n", allocation));
597
 
598
        return_VOID;
599
}
600
 
601
 
602
/*******************************************************************************
603
 *
604
 * FUNCTION:    acpi_ut_find_allocation
605
 *
606
 * PARAMETERS:  Allocation             - Address of allocated memory
607
 *
608
 * RETURN:      A list element if found; NULL otherwise.
609
 *
610
 * DESCRIPTION: Searches for an element in the global allocation tracking list.
611
 *
612
 ******************************************************************************/
613
 
614
struct acpi_debug_mem_block *
615
acpi_ut_find_allocation (
616
        u32                             list_id,
617
        void                            *allocation)
618
{
619
        struct acpi_debug_mem_block     *element;
620
 
621
 
622
        ACPI_FUNCTION_ENTRY ();
623
 
624
 
625
        if (list_id > ACPI_MEM_LIST_MAX) {
626
                return (NULL);
627
        }
628
 
629
        element = acpi_gbl_memory_lists[list_id].list_head;
630
 
631
        /* Search for the address. */
632
 
633
        while (element) {
634
                if (element == allocation) {
635
                        return (element);
636
                }
637
 
638
                element = element->next;
639
        }
640
 
641
        return (NULL);
642
}
643
 
644
 
645
/*******************************************************************************
646
 *
647
 * FUNCTION:    acpi_ut_track_allocation
648
 *
649
 * PARAMETERS:  Allocation          - Address of allocated memory
650
 *              Size                - Size of the allocation
651
 *              alloc_type          - MEM_MALLOC or MEM_CALLOC
652
 *              Component           - Component type of caller
653
 *              Module              - Source file name of caller
654
 *              Line                - Line number of caller
655
 *
656
 * RETURN:      None.
657
 *
658
 * DESCRIPTION: Inserts an element into the global allocation tracking list.
659
 *
660
 ******************************************************************************/
661
 
662
acpi_status
663
acpi_ut_track_allocation (
664
        u32                             list_id,
665
        struct acpi_debug_mem_block     *allocation,
666
        acpi_size                       size,
667
        u8                              alloc_type,
668
        u32                             component,
669
        char                            *module,
670
        u32                             line)
671
{
672
        struct acpi_memory_list         *mem_list;
673
        struct acpi_debug_mem_block     *element;
674
        acpi_status                     status = AE_OK;
675
 
676
 
677
        ACPI_FUNCTION_TRACE_PTR ("ut_track_allocation", allocation);
678
 
679
 
680
        if (list_id > ACPI_MEM_LIST_MAX) {
681
                return_ACPI_STATUS (AE_BAD_PARAMETER);
682
        }
683
 
684
        mem_list = &acpi_gbl_memory_lists[list_id];
685
        status = acpi_ut_acquire_mutex (ACPI_MTX_MEMORY);
686
        if (ACPI_FAILURE (status)) {
687
                return_ACPI_STATUS (status);
688
        }
689
 
690
        /*
691
         * Search list for this address to make sure it is not already on the list.
692
         * This will catch several kinds of problems.
693
         */
694
 
695
        element = acpi_ut_find_allocation (list_id, allocation);
696
        if (element) {
697
                ACPI_REPORT_ERROR (("ut_track_allocation: Allocation already present in list! (%p)\n",
698
                        allocation));
699
 
700
                ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Element %p Address %p\n", element, allocation));
701
 
702
                goto unlock_and_exit;
703
        }
704
 
705
        /* Fill in the instance data. */
706
 
707
        allocation->size      = (u32) size;
708
        allocation->alloc_type = alloc_type;
709
        allocation->component = component;
710
        allocation->line      = line;
711
 
712
        ACPI_STRNCPY (allocation->module, module, ACPI_MAX_MODULE_NAME);
713
 
714
        /* Insert at list head */
715
 
716
        if (mem_list->list_head) {
717
                ((struct acpi_debug_mem_block *)(mem_list->list_head))->previous = allocation;
718
        }
719
 
720
        allocation->next = mem_list->list_head;
721
        allocation->previous = NULL;
722
 
723
        mem_list->list_head = allocation;
724
 
725
 
726
unlock_and_exit:
727
        status = acpi_ut_release_mutex (ACPI_MTX_MEMORY);
728
        return_ACPI_STATUS (status);
729
}
730
 
731
 
732
/*******************************************************************************
733
 *
734
 * FUNCTION:    acpi_ut_remove_allocation
735
 *
736
 * PARAMETERS:  Allocation          - Address of allocated memory
737
 *              Component           - Component type of caller
738
 *              Module              - Source file name of caller
739
 *              Line                - Line number of caller
740
 *
741
 * RETURN:
742
 *
743
 * DESCRIPTION: Deletes an element from the global allocation tracking list.
744
 *
745
 ******************************************************************************/
746
 
747
acpi_status
748
acpi_ut_remove_allocation (
749
        u32                             list_id,
750
        struct acpi_debug_mem_block     *allocation,
751
        u32                             component,
752
        char                            *module,
753
        u32                             line)
754
{
755
        struct acpi_memory_list         *mem_list;
756
        acpi_status                     status;
757
 
758
 
759
        ACPI_FUNCTION_TRACE ("ut_remove_allocation");
760
 
761
 
762
        if (list_id > ACPI_MEM_LIST_MAX) {
763
                return_ACPI_STATUS (AE_BAD_PARAMETER);
764
        }
765
 
766
        mem_list = &acpi_gbl_memory_lists[list_id];
767
        if (NULL == mem_list->list_head) {
768
                /* No allocations! */
769
 
770
                _ACPI_REPORT_ERROR (module, line, component,
771
                                ("ut_remove_allocation: Empty allocation list, nothing to free!\n"));
772
 
773
                return_ACPI_STATUS (AE_OK);
774
        }
775
 
776
        status = acpi_ut_acquire_mutex (ACPI_MTX_MEMORY);
777
        if (ACPI_FAILURE (status)) {
778
                return_ACPI_STATUS (status);
779
        }
780
 
781
        /* Unlink */
782
 
783
        if (allocation->previous) {
784
                (allocation->previous)->next = allocation->next;
785
        }
786
        else {
787
                mem_list->list_head = allocation->next;
788
        }
789
 
790
        if (allocation->next) {
791
                (allocation->next)->previous = allocation->previous;
792
        }
793
 
794
        /* Mark the segment as deleted */
795
 
796
        ACPI_MEMSET (&allocation->user_space, 0xEA, allocation->size);
797
 
798
        ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Freeing size 0%X\n", allocation->size));
799
 
800
        status = acpi_ut_release_mutex (ACPI_MTX_MEMORY);
801
        return_ACPI_STATUS (status);
802
}
803
 
804
 
805
/*******************************************************************************
806
 *
807
 * FUNCTION:    acpi_ut_dump_allocation_info
808
 *
809
 * PARAMETERS:
810
 *
811
 * RETURN:      None
812
 *
813
 * DESCRIPTION: Print some info about the outstanding allocations.
814
 *
815
 ******************************************************************************/
816
 
817
void
818
acpi_ut_dump_allocation_info (
819
        void)
820
{
821
/*
822
        struct acpi_memory_list         *mem_list;
823
*/
824
 
825
        ACPI_FUNCTION_TRACE ("ut_dump_allocation_info");
826
 
827
/*
828
        ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
829
                          ("%30s: %4d (%3d Kb)\n", "Current allocations",
830
                          mem_list->current_count,
831
                          ROUND_UP_TO_1K (mem_list->current_size)));
832
 
833
        ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
834
                          ("%30s: %4d (%3d Kb)\n", "Max concurrent allocations",
835
                          mem_list->max_concurrent_count,
836
                          ROUND_UP_TO_1K (mem_list->max_concurrent_size)));
837
 
838
 
839
        ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
840
                          ("%30s: %4d (%3d Kb)\n", "Total (all) internal objects",
841
                          running_object_count,
842
                          ROUND_UP_TO_1K (running_object_size)));
843
 
844
        ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
845
                          ("%30s: %4d (%3d Kb)\n", "Total (all) allocations",
846
                          running_alloc_count,
847
                          ROUND_UP_TO_1K (running_alloc_size)));
848
 
849
 
850
        ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
851
                          ("%30s: %4d (%3d Kb)\n", "Current Nodes",
852
                          acpi_gbl_current_node_count,
853
                          ROUND_UP_TO_1K (acpi_gbl_current_node_size)));
854
 
855
        ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
856
                          ("%30s: %4d (%3d Kb)\n", "Max Nodes",
857
                          acpi_gbl_max_concurrent_node_count,
858
                          ROUND_UP_TO_1K ((acpi_gbl_max_concurrent_node_count * sizeof (struct acpi_namespace_node)))));
859
*/
860
        return_VOID;
861
}
862
 
863
 
864
/*******************************************************************************
865
 *
866
 * FUNCTION:    acpi_ut_dump_allocations
867
 *
868
 * PARAMETERS:  Component           - Component(s) to dump info for.
869
 *              Module              - Module to dump info for.  NULL means all.
870
 *
871
 * RETURN:      None
872
 *
873
 * DESCRIPTION: Print a list of all outstanding allocations.
874
 *
875
 ******************************************************************************/
876
 
877
void
878
acpi_ut_dump_allocations (
879
        u32                             component,
880
        char                            *module)
881
{
882
        struct acpi_debug_mem_block     *element;
883
        union acpi_descriptor           *descriptor;
884
        u32                             num_outstanding = 0;
885
 
886
 
887
        ACPI_FUNCTION_TRACE ("ut_dump_allocations");
888
 
889
 
890
        /*
891
         * Walk the allocation list.
892
         */
893
        if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_MEMORY))) {
894
                return;
895
        }
896
 
897
        element = acpi_gbl_memory_lists[0].list_head;
898
        while (element) {
899
                if ((element->component & component) &&
900
                        ((module == NULL) || (0 == ACPI_STRCMP (module, element->module)))) {
901
                        /* Ignore allocated objects that are in a cache */
902
 
903
                        descriptor = ACPI_CAST_PTR (union acpi_descriptor, &element->user_space);
904
                        if (descriptor->descriptor_id != ACPI_DESC_TYPE_CACHED) {
905
                                acpi_os_printf ("%p Len %04X %9.9s-%d [%s] ",
906
                                                 descriptor, element->size, element->module,
907
                                                 element->line, acpi_ut_get_descriptor_name (descriptor));
908
 
909
                                /* Most of the elements will be Operand objects. */
910
 
911
                                switch (ACPI_GET_DESCRIPTOR_TYPE (descriptor)) {
912
                                case ACPI_DESC_TYPE_OPERAND:
913
                                        acpi_os_printf ("%12.12s R%hd",
914
                                                        acpi_ut_get_type_name (descriptor->object.common.type),
915
                                                        descriptor->object.common.reference_count);
916
                                        break;
917
 
918
                                case ACPI_DESC_TYPE_PARSER:
919
                                        acpi_os_printf ("aml_opcode %04hX",
920
                                                        descriptor->op.asl.aml_opcode);
921
                                        break;
922
 
923
                                case ACPI_DESC_TYPE_NAMED:
924
                                        acpi_os_printf ("%4.4s",
925
                                                        acpi_ut_get_node_name (&descriptor->node));
926
                                        break;
927
 
928
                                default:
929
                                        break;
930
                                }
931
 
932
                                acpi_os_printf ( "\n");
933
                                num_outstanding++;
934
                        }
935
                }
936
                element = element->next;
937
        }
938
 
939
        (void) acpi_ut_release_mutex (ACPI_MTX_MEMORY);
940
 
941
        /* Print summary */
942
 
943
        if (!num_outstanding) {
944
                ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
945
                        "No outstanding allocations.\n"));
946
        }
947
        else {
948
                ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
949
                        "%d(%X) Outstanding allocations\n",
950
                        num_outstanding, num_outstanding));
951
        }
952
 
953
        return_VOID;
954
}
955
 
956
 
957
#endif  /* #ifdef ACPI_DBG_TRACK_ALLOCATIONS */
958
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.