Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

inflate: refactor inflate malloc code

Inflate requires some dynamic memory allocation very early in the boot
process and this is provided with a set of four functions:
malloc/free/gzip_mark/gzip_release.

The old inflate code used a mark/release strategy rather than implement
free. This new version instead keeps a count on the number of outstanding
allocations and when it hits zero, it resets the malloc arena.

This allows removing all the mark and release implementations and unifying
all the malloc/free implementations.

The architecture-dependent code must define two addresses:
- free_mem_ptr, the address of the beginning of the area in which
allocations should be made
- free_mem_end_ptr, the address of the end of the area in which
allocations should be made. If set to 0, then no check is made on
the number of allocations, it just grows as much as needed

The architecture-dependent code can also provide an arch_decomp_wdog()
function call. This function will be called several times during the
decompression process, and allow to notify the watchdog that the system is
still running. If an architecture provides such a call, then it must
define ARCH_HAS_DECOMP_WDOG so that the generic inflate code calls
arch_decomp_wdog().

Work initially done by Matt Mackall, updated to a recent version of the
kernel and improved by me.

[akpm@linux-foundation.org: coding-style fixes]
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Cc: Matt Mackall <mpm@selenic.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: Mikael Starvik <mikael.starvik@axis.com>
Cc: Jesper Nilsson <jesper.nilsson@axis.com>
Cc: Haavard Skinnemoen <hskinnemoen@atmel.com>
Cc: David Howells <dhowells@redhat.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Acked-by: Paul Mundt <lethal@linux-sh.org>
Acked-by: Yoshinori Sato <ysato@users.sourceforge.jp>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Thomas Petazzoni and committed by
Linus Torvalds
2d6ffcca ba92a43d

