提交 2d6ffcca 编写于 作者: T Thomas Petazzoni 提交者: Linus Torvalds

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: NThomas 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: NPaul Mundt <lethal@linux-sh.org>
Acked-by: NYoshinori Sato <ysato@users.sourceforge.jp>
Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
上级 ba92a43d
...@@ -78,8 +78,6 @@ static unsigned outcnt; /* bytes in output buffer */ ...@@ -78,8 +78,6 @@ static unsigned outcnt; /* bytes in output buffer */
static int fill_inbuf(void); static int fill_inbuf(void);
static void flush_window(void); static void flush_window(void);
static void error(char *m); static void error(char *m);
static void gzip_mark(void **);
static void gzip_release(void **);
static char *input_data; static char *input_data;
static int input_data_size; static int input_data_size;
...@@ -88,51 +86,18 @@ static uch *output_data; ...@@ -88,51 +86,18 @@ static uch *output_data;
static ulg output_ptr; static ulg output_ptr;
static ulg bytes_out; static ulg bytes_out;
static void *malloc(int size);
static void free(void *where);
static void error(char *m); static void error(char *m);
static void gzip_mark(void **); static void gzip_mark(void **);
static void gzip_release(void **); static void gzip_release(void **);
extern int end; extern int end;
static ulg free_mem_ptr; static ulg free_mem_ptr;
static ulg free_mem_ptr_end; static ulg free_mem_end_ptr;
#define HEAP_SIZE 0x3000 #define HEAP_SIZE 0x3000
#include "../../../lib/inflate.c" #include "../../../lib/inflate.c"
static void *malloc(int size)
{
void *p;
if (size <0) error("Malloc error");
if (free_mem_ptr <= 0) error("Memory error");
free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
p = (void *)free_mem_ptr;
free_mem_ptr += size;
if (free_mem_ptr >= free_mem_ptr_end)
error("Out of memory");
return p;
}
static void free(void *where)
{ /* gzip_mark & gzip_release do the free */
}
static void gzip_mark(void **ptr)
{
*ptr = (void *) free_mem_ptr;
}
static void gzip_release(void **ptr)
{
free_mem_ptr = (long) *ptr;
}
/* =========================================================================== /* ===========================================================================
* Fill the input buffer. This is called only when the buffer is empty * Fill the input buffer. This is called only when the buffer is empty
* and at least one byte is really needed. * and at least one byte is really needed.
...@@ -193,7 +158,7 @@ decompress_kernel(void *output_start, ...@@ -193,7 +158,7 @@ decompress_kernel(void *output_start,
/* FIXME FIXME FIXME */ /* FIXME FIXME FIXME */
free_mem_ptr = (ulg)output_start + ksize; free_mem_ptr = (ulg)output_start + ksize;
free_mem_ptr_end = (ulg)output_start + ksize + 0x200000; free_mem_end_ptr = (ulg)output_start + ksize + 0x200000;
/* FIXME FIXME FIXME */ /* FIXME FIXME FIXME */
/* put in temp area to reduce initial footprint */ /* put in temp area to reduce initial footprint */
......
...@@ -217,8 +217,6 @@ static unsigned outcnt; /* bytes in output buffer */ ...@@ -217,8 +217,6 @@ static unsigned outcnt; /* bytes in output buffer */
static int fill_inbuf(void); static int fill_inbuf(void);
static void flush_window(void); static void flush_window(void);
static void error(char *m); static void error(char *m);
static void gzip_mark(void **);
static void gzip_release(void **);
extern char input_data[]; extern char input_data[];
extern char input_data_end[]; extern char input_data_end[];
...@@ -227,64 +225,21 @@ static uch *output_data; ...@@ -227,64 +225,21 @@ static uch *output_data;
static ulg output_ptr; static ulg output_ptr;
static ulg bytes_out; static ulg bytes_out;
static void *malloc(int size);
static void free(void *where);
static void error(char *m); static void error(char *m);
static void gzip_mark(void **);
static void gzip_release(void **);
static void putstr(const char *); static void putstr(const char *);
extern int end; extern int end;
static ulg free_mem_ptr; static ulg free_mem_ptr;
static ulg free_mem_ptr_end; static ulg free_mem_end_ptr;
#define HEAP_SIZE 0x3000 #ifdef STANDALONE_DEBUG
#define NO_INFLATE_MALLOC
#include "../../../../lib/inflate.c" #endif
#ifndef STANDALONE_DEBUG
static void *malloc(int size)
{
void *p;
if (size <0) error("Malloc error");
if (free_mem_ptr <= 0) error("Memory error");
free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
p = (void *)free_mem_ptr;
free_mem_ptr += size;
if (free_mem_ptr >= free_mem_ptr_end)
error("Out of memory");
return p;
}
static void free(void *where)
{ /* gzip_mark & gzip_release do the free */
}
static void gzip_mark(void **ptr)
{
arch_decomp_wdog();
*ptr = (void *) free_mem_ptr;
}
static void gzip_release(void **ptr) #define ARCH_HAS_DECOMP_WDOG
{
arch_decomp_wdog();
free_mem_ptr = (long) *ptr;
}
#else
static void gzip_mark(void **ptr)
{
}
static void gzip_release(void **ptr) #include "../../../../lib/inflate.c"
{
}
#endif
/* =========================================================================== /* ===========================================================================
* Fill the input buffer. This is called only when the buffer is empty * Fill the input buffer. This is called only when the buffer is empty
...@@ -348,7 +303,7 @@ decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p, ...@@ -348,7 +303,7 @@ decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p,
{ {
output_data = (uch *)output_start; /* Points to kernel start */ output_data = (uch *)output_start; /* Points to kernel start */
free_mem_ptr = free_mem_ptr_p; free_mem_ptr = free_mem_ptr_p;
free_mem_ptr_end = free_mem_ptr_end_p; free_mem_end_ptr = free_mem_ptr_end_p;
__machine_arch_type = arch_id; __machine_arch_type = arch_id;
arch_decomp_setup(); arch_decomp_setup();
......
...@@ -102,50 +102,16 @@ extern char *input_data; /* lives in head.S */ ...@@ -102,50 +102,16 @@ extern char *input_data; /* lives in head.S */
static long bytes_out = 0; static long bytes_out = 0;
static uch *output_data; static uch *output_data;
static unsigned long output_ptr = 0; static unsigned long output_ptr = 0;
static void *malloc(int size);
static void free(void *where);
static void gzip_mark(void **);
static void gzip_release(void **);
static void puts(const char *); static void puts(const char *);
/* the "heap" is put directly after the BSS ends, at end */ /* the "heap" is put directly after the BSS ends, at end */
extern int _end; extern int _end;
static long free_mem_ptr = (long)&_end; static long free_mem_ptr = (long)&_end;
static long free_mem_end_ptr;
#include "../../../../../lib/inflate.c" #include "../../../../../lib/inflate.c"
static void *malloc(int size)
{
void *p;
if (size < 0)
error("Malloc error");
free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
p = (void *)free_mem_ptr;
free_mem_ptr += size;
return p;
}
static void free(void *where)
{ /* Don't care */
}
static void gzip_mark(void **ptr)
{
*ptr = (void *) free_mem_ptr;
}
static void gzip_release(void **ptr)
{
free_mem_ptr = (long) *ptr;
}
/* decompressor info and error messages to serial console */ /* decompressor info and error messages to serial console */
static void static void
......
...@@ -89,20 +89,14 @@ static unsigned outcnt = 0; /* bytes in output buffer */ ...@@ -89,20 +89,14 @@ static unsigned outcnt = 0; /* bytes in output buffer */
static void flush_window(void); static void flush_window(void);
static void error(char *m); static void error(char *m);
static void gzip_mark(void **);
static void gzip_release(void **);
extern char *input_data; /* lives in head.S */ extern char *input_data; /* lives in head.S */
static long bytes_out = 0; static long bytes_out;
static uch *output_data; static uch *output_data;
static unsigned long output_ptr = 0; static unsigned long output_ptr;
static void *malloc(int size);
static void free(void *where);
static void error(char *m); static void error(char *m);
static void gzip_mark(void **);
static void gzip_release(void **);
static void puts(const char *); static void puts(const char *);
...@@ -110,37 +104,10 @@ static void puts(const char *); ...@@ -110,37 +104,10 @@ static void puts(const char *);
extern int _end; extern int _end;
static long free_mem_ptr = (long)&_end; static long free_mem_ptr = (long)&_end;
static long free_mem_end_ptr;
#include "../../../../../lib/inflate.c" #include "../../../../../lib/inflate.c"
static void *malloc(int size)
{
void *p;
if (size <0) error("Malloc error");
free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
p = (void *)free_mem_ptr;
free_mem_ptr += size;
return p;
}
static void free(void *where)
{ /* Don't care */
}
static void gzip_mark(void **ptr)
{
*ptr = (void *) free_mem_ptr;
}
static void gzip_release(void **ptr)
{
free_mem_ptr = (long) *ptr;
}
/* decompressor info and error messages to serial console */ /* decompressor info and error messages to serial console */
static inline void static inline void
......
...@@ -67,8 +67,6 @@ static unsigned outcnt = 0; /* bytes in output buffer */ ...@@ -67,8 +67,6 @@ static unsigned outcnt = 0; /* bytes in output buffer */
static int fill_inbuf(void); static int fill_inbuf(void);
static void flush_window(void); static void flush_window(void);
static void error(char *m); static void error(char *m);
static void gzip_mark(void **);
static void gzip_release(void **);
extern char input_data[]; extern char input_data[];
extern int input_len; extern int input_len;
...@@ -77,11 +75,7 @@ static long bytes_out = 0; ...@@ -77,11 +75,7 @@ static long bytes_out = 0;
static uch *output_data; static uch *output_data;
static unsigned long output_ptr = 0; static unsigned long output_ptr = 0;
static void *malloc(int size);
static void free(void *where);
static void error(char *m); static void error(char *m);
static void gzip_mark(void **);
static void gzip_release(void **);
int puts(const char *); int puts(const char *);
...@@ -98,38 +92,6 @@ static unsigned long free_mem_end_ptr; ...@@ -98,38 +92,6 @@ static unsigned long free_mem_end_ptr;
#define TDR *((volatile unsigned char *)0xffff8b) #define TDR *((volatile unsigned char *)0xffff8b)
#define SSR *((volatile unsigned char *)0xffff8c) #define SSR *((volatile unsigned char *)0xffff8c)
static void *malloc(int size)
{
void *p;
if (size <0) error("Malloc error");
if (free_mem_ptr == 0) error("Memory error");
free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
p = (void *)free_mem_ptr;
free_mem_ptr += size;
if (free_mem_ptr >= free_mem_end_ptr)
error("Out of memory");
return p;
}
static void free(void *where)
{ /* Don't care */
}
static void gzip_mark(void **ptr)
{
*ptr = (void *) free_mem_ptr;
}
static void gzip_release(void **ptr)
{
free_mem_ptr = (long) *ptr;
}
int puts(const char *s) int puts(const char *s)
{ {
return 0; return 0;
......
...@@ -70,8 +70,6 @@ static unsigned outcnt = 0; /* bytes in output buffer */ ...@@ -70,8 +70,6 @@ static unsigned outcnt = 0; /* bytes in output buffer */
static int fill_inbuf(void); static int fill_inbuf(void);
static void flush_window(void); static void flush_window(void);
static void error(char *m); static void error(char *m);
static void gzip_mark(void **);
static void gzip_release(void **);
static unsigned char *input_data; static unsigned char *input_data;
static int input_len; static int input_len;
...@@ -82,9 +80,6 @@ static unsigned long output_ptr = 0; ...@@ -82,9 +80,6 @@ static unsigned long output_ptr = 0;
#include "m32r_sio.c" #include "m32r_sio.c"
static void *malloc(int size);
static void free(void *where);
static unsigned long free_mem_ptr; static unsigned long free_mem_ptr;
static unsigned long free_mem_end_ptr; static unsigned long free_mem_end_ptr;
...@@ -92,38 +87,6 @@ static unsigned long free_mem_end_ptr; ...@@ -92,38 +87,6 @@ static unsigned long free_mem_end_ptr;
#include "../../../../lib/inflate.c" #include "../../../../lib/inflate.c"
static void *malloc(int size)
{
void *p;
if (size <0) error("Malloc error");
if (free_mem_ptr == 0) error("Memory error");
free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
p = (void *)free_mem_ptr;
free_mem_ptr += size;
if (free_mem_ptr >= free_mem_end_ptr)
error("Out of memory");
return p;
}
static void free(void *where)
{ /* Don't care */
}
static void gzip_mark(void **ptr)
{
*ptr = (void *) free_mem_ptr;
}
static void gzip_release(void **ptr)
{
free_mem_ptr = (long) *ptr;
}
void* memset(void* s, int c, size_t n) void* memset(void* s, int c, size_t n)
{ {
int i; int i;
......
...@@ -153,26 +153,9 @@ static uch *output_data; ...@@ -153,26 +153,9 @@ static uch *output_data;
static unsigned long output_ptr; static unsigned long output_ptr;
static void *malloc(int size);
static inline void free(void *where)
{ /* Don't care */
}
static unsigned long free_mem_ptr = (unsigned long) &end; static unsigned long free_mem_ptr = (unsigned long) &end;
static unsigned long free_mem_end_ptr = (unsigned long) &end + 0x90000; static unsigned long free_mem_end_ptr = (unsigned long) &end + 0x90000;
static inline void gzip_mark(void **ptr)
{
kputs(".");
*ptr = (void *) free_mem_ptr;
}
static inline void gzip_release(void **ptr)
{
free_mem_ptr = (unsigned long) *ptr;
}
#define INPLACE_MOVE_ROUTINE 0x1000 #define INPLACE_MOVE_ROUTINE 0x1000
#define LOW_BUFFER_START 0x2000 #define LOW_BUFFER_START 0x2000
#define LOW_BUFFER_END 0x90000 #define LOW_BUFFER_END 0x90000
...@@ -186,26 +169,6 @@ static int lines, cols; ...@@ -186,26 +169,6 @@ static int lines, cols;
#include "../../../../lib/inflate.c" #include "../../../../lib/inflate.c"
static void *malloc(int size)
{
void *p;
if (size < 0)
error("Malloc error\n");
if (!free_mem_ptr)
error("Memory error\n");
free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
p = (void *) free_mem_ptr;
free_mem_ptr += size;
if (free_mem_ptr >= free_mem_end_ptr)
error("\nOut of memory\n");
return p;
}
static inline void scroll(void) static inline void scroll(void)
{ {
int i; int i;
......
...@@ -74,8 +74,6 @@ static unsigned outcnt = 0; /* bytes in output buffer */ ...@@ -74,8 +74,6 @@ static unsigned outcnt = 0; /* bytes in output buffer */
static int fill_inbuf(void); static int fill_inbuf(void);
static void flush_window(void); static void flush_window(void);
static void error(char *m); static void error(char *m);
static void gzip_mark(void **);
static void gzip_release(void **);
extern char input_data[]; extern char input_data[];
extern int input_len; extern int input_len;
...@@ -84,11 +82,7 @@ static long bytes_out = 0; ...@@ -84,11 +82,7 @@ static long bytes_out = 0;
static uch *output_data; static uch *output_data;
static unsigned long output_ptr = 0; static unsigned long output_ptr = 0;
static void *malloc(int size);
static void free(void *where);
static void error(char *m); static void error(char *m);
static void gzip_mark(void **);
static void gzip_release(void **);
int puts(const char *); int puts(const char *);
...@@ -101,38 +95,6 @@ static unsigned long free_mem_end_ptr; ...@@ -101,38 +95,6 @@ static unsigned long free_mem_end_ptr;
#include "../../../../lib/inflate.c" #include "../../../../lib/inflate.c"
static void *malloc(int size)
{
void *p;
if (size <0) error("Malloc error");
if (free_mem_ptr == 0) error("Memory error");
free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
p = (void *)free_mem_ptr;
free_mem_ptr += size;
if (free_mem_ptr >= free_mem_end_ptr)
error("Out of memory");
return p;
}
static void free(void *where)
{ /* Don't care */
}
static void gzip_mark(void **ptr)
{
*ptr = (void *) free_mem_ptr;
}
static void gzip_release(void **ptr)
{
free_mem_ptr = (long) *ptr;
}
#ifdef CONFIG_SH_STANDARD_BIOS #ifdef CONFIG_SH_STANDARD_BIOS
size_t strlen(const char *s) size_t strlen(const char *s)
{ {
......
...@@ -72,8 +72,6 @@ static unsigned outcnt = 0; /* bytes in output buffer */ ...@@ -72,8 +72,6 @@ static unsigned outcnt = 0; /* bytes in output buffer */
static int fill_inbuf(void); static int fill_inbuf(void);
static void flush_window(void); static void flush_window(void);
static void error(char *m); static void error(char *m);
static void gzip_mark(void **);
static void gzip_release(void **);
extern char input_data[]; extern char input_data[];
extern int input_len; extern int input_len;
...@@ -82,11 +80,7 @@ static long bytes_out = 0; ...@@ -82,11 +80,7 @@ static long bytes_out = 0;
static uch *output_data; static uch *output_data;
static unsigned long output_ptr = 0; static unsigned long output_ptr = 0;
static void *malloc(int size);
static void free(void *where);
static void error(char *m); static void error(char *m);
static void gzip_mark(void **);
static void gzip_release(void **);
static void puts(const char *); static void puts(const char *);
...@@ -99,40 +93,6 @@ static unsigned long free_mem_end_ptr; ...@@ -99,40 +93,6 @@ static unsigned long free_mem_end_ptr;
#include "../../../../lib/inflate.c" #include "../../../../lib/inflate.c"
static void *malloc(int size)
{
void *p;
if (size < 0)
error("Malloc error\n");
if (free_mem_ptr == 0)
error("Memory error\n");
free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
p = (void *) free_mem_ptr;
free_mem_ptr += size;
if (free_mem_ptr >= free_mem_end_ptr)
error("\nOut of memory\n");
return p;
}
static void free(void *where)
{ /* Don't care */
}
static void gzip_mark(void **ptr)
{
*ptr = (void *) free_mem_ptr;
}
static void gzip_release(void **ptr)
{
free_mem_ptr = (long) *ptr;
}
void puts(const char *s) void puts(const char *s)
{ {
} }
......
...@@ -182,8 +182,6 @@ static unsigned outcnt; ...@@ -182,8 +182,6 @@ static unsigned outcnt;
static int fill_inbuf(void); static int fill_inbuf(void);
static void flush_window(void); static void flush_window(void);
static void error(char *m); static void error(char *m);
static void gzip_mark(void **);
static void gzip_release(void **);
/* /*
* This is set up by the setup-routine at boot-time * This is set up by the setup-routine at boot-time
...@@ -196,9 +194,6 @@ extern int input_len; ...@@ -196,9 +194,6 @@ extern int input_len;
static long bytes_out; static long bytes_out;
static void *malloc(int size);
static void free(void *where);
static void *memset(void *s, int c, unsigned n); static void *memset(void *s, int c, unsigned n);
static void *memcpy(void *dest, const void *src, unsigned n); static void *memcpy(void *dest, const void *src, unsigned n);
...@@ -220,40 +215,6 @@ static int lines, cols; ...@@ -220,40 +215,6 @@ static int lines, cols;
#include "../../../../lib/inflate.c" #include "../../../../lib/inflate.c"
static void *malloc(int size)
{
void *p;
if (size < 0)
error("Malloc error");
if (free_mem_ptr <= 0)
error("Memory error");
free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
p = (void *)free_mem_ptr;
free_mem_ptr += size;
if (free_mem_ptr >= free_mem_end_ptr)
error("Out of memory");
return p;
}
static void free(void *where)
{ /* Don't care */
}
static void gzip_mark(void **ptr)
{
*ptr = (void *) free_mem_ptr;
}
static void gzip_release(void **ptr)
{
free_mem_ptr = (memptr) *ptr;
}
static void scroll(void) static void scroll(void)
{ {
int i; int i;
......
...@@ -303,32 +303,11 @@ static int crd_infd, crd_outfd; ...@@ -303,32 +303,11 @@ static int crd_infd, crd_outfd;
static int __init fill_inbuf(void); static int __init fill_inbuf(void);
static void __init flush_window(void); static void __init flush_window(void);
static void __init *malloc(size_t size);
static void __init free(void *where);
static void __init error(char *m); static void __init error(char *m);
static void __init gzip_mark(void **);
static void __init gzip_release(void **);
#include "../lib/inflate.c" #define NO_INFLATE_MALLOC
static void __init *malloc(size_t size)
{
return kmalloc(size, GFP_KERNEL);
}
static void __init free(void *where)
{
kfree(where);
}
static void __init gzip_mark(void **ptr)
{
}
static void __init gzip_release(void **ptr)
{
}
#include "../lib/inflate.c"
/* =========================================================================== /* ===========================================================================
* Fill the input buffer. This is called only when the buffer is empty * Fill the input buffer. This is called only when the buffer is empty
......
...@@ -14,16 +14,6 @@ static void __init error(char *x) ...@@ -14,16 +14,6 @@ static void __init error(char *x)
message = x; message = x;
} }
static void __init *malloc(size_t size)
{
return kmalloc(size, GFP_KERNEL);
}
static void __init free(void *where)
{
kfree(where);
}
/* link hash */ /* link hash */
#define N_ALIGN(len) ((((len) + 1) & ~3) + 2) #define N_ALIGN(len) ((((len) + 1) & ~3) + 2)
...@@ -407,18 +397,10 @@ static long bytes_out; ...@@ -407,18 +397,10 @@ static long bytes_out;
static void __init flush_window(void); static void __init flush_window(void);
static void __init error(char *m); static void __init error(char *m);
static void __init gzip_mark(void **);
static void __init gzip_release(void **);
#include "../lib/inflate.c" #define NO_INFLATE_MALLOC
static void __init gzip_mark(void **ptr) #include "../lib/inflate.c"
{
}
static void __init gzip_release(void **ptr)
{
}
/* =========================================================================== /* ===========================================================================
* Write the output window window[0..outcnt-1] and update crc and bytes_out. * Write the output window window[0..outcnt-1] and update crc and bytes_out.
......
...@@ -230,6 +230,45 @@ STATIC const ush mask_bits[] = { ...@@ -230,6 +230,45 @@ STATIC const ush mask_bits[] = {
#define NEEDBITS(n) {while(k<(n)){b|=((ulg)NEXTBYTE())<<k;k+=8;}} #define NEEDBITS(n) {while(k<(n)){b|=((ulg)NEXTBYTE())<<k;k+=8;}}
#define DUMPBITS(n) {b>>=(n);k-=(n);} #define DUMPBITS(n) {b>>=(n);k-=(n);}
#ifndef NO_INFLATE_MALLOC
/* A trivial malloc implementation, adapted from
* malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
*/
static unsigned long malloc_ptr;
static int malloc_count;
static void *malloc(int size)
{
void *p;
if (size < 0)
error("Malloc error");
if (!malloc_ptr)
malloc_ptr = free_mem_ptr;
malloc_ptr = (malloc_ptr + 3) & ~3; /* Align */
p = (void *)malloc_ptr;
malloc_ptr += size;
if (free_mem_end_ptr && malloc_ptr >= free_mem_end_ptr)
error("Out of memory");
malloc_count++;
return p;
}
static void free(void *where)
{
malloc_count--;
if (!malloc_count)
malloc_ptr = free_mem_ptr;
}
#else
#define malloc(a) kmalloc(a, GFP_KERNEL)
#define free(a) kfree(a)
#endif
/* /*
Huffman code decoding is performed using a multi-level table lookup. Huffman code decoding is performed using a multi-level table lookup.
...@@ -1045,7 +1084,6 @@ STATIC int INIT inflate(void) ...@@ -1045,7 +1084,6 @@ STATIC int INIT inflate(void)
int e; /* last block flag */ int e; /* last block flag */
int r; /* result code */ int r; /* result code */
unsigned h; /* maximum struct huft's malloc'ed */ unsigned h; /* maximum struct huft's malloc'ed */
void *ptr;
/* initialize window, bit buffer */ /* initialize window, bit buffer */
wp = 0; wp = 0;
...@@ -1057,12 +1095,12 @@ STATIC int INIT inflate(void) ...@@ -1057,12 +1095,12 @@ STATIC int INIT inflate(void)
h = 0; h = 0;
do { do {
hufts = 0; hufts = 0;
gzip_mark(&ptr); #ifdef ARCH_HAS_DECOMP_WDOG
if ((r = inflate_block(&e)) != 0) { arch_decomp_wdog();
gzip_release(&ptr); #endif
r = inflate_block(&e);
if (r)
return r; return r;
}
gzip_release(&ptr);
if (hufts > h) if (hufts > h)
h = hufts; h = hufts;
} while (!e); } while (!e);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册