OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. | 2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 | 11 |
12 /* This code is in the public domain. | 12 /* This code is in the public domain. |
13 ** Version: 1.1 Author: Walt Karas | 13 ** Version: 1.1 Author: Walt Karas |
14 */ | 14 */ |
15 | 15 |
16 #ifndef HMM_INTRNL_H_ | 16 #ifndef HMM_INTRNL_H_ |
17 #define HMM_INTRNL_H_ | 17 #define HMM_INTRNL_H_ |
18 | 18 |
19 #ifdef __uClinux__ | 19 #ifdef __uClinux__ |
20 # include <lddk.h> | 20 # include <lddk.h> |
21 #endif | 21 #endif |
22 | 22 |
23 #include "heapmm.h" | 23 #include "heapmm.h" |
24 | 24 |
25 #define U(BASE) HMM_UNIQUE(BASE) | 25 #define U(BASE) HMM_UNIQUE(BASE) |
26 | 26 |
27 /* Mask of high bit of variable of size_bau type. */ | 27 /* Mask of high bit of variable of size_bau type. */ |
28 #define HIGH_BIT_BAU_SIZE \ | 28 #define HIGH_BIT_BAU_SIZE \ |
29 ((U(size_bau)) ~ (((U(size_bau)) ~ (U(size_bau)) 0) >> 1)) | 29 ((U(size_bau)) ~ (((U(size_bau)) ~ (U(size_bau)) 0) >> 1)) |
30 | 30 |
31 /* Add a given number of AAUs to pointer. */ | 31 /* Add a given number of AAUs to pointer. */ |
32 #define AAUS_FORWARD(PTR, AAU_OFFSET) \ | 32 #define AAUS_FORWARD(PTR, AAU_OFFSET) \ |
33 (((char *) (PTR)) + ((AAU_OFFSET) * ((U(size_aau)) HMM_ADDR_ALIGN_UNIT))) | 33 (((char *) (PTR)) + ((AAU_OFFSET) * ((U(size_aau)) HMM_ADDR_ALIGN_UNIT))) |
34 | 34 |
35 /* Subtract a given number of AAUs from pointer. */ | 35 /* Subtract a given number of AAUs from pointer. */ |
36 #define AAUS_BACKWARD(PTR, AAU_OFFSET) \ | 36 #define AAUS_BACKWARD(PTR, AAU_OFFSET) \ |
37 (((char *) (PTR)) - ((AAU_OFFSET) * ((U(size_aau)) HMM_ADDR_ALIGN_UNIT))) | 37 (((char *) (PTR)) - ((AAU_OFFSET) * ((U(size_aau)) HMM_ADDR_ALIGN_UNIT))) |
38 | 38 |
39 /* Add a given number of BAUs to a pointer. */ | 39 /* Add a given number of BAUs to a pointer. */ |
40 #define BAUS_FORWARD(PTR, BAU_OFFSET) \ | 40 #define BAUS_FORWARD(PTR, BAU_OFFSET) \ |
41 AAUS_FORWARD((PTR), (BAU_OFFSET) * ((U(size_aau)) HMM_BLOCK_ALIGN_UNIT)) | 41 AAUS_FORWARD((PTR), (BAU_OFFSET) * ((U(size_aau)) HMM_BLOCK_ALIGN_UNIT)) |
42 | 42 |
43 /* Subtract a given number of BAUs to a pointer. */ | 43 /* Subtract a given number of BAUs to a pointer. */ |
44 #define BAUS_BACKWARD(PTR, BAU_OFFSET) \ | 44 #define BAUS_BACKWARD(PTR, BAU_OFFSET) \ |
45 AAUS_BACKWARD((PTR), (BAU_OFFSET) * ((U(size_aau)) HMM_BLOCK_ALIGN_UNIT)) | 45 AAUS_BACKWARD((PTR), (BAU_OFFSET) * ((U(size_aau)) HMM_BLOCK_ALIGN_UNIT)) |
46 | 46 |
47 typedef struct head_struct | 47 typedef struct head_struct { |
48 { | 48 /* Sizes in Block Alignment Units. */ |
49 /* Sizes in Block Alignment Units. */ | 49 HMM_UNIQUE(size_bau) previous_block_size, block_size; |
50 HMM_UNIQUE(size_bau) previous_block_size, block_size; | |
51 } | 50 } |
52 head_record; | 51 head_record; |
53 | 52 |
54 typedef struct ptr_struct | 53 typedef struct ptr_struct { |
55 { | 54 struct ptr_struct *self, *prev, *next; |
56 struct ptr_struct *self, *prev, *next; | |
57 } | 55 } |
58 ptr_record; | 56 ptr_record; |
59 | 57 |
60 /* Divide and round up any fraction to the next whole number. */ | 58 /* Divide and round up any fraction to the next whole number. */ |
61 #define DIV_ROUND_UP(NUMER, DENOM) (((NUMER) + (DENOM) - 1) / (DENOM)) | 59 #define DIV_ROUND_UP(NUMER, DENOM) (((NUMER) + (DENOM) - 1) / (DENOM)) |
62 | 60 |
63 /* Number of AAUs in a block head. */ | 61 /* Number of AAUs in a block head. */ |
64 #define HEAD_AAUS DIV_ROUND_UP(sizeof(head_record), HMM_ADDR_ALIGN_UNIT) | 62 #define HEAD_AAUS DIV_ROUND_UP(sizeof(head_record), HMM_ADDR_ALIGN_UNIT) |
65 | 63 |
66 /* Number of AAUs in a block pointer record. */ | 64 /* Number of AAUs in a block pointer record. */ |
67 #define PTR_RECORD_AAUS DIV_ROUND_UP(sizeof(ptr_record), HMM_ADDR_ALIGN_UNIT) | 65 #define PTR_RECORD_AAUS DIV_ROUND_UP(sizeof(ptr_record), HMM_ADDR_ALIGN_UNIT) |
68 | 66 |
69 /* Number of BAUs in a dummy end record (at end of chunk). */ | 67 /* Number of BAUs in a dummy end record (at end of chunk). */ |
70 #define DUMMY_END_BLOCK_BAUS DIV_ROUND_UP(HEAD_AAUS, HMM_BLOCK_ALIGN_UNIT) | 68 #define DUMMY_END_BLOCK_BAUS DIV_ROUND_UP(HEAD_AAUS, HMM_BLOCK_ALIGN_UNIT) |
71 | 69 |
72 /* Minimum number of BAUs in a block (allowing room for the pointer record. */ | 70 /* Minimum number of BAUs in a block (allowing room for the pointer record. */ |
73 #define MIN_BLOCK_BAUS \ | 71 #define MIN_BLOCK_BAUS \ |
74 DIV_ROUND_UP(HEAD_AAUS + PTR_RECORD_AAUS, HMM_BLOCK_ALIGN_UNIT) | 72 DIV_ROUND_UP(HEAD_AAUS + PTR_RECORD_AAUS, HMM_BLOCK_ALIGN_UNIT) |
75 | 73 |
76 /* Return number of BAUs in block (masking off high bit containing block | 74 /* Return number of BAUs in block (masking off high bit containing block |
77 ** status). */ | 75 ** status). */ |
78 #define BLOCK_BAUS(HEAD_PTR) \ | 76 #define BLOCK_BAUS(HEAD_PTR) \ |
79 (((head_record *) (HEAD_PTR))->block_size & ~HIGH_BIT_BAU_SIZE) | 77 (((head_record *) (HEAD_PTR))->block_size & ~HIGH_BIT_BAU_SIZE) |
80 | 78 |
81 /* Return number of BAUs in previous block (masking off high bit containing | 79 /* Return number of BAUs in previous block (masking off high bit containing |
82 ** block status). */ | 80 ** block status). */ |
83 #define PREV_BLOCK_BAUS(HEAD_PTR) \ | 81 #define PREV_BLOCK_BAUS(HEAD_PTR) \ |
84 (((head_record *) (HEAD_PTR))->previous_block_size & ~HIGH_BIT_BAU_SIZE) | 82 (((head_record *) (HEAD_PTR))->previous_block_size & ~HIGH_BIT_BAU_SIZE) |
85 | 83 |
86 /* Set number of BAUs in previous block, preserving high bit containing | 84 /* Set number of BAUs in previous block, preserving high bit containing |
87 ** block status. */ | 85 ** block status. */ |
88 #define SET_PREV_BLOCK_BAUS(HEAD_PTR, N_BAUS) \ | 86 #define SET_PREV_BLOCK_BAUS(HEAD_PTR, N_BAUS) \ |
89 { register head_record *h_ptr = (head_record *) (HEAD_PTR); \ | 87 { register head_record *h_ptr = (head_record *) (HEAD_PTR); \ |
90 h_ptr->previous_block_size &= HIGH_BIT_BAU_SIZE; \ | 88 h_ptr->previous_block_size &= HIGH_BIT_BAU_SIZE; \ |
91 h_ptr->previous_block_size |= (N_BAUS); } | 89 h_ptr->previous_block_size |= (N_BAUS); } |
92 | 90 |
93 /* Convert pointer to pointer record of block to pointer to block's head | 91 /* Convert pointer to pointer record of block to pointer to block's head |
94 ** record. */ | 92 ** record. */ |
95 #define PTR_REC_TO_HEAD(PTR_REC_PTR) \ | 93 #define PTR_REC_TO_HEAD(PTR_REC_PTR) \ |
96 ((head_record *) AAUS_BACKWARD(PTR_REC_PTR, HEAD_AAUS)) | 94 ((head_record *) AAUS_BACKWARD(PTR_REC_PTR, HEAD_AAUS)) |
97 | 95 |
98 /* Convert pointer to block head to pointer to block's pointer record. */ | 96 /* Convert pointer to block head to pointer to block's pointer record. */ |
99 #define HEAD_TO_PTR_REC(HEAD_PTR) \ | 97 #define HEAD_TO_PTR_REC(HEAD_PTR) \ |
100 ((ptr_record *) AAUS_FORWARD(HEAD_PTR, HEAD_AAUS)) | 98 ((ptr_record *) AAUS_FORWARD(HEAD_PTR, HEAD_AAUS)) |
101 | 99 |
102 /* Returns non-zero if block is allocated. */ | 100 /* Returns non-zero if block is allocated. */ |
103 #define IS_BLOCK_ALLOCATED(HEAD_PTR) \ | 101 #define IS_BLOCK_ALLOCATED(HEAD_PTR) \ |
104 (((((head_record *) (HEAD_PTR))->block_size | \ | 102 (((((head_record *) (HEAD_PTR))->block_size | \ |
105 ((head_record *) (HEAD_PTR))->previous_block_size) & \ | 103 ((head_record *) (HEAD_PTR))->previous_block_size) & \ |
106 HIGH_BIT_BAU_SIZE) == 0) | 104 HIGH_BIT_BAU_SIZE) == 0) |
107 | 105 |
108 #define MARK_BLOCK_ALLOCATED(HEAD_PTR) \ | 106 #define MARK_BLOCK_ALLOCATED(HEAD_PTR) \ |
109 { register head_record *h_ptr = (head_record *) (HEAD_PTR); \ | 107 { register head_record *h_ptr = (head_record *) (HEAD_PTR); \ |
110 h_ptr->block_size &= ~HIGH_BIT_BAU_SIZE; \ | 108 h_ptr->block_size &= ~HIGH_BIT_BAU_SIZE; \ |
111 h_ptr->previous_block_size &= ~HIGH_BIT_BAU_SIZE; } | 109 h_ptr->previous_block_size &= ~HIGH_BIT_BAU_SIZE; } |
112 | 110 |
113 /* Mark a block as free when it is not the first block in a bin (and | 111 /* Mark a block as free when it is not the first block in a bin (and |
114 ** therefore not a node in the AVL tree). */ | 112 ** therefore not a node in the AVL tree). */ |
115 #define MARK_SUCCESSIVE_BLOCK_IN_FREE_BIN(HEAD_PTR) \ | 113 #define MARK_SUCCESSIVE_BLOCK_IN_FREE_BIN(HEAD_PTR) \ |
116 { register head_record *h_ptr = (head_record *) (HEAD_PTR); \ | 114 { register head_record *h_ptr = (head_record *) (HEAD_PTR); \ |
117 h_ptr->block_size |= HIGH_BIT_BAU_SIZE; } | 115 h_ptr->block_size |= HIGH_BIT_BAU_SIZE; } |
118 | 116 |
119 /* Prototypes for internal functions implemented in one file and called in | 117 /* Prototypes for internal functions implemented in one file and called in |
120 ** another. | 118 ** another. |
121 */ | 119 */ |
122 | 120 |
123 void U(into_free_collection)(U(descriptor) *desc, head_record *head_ptr); | 121 void U(into_free_collection)(U(descriptor) *desc, head_record *head_ptr); |
124 | 122 |
125 void U(out_of_free_collection)(U(descriptor) *desc, head_record *head_ptr); | 123 void U(out_of_free_collection)(U(descriptor) *desc, head_record *head_ptr); |
126 | 124 |
127 void *U(alloc_from_bin)( | 125 void *U(alloc_from_bin)( |
128 U(descriptor) *desc, ptr_record *bin_front_ptr, U(size_bau) n_baus); | 126 U(descriptor) *desc, ptr_record *bin_front_ptr, U(size_bau) n_baus); |
129 | 127 |
130 #ifdef HMM_AUDIT_FAIL | 128 #ifdef HMM_AUDIT_FAIL |
131 | 129 |
132 /* Simply contains a reference to the HMM_AUDIT_FAIL macro and a | 130 /* Simply contains a reference to the HMM_AUDIT_FAIL macro and a |
133 ** dummy return. */ | 131 ** dummy return. */ |
134 int U(audit_block_fail_dummy_return)(void); | 132 int U(audit_block_fail_dummy_return)(void); |
135 | 133 |
136 | 134 |
137 /* Auditing a block consists of checking that the size in its head | 135 /* Auditing a block consists of checking that the size in its head |
138 ** matches the previous block size in the head of the next block. */ | 136 ** matches the previous block size in the head of the next block. */ |
139 #define AUDIT_BLOCK_AS_EXPR(HEAD_PTR) \ | 137 #define AUDIT_BLOCK_AS_EXPR(HEAD_PTR) \ |
140 ((BLOCK_BAUS(HEAD_PTR) == \ | 138 ((BLOCK_BAUS(HEAD_PTR) == \ |
141 PREV_BLOCK_BAUS(BAUS_FORWARD(HEAD_PTR, BLOCK_BAUS(HEAD_PTR)))) ? \ | 139 PREV_BLOCK_BAUS(BAUS_FORWARD(HEAD_PTR, BLOCK_BAUS(HEAD_PTR)))) ? \ |
142 0 : U(audit_block_fail_dummy_return)()) | 140 0 : U(audit_block_fail_dummy_return)()) |
143 | 141 |
144 #define AUDIT_BLOCK(HEAD_PTR) \ | 142 #define AUDIT_BLOCK(HEAD_PTR) \ |
145 { void *h_ptr = (HEAD_PTR); AUDIT_BLOCK_AS_EXPR(h_ptr); } | 143 { void *h_ptr = (HEAD_PTR); AUDIT_BLOCK_AS_EXPR(h_ptr); } |
146 | 144 |
147 #endif | 145 #endif |
148 | 146 |
149 /* Interface to AVL tree generic package instantiation. */ | 147 /* Interface to AVL tree generic package instantiation. */ |
150 | 148 |
151 #define AVL_UNIQUE(BASE) U(avl_ ## BASE) | 149 #define AVL_UNIQUE(BASE) U(avl_ ## BASE) |
152 | 150 |
153 #define AVL_HANDLE ptr_record * | 151 #define AVL_HANDLE ptr_record * |
154 | 152 |
155 #define AVL_KEY U(size_bau) | 153 #define AVL_KEY U(size_bau) |
156 | 154 |
157 #define AVL_MAX_DEPTH 64 | 155 #define AVL_MAX_DEPTH 64 |
158 | 156 |
159 #include "cavl_if.h" | 157 #include "cavl_if.h" |
160 | 158 |
161 #endif /* Include once. */ | 159 #endif /* Include once. */ |
OLD | NEW |