+62 -439
+2 -37
arch/alpha/boot/misc.c
··· 78 78 static int fill_inbuf(void); 79 79 static void flush_window(void); 80 80 static void error(char *m); 81 - static void gzip_mark(void **); 82 - static void gzip_release(void **); 83 81 84 82 static char *input_data; 85 83 static int input_data_size; ··· 86 88 static ulg output_ptr; 87 89 static ulg bytes_out; 88 90 89 - static void *malloc(int size); 90 - static void free(void *where); 91 91 static void error(char *m); 92 92 static void gzip_mark(void **); 93 93 static void gzip_release(void **); 94 94 95 95 extern int end; 96 96 static ulg free_mem_ptr; 97 - static ulg free_mem_ptr_end; 97 + static ulg free_mem_end_ptr; 98 98 99 99 #define HEAP_SIZE 0x3000 100 100 101 101 #include "../../../lib/inflate.c" 102 - 103 - static void *malloc(int size) 104 - { 105 - void *p; 106 - 107 - if (size <0) error("Malloc error"); 108 - if (free_mem_ptr <= 0) error("Memory error"); 109 - 110 - free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */ 111 - 112 - p = (void *)free_mem_ptr; 113 - free_mem_ptr += size; 114 - 115 - if (free_mem_ptr >= free_mem_ptr_end) 116 - error("Out of memory"); 117 - return p; 118 - } 119 - 120 - static void free(void *where) 121 - { /* gzip_mark & gzip_release do the free */ 122 - } 123 - 124 - static void gzip_mark(void **ptr) 125 - { 126 - *ptr = (void *) free_mem_ptr; 127 - } 128 - 129 - static void gzip_release(void **ptr) 130 - { 131 - free_mem_ptr = (long) *ptr; 132 - } 133 102 134 103 /* =========================================================================== 135 104 * Fill the input buffer. This is called only when the buffer is empty ··· 158 193 159 194 /* FIXME FIXME FIXME */ 160 195 free_mem_ptr = (ulg)output_start + ksize; 161 - free_mem_ptr_end = (ulg)output_start + ksize + 0x200000; 196 + free_mem_end_ptr = (ulg)output_start + ksize + 0x200000; 162 197 /* FIXME FIXME FIXME */ 163 198 164 199 /* put in temp area to reduce initial footprint */
+7 -52
arch/arm/boot/compressed/misc.c
··· 217 217 static int fill_inbuf(void); 218 218 static void flush_window(void); 219 219 static void error(char *m); 220 - static void gzip_mark(void **); 221 - static void gzip_release(void **); 222 220 223 221 extern char input_data[]; 224 222 extern char input_data_end[]; ··· 225 227 static ulg output_ptr; 226 228 static ulg bytes_out; 227 229 228 - static void *malloc(int size); 229 - static void free(void *where); 230 230 static void error(char *m); 231 - static void gzip_mark(void **); 232 - static void gzip_release(void **); 233 231 234 232 static void putstr(const char *); 235 233 236 234 extern int end; 237 235 static ulg free_mem_ptr; 238 - static ulg free_mem_ptr_end; 236 + static ulg free_mem_end_ptr; 239 237 240 - #define HEAP_SIZE 0x3000 238 + #ifdef STANDALONE_DEBUG 239 + #define NO_INFLATE_MALLOC 240 + #endif 241 + 242 + #define ARCH_HAS_DECOMP_WDOG 241 243 242 244 #include "../../../../lib/inflate.c" 243 - 244 - #ifndef STANDALONE_DEBUG 245 - static void *malloc(int size) 246 - { 247 - void *p; 248 - 249 - if (size <0) error("Malloc error"); 250 - if (free_mem_ptr <= 0) error("Memory error"); 251 - 252 - free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */ 253 - 254 - p = (void *)free_mem_ptr; 255 - free_mem_ptr += size; 256 - 257 - if (free_mem_ptr >= free_mem_ptr_end) 258 - error("Out of memory"); 259 - return p; 260 - } 261 - 262 - static void free(void *where) 263 - { /* gzip_mark & gzip_release do the free */ 264 - } 265 - 266 - static void gzip_mark(void **ptr) 267 - { 268 - arch_decomp_wdog(); 269 - *ptr = (void *) free_mem_ptr; 270 - } 271 - 272 - static void gzip_release(void **ptr) 273 - { 274 - arch_decomp_wdog(); 275 - free_mem_ptr = (long) *ptr; 276 - } 277 - #else 278 - static void gzip_mark(void **ptr) 279 - { 280 - } 281 - 282 - static void gzip_release(void **ptr) 283 - { 284 - } 285 - #endif 286 245 287 246 /* =========================================================================== 288 247 * Fill the input buffer. This is called only when the buffer is empty ··· 303 348 { 304 349 output_data = (uch *)output_start; /* Points to kernel start */ 305 350 free_mem_ptr = free_mem_ptr_p; 306 - free_mem_ptr_end = free_mem_ptr_end_p; 351 + free_mem_end_ptr = free_mem_ptr_end_p; 307 352 __machine_arch_type = arch_id; 308 353 309 354 arch_decomp_setup();
+1 -35
arch/cris/arch-v10/boot/compressed/misc.c
··· 102 102 static long bytes_out = 0; 103 103 static uch *output_data; 104 104 static unsigned long output_ptr = 0; 105 - 106 - static void *malloc(int size); 107 - static void free(void *where); 108 - static void gzip_mark(void **); 109 - static void gzip_release(void **); 110 - 111 105 static void puts(const char *); 112 106 113 107 /* the "heap" is put directly after the BSS ends, at end */ 114 108 115 109 extern int _end; 116 110 static long free_mem_ptr = (long)&_end; 111 + static long free_mem_end_ptr; 117 112 118 113 #include "../../../../../lib/inflate.c" 119 - 120 - static void *malloc(int size) 121 - { 122 - void *p; 123 - 124 - if (size < 0) 125 - error("Malloc error"); 126 - 127 - free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */ 128 - 129 - p = (void *)free_mem_ptr; 130 - free_mem_ptr += size; 131 - 132 - return p; 133 - } 134 - 135 - static void free(void *where) 136 - { /* Don't care */ 137 - } 138 - 139 - static void gzip_mark(void **ptr) 140 - { 141 - *ptr = (void *) free_mem_ptr; 142 - } 143 - 144 - static void gzip_release(void **ptr) 145 - { 146 - free_mem_ptr = (long) *ptr; 147 - } 148 114 149 115 /* decompressor info and error messages to serial console */ 150 116
+3 -36
arch/cris/arch-v32/boot/compressed/misc.c
··· 89 89 90 90 static void flush_window(void); 91 91 static void error(char *m); 92 - static void gzip_mark(void **); 93 - static void gzip_release(void **); 94 92 95 93 extern char *input_data; /* lives in head.S */ 96 94 97 - static long bytes_out = 0; 95 + static long bytes_out; 98 96 static uch *output_data; 99 - static unsigned long output_ptr = 0; 97 + static unsigned long output_ptr; 100 98 101 - static void *malloc(int size); 102 - static void free(void *where); 103 99 static void error(char *m); 104 - static void gzip_mark(void **); 105 - static void gzip_release(void **); 106 100 107 101 static void puts(const char *); 108 102 ··· 104 110 105 111 extern int _end; 106 112 static long free_mem_ptr = (long)&_end; 113 + static long free_mem_end_ptr; 107 114 108 115 #include "../../../../../lib/inflate.c" 109 - 110 - static void *malloc(int size) 111 - { 112 - void *p; 113 - 114 - if (size <0) error("Malloc error"); 115 - 116 - free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */ 117 - 118 - p = (void *)free_mem_ptr; 119 - free_mem_ptr += size; 120 - 121 - return p; 122 - } 123 - 124 - static void free(void *where) 125 - { /* Don't care */ 126 - } 127 - 128 - static void gzip_mark(void **ptr) 129 - { 130 - *ptr = (void *) free_mem_ptr; 131 - } 132 - 133 - static void gzip_release(void **ptr) 134 - { 135 - free_mem_ptr = (long) *ptr; 136 - } 137 116 138 117 /* decompressor info and error messages to serial console */ 139 118
-38
arch/h8300/boot/compressed/misc.c
··· 67 67 static int fill_inbuf(void); 68 68 static void flush_window(void); 69 69 static void error(char *m); 70 - static void gzip_mark(void **); 71 - static void gzip_release(void **); 72 70 73 71 extern char input_data[]; 74 72 extern int input_len; ··· 75 77 static uch *output_data; 76 78 static unsigned long output_ptr = 0; 77 79 78 - static void *malloc(int size); 79 - static void free(void *where); 80 80 static void error(char *m); 81 - static void gzip_mark(void **); 82 - static void gzip_release(void **); 83 81 84 82 int puts(const char *); 85 83 ··· 91 97 #define SCR *((volatile unsigned char *)0xffff8a) 92 98 #define TDR *((volatile unsigned char *)0xffff8b) 93 99 #define SSR *((volatile unsigned char *)0xffff8c) 94 - 95 - static void *malloc(int size) 96 - { 97 - void *p; 98 - 99 - if (size <0) error("Malloc error"); 100 - if (free_mem_ptr == 0) error("Memory error"); 101 - 102 - free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */ 103 - 104 - p = (void *)free_mem_ptr; 105 - free_mem_ptr += size; 106 - 107 - if (free_mem_ptr >= free_mem_end_ptr) 108 - error("Out of memory"); 109 - 110 - return p; 111 - } 112 - 113 - static void free(void *where) 114 - { /* Don't care */ 115 - } 116 - 117 - static void gzip_mark(void **ptr) 118 - { 119 - *ptr = (void *) free_mem_ptr; 120 - } 121 - 122 - static void gzip_release(void **ptr) 123 - { 124 - free_mem_ptr = (long) *ptr; 125 - } 126 100 127 101 int puts(const char *s) 128 102 {
-37
arch/m32r/boot/compressed/misc.c
··· 70 70 static int fill_inbuf(void); 71 71 static void flush_window(void); 72 72 static void error(char *m); 73 - static void gzip_mark(void **); 74 - static void gzip_release(void **); 75 73 76 74 static unsigned char *input_data; 77 75 static int input_len; ··· 80 82 81 83 #include "m32r_sio.c" 82 84 83 - static void *malloc(int size); 84 - static void free(void *where); 85 - 86 85 static unsigned long free_mem_ptr; 87 86 static unsigned long free_mem_end_ptr; 88 87 89 88 #define HEAP_SIZE 0x10000 90 89 91 90 #include "../../../../lib/inflate.c" 92 - 93 - static void *malloc(int size) 94 - { 95 - void *p; 96 - 97 - if (size <0) error("Malloc error"); 98 - if (free_mem_ptr == 0) error("Memory error"); 99 - 100 - free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */ 101 - 102 - p = (void *)free_mem_ptr; 103 - free_mem_ptr += size; 104 - 105 - if (free_mem_ptr >= free_mem_end_ptr) 106 - error("Out of memory"); 107 - 108 - return p; 109 - } 110 - 111 - static void free(void *where) 112 - { /* Don't care */ 113 - } 114 - 115 - static void gzip_mark(void **ptr) 116 - { 117 - *ptr = (void *) free_mem_ptr; 118 - } 119 - 120 - static void gzip_release(void **ptr) 121 - { 122 - free_mem_ptr = (long) *ptr; 123 - } 124 91 125 92 void* memset(void* s, int c, size_t n) 126 93 {
-37
arch/mn10300/boot/compressed/misc.c
··· 153 153 static unsigned long output_ptr; 154 154 155 155 156 - static void *malloc(int size); 157 - 158 - static inline void free(void *where) 159 - { /* Don't care */ 160 - } 161 - 162 156 static unsigned long free_mem_ptr = (unsigned long) &end; 163 157 static unsigned long free_mem_end_ptr = (unsigned long) &end + 0x90000; 164 - 165 - static inline void gzip_mark(void **ptr) 166 - { 167 - kputs("."); 168 - *ptr = (void *) free_mem_ptr; 169 - } 170 - 171 - static inline void gzip_release(void **ptr) 172 - { 173 - free_mem_ptr = (unsigned long) *ptr; 174 - } 175 158 176 159 #define INPLACE_MOVE_ROUTINE 0x1000 177 160 #define LOW_BUFFER_START 0x2000 ··· 168 185 static int lines, cols; 169 186 170 187 #include "../../../../lib/inflate.c" 171 - 172 - static void *malloc(int size) 173 - { 174 - void *p; 175 - 176 - if (size < 0) 177 - error("Malloc error\n"); 178 - if (!free_mem_ptr) 179 - error("Memory error\n"); 180 - 181 - free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */ 182 - 183 - p = (void *) free_mem_ptr; 184 - free_mem_ptr += size; 185 - 186 - if (free_mem_ptr >= free_mem_end_ptr) 187 - error("\nOut of memory\n"); 188 - 189 - return p; 190 - } 191 188 192 189 static inline void scroll(void) 193 190 {
-38
arch/sh/boot/compressed/misc_32.c
··· 74 74 static int fill_inbuf(void); 75 75 static void flush_window(void); 76 76 static void error(char *m); 77 - static void gzip_mark(void **); 78 - static void gzip_release(void **); 79 77 80 78 extern char input_data[]; 81 79 extern int input_len; ··· 82 84 static uch *output_data; 83 85 static unsigned long output_ptr = 0; 84 86 85 - static void *malloc(int size); 86 - static void free(void *where); 87 87 static void error(char *m); 88 - static void gzip_mark(void **); 89 - static void gzip_release(void **); 90 88 91 89 int puts(const char *); 92 90 ··· 94 100 #define HEAP_SIZE 0x10000 95 101 96 102 #include "../../../../lib/inflate.c" 97 - 98 - static void *malloc(int size) 99 - { 100 - void *p; 101 - 102 - if (size <0) error("Malloc error"); 103 - if (free_mem_ptr == 0) error("Memory error"); 104 - 105 - free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */ 106 - 107 - p = (void *)free_mem_ptr; 108 - free_mem_ptr += size; 109 - 110 - if (free_mem_ptr >= free_mem_end_ptr) 111 - error("Out of memory"); 112 - 113 - return p; 114 - } 115 - 116 - static void free(void *where) 117 - { /* Don't care */ 118 - } 119 - 120 - static void gzip_mark(void **ptr) 121 - { 122 - *ptr = (void *) free_mem_ptr; 123 - } 124 - 125 - static void gzip_release(void **ptr) 126 - { 127 - free_mem_ptr = (long) *ptr; 128 - } 129 103 130 104 #ifdef CONFIG_SH_STANDARD_BIOS 131 105 size_t strlen(const char *s)
-40
arch/sh/boot/compressed/misc_64.c
··· 72 72 static int fill_inbuf(void); 73 73 static void flush_window(void); 74 74 static void error(char *m); 75 - static void gzip_mark(void **); 76 - static void gzip_release(void **); 77 75 78 76 extern char input_data[]; 79 77 extern int input_len; ··· 80 82 static uch *output_data; 81 83 static unsigned long output_ptr = 0; 82 84 83 - static void *malloc(int size); 84 - static void free(void *where); 85 85 static void error(char *m); 86 - static void gzip_mark(void **); 87 - static void gzip_release(void **); 88 86 89 87 static void puts(const char *); 90 88 ··· 92 98 #define HEAP_SIZE 0x10000 93 99 94 100 #include "../../../../lib/inflate.c" 95 - 96 - static void *malloc(int size) 97 - { 98 - void *p; 99 - 100 - if (size < 0) 101 - error("Malloc error\n"); 102 - if (free_mem_ptr == 0) 103 - error("Memory error\n"); 104 - 105 - free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */ 106 - 107 - p = (void *) free_mem_ptr; 108 - free_mem_ptr += size; 109 - 110 - if (free_mem_ptr >= free_mem_end_ptr) 111 - error("\nOut of memory\n"); 112 - 113 - return p; 114 - } 115 - 116 - static void free(void *where) 117 - { /* Don't care */ 118 - } 119 - 120 - static void gzip_mark(void **ptr) 121 - { 122 - *ptr = (void *) free_mem_ptr; 123 - } 124 - 125 - static void gzip_release(void **ptr) 126 - { 127 - free_mem_ptr = (long) *ptr; 128 - } 129 101 130 102 void puts(const char *s) 131 103 {
-39
arch/x86/boot/compressed/misc.c
··· 182 182 static int fill_inbuf(void); 183 183 static void flush_window(void); 184 184 static void error(char *m); 185 - static void gzip_mark(void **); 186 - static void gzip_release(void **); 187 185 188 186 /* 189 187 * This is set up by the setup-routine at boot-time ··· 193 195 extern int input_len; 194 196 195 197 static long bytes_out; 196 - 197 - static void *malloc(int size); 198 - static void free(void *where); 199 198 200 199 static void *memset(void *s, int c, unsigned n); 201 200 static void *memcpy(void *dest, const void *src, unsigned n); ··· 214 219 static int lines, cols; 215 220 216 221 #include "../../../../lib/inflate.c" 217 - 218 - static void *malloc(int size) 219 - { 220 - void *p; 221 - 222 - if (size < 0) 223 - error("Malloc error"); 224 - if (free_mem_ptr <= 0) 225 - error("Memory error"); 226 - 227 - free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */ 228 - 229 - p = (void *)free_mem_ptr; 230 - free_mem_ptr += size; 231 - 232 - if (free_mem_ptr >= free_mem_end_ptr) 233 - error("Out of memory"); 234 - 235 - return p; 236 - } 237 - 238 - static void free(void *where) 239 - { /* Don't care */ 240 - } 241 - 242 - static void gzip_mark(void **ptr) 243 - { 244 - *ptr = (void *) free_mem_ptr; 245 - } 246 - 247 - static void gzip_release(void **ptr) 248 - { 249 - free_mem_ptr = (memptr) *ptr; 250 - } 251 222 252 223 static void scroll(void) 253 224 {
+2 -23
init/do_mounts_rd.c
··· 303 303 304 304 static int __init fill_inbuf(void); 305 305 static void __init flush_window(void); 306 - static void __init *malloc(size_t size); 307 - static void __init free(void *where); 308 306 static void __init error(char *m); 309 - static void __init gzip_mark(void **); 310 - static void __init gzip_release(void **); 307 + 308 + #define NO_INFLATE_MALLOC 311 309 312 310 #include "../lib/inflate.c" 313 - 314 - static void __init *malloc(size_t size) 315 - { 316 - return kmalloc(size, GFP_KERNEL); 317 - } 318 - 319 - static void __init free(void *where) 320 - { 321 - kfree(where); 322 - } 323 - 324 - static void __init gzip_mark(void **ptr) 325 - { 326 - } 327 - 328 - static void __init gzip_release(void **ptr) 329 - { 330 - } 331 - 332 311 333 312 /* =========================================================================== 334 313 * Fill the input buffer. This is called only when the buffer is empty
+2 -20
init/initramfs.c
··· 14 14 message = x; 15 15 } 16 16 17 - static void __init *malloc(size_t size) 18 - { 19 - return kmalloc(size, GFP_KERNEL); 20 - } 21 - 22 - static void __init free(void *where) 23 - { 24 - kfree(where); 25 - } 26 - 27 17 /* link hash */ 28 18 29 19 #define N_ALIGN(len) ((((len) + 1) & ~3) + 2) ··· 397 407 398 408 static void __init flush_window(void); 399 409 static void __init error(char *m); 400 - static void __init gzip_mark(void **); 401 - static void __init gzip_release(void **); 410 + 411 + #define NO_INFLATE_MALLOC 402 412 403 413 #include "../lib/inflate.c" 404 - 405 - static void __init gzip_mark(void **ptr) 406 - { 407 - } 408 - 409 - static void __init gzip_release(void **ptr) 410 - { 411 - } 412 414 413 415 /* =========================================================================== 414 416 * Write the output window window[0..outcnt-1] and update crc and bytes_out.
+45 -7
lib/inflate.c
··· 230 230 #define NEEDBITS(n) {while(k<(n)){b|=((ulg)NEXTBYTE())<<k;k+=8;}} 231 231 #define DUMPBITS(n) {b>>=(n);k-=(n);} 232 232 233 + #ifndef NO_INFLATE_MALLOC 234 + /* A trivial malloc implementation, adapted from 235 + * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994 236 + */ 237 + 238 + static unsigned long malloc_ptr; 239 + static int malloc_count; 240 + 241 + static void *malloc(int size) 242 + { 243 + void *p; 244 + 245 + if (size < 0) 246 + error("Malloc error"); 247 + if (!malloc_ptr) 248 + malloc_ptr = free_mem_ptr; 249 + 250 + malloc_ptr = (malloc_ptr + 3) & ~3; /* Align */ 251 + 252 + p = (void *)malloc_ptr; 253 + malloc_ptr += size; 254 + 255 + if (free_mem_end_ptr && malloc_ptr >= free_mem_end_ptr) 256 + error("Out of memory"); 257 + 258 + malloc_count++; 259 + return p; 260 + } 261 + 262 + static void free(void *where) 263 + { 264 + malloc_count--; 265 + if (!malloc_count) 266 + malloc_ptr = free_mem_ptr; 267 + } 268 + #else 269 + #define malloc(a) kmalloc(a, GFP_KERNEL) 270 + #define free(a) kfree(a) 271 + #endif 233 272 234 273 /* 235 274 Huffman code decoding is performed using a multi-level table lookup. ··· 1084 1045 int e; /* last block flag */ 1085 1046 int r; /* result code */ 1086 1047 unsigned h; /* maximum struct huft's malloc'ed */ 1087 - void *ptr; 1088 1048 1089 1049 /* initialize window, bit buffer */ 1090 1050 wp = 0; ··· 1095 1057 h = 0; 1096 1058 do { 1097 1059 hufts = 0; 1098 - gzip_mark(&ptr); 1099 - if ((r = inflate_block(&e)) != 0) { 1100 - gzip_release(&ptr); 1101 - return r; 1102 - } 1103 - gzip_release(&ptr); 1060 + #ifdef ARCH_HAS_DECOMP_WDOG 1061 + arch_decomp_wdog(); 1062 + #endif 1063 + r = inflate_block(&e); 1064 + if (r) 1065 + return r; 1104 1066 if (hufts > h) 1105 1067 h = hufts; 1106 1068 } while (!e);