aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhillip Lougher <phillip@lougher.demon.co.uk>2010-01-11 16:45:50 +0000
committerroot <root@logopolis.(none)>2010-03-15 01:14:32 +0000
commit5c1d88d3302206703efaa9743d92bbc1fe28e444 (patch)
treee16b57adb2310f9fe11ccec336f84909f1092df3
parent89c0318ad0a2bcc1299c670bb110a73a9dff0f2b (diff)
downloadsquashfs-lzma-5c1d88d3302206703efaa9743d92bbc1fe28e444.tar.gz
lzma: make lzma reentrant
The error function pointer used by lzma is global (file scope) which prevents it being used concurrently. This patch removes the global error pointer use, and instead passes it to all functions that need it. The error function pointer is still used by bunzip2, inflate and unlzo. This patch moves the definition into the separate bunzip2, inflate and unlzo header files. This prevents gcc from complaining about an unused definition compiling lzma. Signed-off-by: Phillip Lougher <phillip@lougher.demon.co.uk>
-rw-r--r--include/linux/decompress/bunzip2_mm.h1
-rw-r--r--include/linux/decompress/inflate_mm.h1
-rw-r--r--include/linux/decompress/mm.h1
-rw-r--r--include/linux/decompress/unlzo_mm.h1
-rw-r--r--lib/decompress_unlzma.c82
5 files changed, 45 insertions, 41 deletions
diff --git a/include/linux/decompress/bunzip2_mm.h b/include/linux/decompress/bunzip2_mm.h
index cac6fef966082b..863efd058f7715 100644
--- a/include/linux/decompress/bunzip2_mm.h
+++ b/include/linux/decompress/bunzip2_mm.h
@@ -7,6 +7,7 @@
#else
/* Compile for initramfs/initrd code only */
#define INIT __init
+static void(*error)(char *m);
#endif
#endif
diff --git a/include/linux/decompress/inflate_mm.h b/include/linux/decompress/inflate_mm.h
index ca4a2aed15d74e..87a742b77a7198 100644
--- a/include/linux/decompress/inflate_mm.h
+++ b/include/linux/decompress/inflate_mm.h
@@ -7,6 +7,7 @@
#else
/* Compile for initramfs/initrd code only */
#define INIT __init
+static void(*error)(char *m);
#endif
#endif
diff --git a/include/linux/decompress/mm.h b/include/linux/decompress/mm.h
index 93dd57436802c4..44f6e145875d8e 100644
--- a/include/linux/decompress/mm.h
+++ b/include/linux/decompress/mm.h
@@ -72,7 +72,6 @@ static void free(void *where)
#define large_malloc(a) vmalloc(a)
#define large_free(a) vfree(a)
-static void(*error)(char *m);
#define set_error_fn(x) error = x;
#define STATIC
diff --git a/include/linux/decompress/unlzo_mm.h b/include/linux/decompress/unlzo_mm.h
index e3f15737c92e6c..27fe0abbc4c673 100644
--- a/include/linux/decompress/unlzo_mm.h
+++ b/include/linux/decompress/unlzo_mm.h
@@ -7,6 +7,7 @@
#else
/* Compile for initramfs/initrd code only */
#define INIT __init
+static void(*error)(char *m);
#endif
#endif
diff --git a/lib/decompress_unlzma.c b/lib/decompress_unlzma.c
index a614b261516ed4..3e85763a00413b 100644
--- a/lib/decompress_unlzma.c
+++ b/lib/decompress_unlzma.c
@@ -89,7 +89,7 @@ static int nofill(void *buffer, unsigned int len)
}
/* Called twice: once at startup and once in rc_normalize() */
-static void INIT rc_read(struct rc *rc)
+static void INIT rc_read(struct rc *rc, void(*error)(char *x))
{
rc->buffer_size = rc->fill((char *)rc->buffer, LZMA_IOBUF_SIZE);
if (rc->buffer_size <= 0)
@@ -116,13 +116,13 @@ static inline void INIT rc_init(struct rc *rc,
rc->range = 0xFFFFFFFF;
}
-static inline void INIT rc_init_code(struct rc *rc)
+static inline void INIT rc_init_code(struct rc *rc, void(*error)(char *x))
{
int i;
for (i = 0; i < 5; i++) {
if (rc->ptr >= rc->buffer_end)
- rc_read(rc);
+ rc_read(rc, error);
rc->code = (rc->code << 8) | *rc->ptr++;
}
}
@@ -135,32 +135,33 @@ static inline void INIT rc_free(struct rc *rc)
}
/* Called twice, but one callsite is in inline'd rc_is_bit_0_helper() */
-static void INIT rc_do_normalize(struct rc *rc)
+static void INIT rc_do_normalize(struct rc *rc, void(*error)(char *x))
{
if (rc->ptr >= rc->buffer_end)
- rc_read(rc);
+ rc_read(rc, error);
rc->range <<= 8;
rc->code = (rc->code << 8) | *rc->ptr++;
}
-static inline void INIT rc_normalize(struct rc *rc)
+static inline void INIT rc_normalize(struct rc *rc, void(*error)(char *x))
{
if (rc->range < (1 << RC_TOP_BITS))
- rc_do_normalize(rc);
+ rc_do_normalize(rc, error);
}
/* Called 9 times */
/* Why rc_is_bit_0_helper exists?
*Because we want to always expose (rc->code < rc->bound) to optimizer
*/
-static inline uint32_t INIT rc_is_bit_0_helper(struct rc *rc, uint16_t *p)
+static inline uint32_t INIT rc_is_bit_0_helper(struct rc *rc, uint16_t *p,
+ void (*error)(char *x))
{
- rc_normalize(rc);
+ rc_normalize(rc, error);
rc->bound = *p * (rc->range >> RC_MODEL_TOTAL_BITS);
return rc->bound;
}
-static inline int INIT rc_is_bit_0(struct rc *rc, uint16_t *p)
+static inline int INIT rc_is_bit_0(struct rc *rc, uint16_t *p, void(*error)(char *x))
{
- uint32_t t = rc_is_bit_0_helper(rc, p);
+ uint32_t t = rc_is_bit_0_helper(rc, p, error);
return rc->code < t;
}
@@ -178,9 +179,9 @@ static inline void rc_update_bit_1(struct rc *rc, uint16_t *p)
}
/* Called 4 times in unlzma loop */
-static int INIT rc_get_bit(struct rc *rc, uint16_t *p, int *symbol)
+static int INIT rc_get_bit(struct rc *rc, uint16_t *p, int *symbol, void(*error)(char *x))
{
- if (rc_is_bit_0(rc, p)) {
+ if (rc_is_bit_0(rc, p, error)) {
rc_update_bit_0(rc, p);
*symbol *= 2;
return 0;
@@ -192,9 +193,9 @@ static int INIT rc_get_bit(struct rc *rc, uint16_t *p, int *symbol)
}
/* Called once */
-static inline int INIT rc_direct_bit(struct rc *rc)
+static inline int INIT rc_direct_bit(struct rc *rc , void(*error)(char *x))
{
- rc_normalize(rc);
+ rc_normalize(rc, error);
rc->range >>= 1;
if (rc->code >= rc->range) {
rc->code -= rc->range;
@@ -205,13 +206,14 @@ static inline int INIT rc_direct_bit(struct rc *rc)
/* Called twice */
static inline void INIT
-rc_bit_tree_decode(struct rc *rc, uint16_t *p, int num_levels, int *symbol)
+rc_bit_tree_decode(struct rc *rc, uint16_t *p, int num_levels, int *symbol,
+ void(*error)(char *x))
{
int i = num_levels;
*symbol = 1;
while (i--)
- rc_get_bit(rc, p + *symbol, symbol);
+ rc_get_bit(rc, p + *symbol, symbol, error);
*symbol -= 1 << num_levels;
}
@@ -348,7 +350,8 @@ static inline void INIT copy_bytes(struct writer *wr,
static inline void INIT process_bit0(struct writer *wr, struct rc *rc,
struct cstate *cst, uint16_t *p,
int pos_state, uint16_t *prob,
- int lc, uint32_t literal_pos_mask) {
+ int lc, uint32_t literal_pos_mask,
+ void(*error)(char *x)) {
int mi = 1;
rc_update_bit_0(rc, prob);
prob = (p + LZMA_LITERAL +
@@ -366,7 +369,7 @@ static inline void INIT process_bit0(struct writer *wr, struct rc *rc,
match_byte <<= 1;
bit = match_byte & 0x100;
prob_lit = prob + 0x100 + bit + mi;
- if (rc_get_bit(rc, prob_lit, &mi)) {
+ if (rc_get_bit(rc, prob_lit, &mi, error)) {
if (!bit)
break;
} else {
@@ -377,7 +380,7 @@ static inline void INIT process_bit0(struct writer *wr, struct rc *rc,
}
while (mi < 0x100) {
uint16_t *prob_lit = prob + mi;
- rc_get_bit(rc, prob_lit, &mi);
+ rc_get_bit(rc, prob_lit, &mi, error);
}
write_byte(wr, mi);
if (cst->state < 4)
@@ -390,7 +393,8 @@ static inline void INIT process_bit0(struct writer *wr, struct rc *rc,
static inline void INIT process_bit1(struct writer *wr, struct rc *rc,
struct cstate *cst, uint16_t *p,
- int pos_state, uint16_t *prob) {
+ int pos_state, uint16_t *prob,
+ void(*error)(char *x)) {
int offset;
uint16_t *prob_len;
int num_bits;
@@ -398,7 +402,7 @@ static inline void INIT process_bit1(struct writer *wr, struct rc *rc,
rc_update_bit_1(rc, prob);
prob = p + LZMA_IS_REP + cst->state;
- if (rc_is_bit_0(rc, prob)) {
+ if (rc_is_bit_0(rc, prob, error)) {
rc_update_bit_0(rc, prob);
cst->rep3 = cst->rep2;
cst->rep2 = cst->rep1;
@@ -408,13 +412,13 @@ static inline void INIT process_bit1(struct writer *wr, struct rc *rc,
} else {
rc_update_bit_1(rc, prob);
prob = p + LZMA_IS_REP_G0 + cst->state;
- if (rc_is_bit_0(rc, prob)) {
+ if (rc_is_bit_0(rc, prob, error)) {
rc_update_bit_0(rc, prob);
prob = (p + LZMA_IS_REP_0_LONG
+ (cst->state <<
LZMA_NUM_POS_BITS_MAX) +
pos_state);
- if (rc_is_bit_0(rc, prob)) {
+ if (rc_is_bit_0(rc, prob, error)) {
rc_update_bit_0(rc, prob);
cst->state = cst->state < LZMA_NUM_LIT_STATES ?
@@ -429,13 +433,13 @@ static inline void INIT process_bit1(struct writer *wr, struct rc *rc,
rc_update_bit_1(rc, prob);
prob = p + LZMA_IS_REP_G1 + cst->state;
- if (rc_is_bit_0(rc, prob)) {
+ if (rc_is_bit_0(rc, prob, error)) {
rc_update_bit_0(rc, prob);
distance = cst->rep1;
} else {
rc_update_bit_1(rc, prob);
prob = p + LZMA_IS_REP_G2 + cst->state;
- if (rc_is_bit_0(rc, prob)) {
+ if (rc_is_bit_0(rc, prob, error)) {
rc_update_bit_0(rc, prob);
distance = cst->rep2;
} else {
@@ -453,7 +457,7 @@ static inline void INIT process_bit1(struct writer *wr, struct rc *rc,
}
prob_len = prob + LZMA_LEN_CHOICE;
- if (rc_is_bit_0(rc, prob_len)) {
+ if (rc_is_bit_0(rc, prob_len, error)) {
rc_update_bit_0(rc, prob_len);
prob_len = (prob + LZMA_LEN_LOW
+ (pos_state <<
@@ -463,7 +467,7 @@ static inline void INIT process_bit1(struct writer *wr, struct rc *rc,
} else {
rc_update_bit_1(rc, prob_len);
prob_len = prob + LZMA_LEN_CHOICE_2;
- if (rc_is_bit_0(rc, prob_len)) {
+ if (rc_is_bit_0(rc, prob_len, error)) {
rc_update_bit_0(rc, prob_len);
prob_len = (prob + LZMA_LEN_MID
+ (pos_state <<
@@ -479,7 +483,7 @@ static inline void INIT process_bit1(struct writer *wr, struct rc *rc,
}
}
- rc_bit_tree_decode(rc, prob_len, num_bits, &len);
+ rc_bit_tree_decode(rc, prob_len, num_bits, &len, error);
len += offset;
if (cst->state < 4) {
@@ -494,7 +498,7 @@ static inline void INIT process_bit1(struct writer *wr, struct rc *rc,
<< LZMA_NUM_POS_SLOT_BITS);
rc_bit_tree_decode(rc, prob,
LZMA_NUM_POS_SLOT_BITS,
- &pos_slot);
+ &pos_slot, error);
if (pos_slot >= LZMA_START_POS_MODEL_INDEX) {
int i, mi;
num_bits = (pos_slot >> 1) - 1;
@@ -507,7 +511,7 @@ static inline void INIT process_bit1(struct writer *wr, struct rc *rc,
num_bits -= LZMA_NUM_ALIGN_BITS;
while (num_bits--)
cst->rep0 = (cst->rep0 << 1) |
- rc_direct_bit(rc);
+ rc_direct_bit(rc, error);
prob = p + LZMA_ALIGN;
cst->rep0 <<= LZMA_NUM_ALIGN_BITS;
num_bits = LZMA_NUM_ALIGN_BITS;
@@ -515,7 +519,7 @@ static inline void INIT process_bit1(struct writer *wr, struct rc *rc,
i = 1;
mi = 1;
while (num_bits--) {
- if (rc_get_bit(rc, prob + mi, &mi))
+ if (rc_get_bit(rc, prob + mi, &mi, error))
cst->rep0 |= i;
i <<= 1;
}
@@ -537,7 +541,7 @@ STATIC int INIT unlzma(unsigned char *buf, int in_len,
int(*flush)(void*, unsigned int),
unsigned char *output,
int *posp,
- void(*error_fn)(char *x)
+ void(*error)(char *x)
)
{
struct lzma_header header;
@@ -553,8 +557,6 @@ STATIC int INIT unlzma(unsigned char *buf, int in_len,
unsigned char *inbuf;
int ret = -1;
- set_error_fn(error_fn);
-
if (buf)
inbuf = buf;
else
@@ -577,7 +579,7 @@ STATIC int INIT unlzma(unsigned char *buf, int in_len,
for (i = 0; i < sizeof(header); i++) {
if (rc.ptr >= rc.buffer_end)
- rc_read(&rc);
+ rc_read(&rc, error);
((unsigned char *)&header)[i] = *rc.ptr++;
}
@@ -622,17 +624,17 @@ STATIC int INIT unlzma(unsigned char *buf, int in_len,
for (i = 0; i < num_probs; i++)
p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1;
- rc_init_code(&rc);
+ rc_init_code(&rc, error);
while (get_pos(&wr) < header.dst_size) {
int pos_state = get_pos(&wr) & pos_state_mask;
uint16_t *prob = p + LZMA_IS_MATCH +
(cst.state << LZMA_NUM_POS_BITS_MAX) + pos_state;
- if (rc_is_bit_0(&rc, prob))
+ if (rc_is_bit_0(&rc, prob, error))
process_bit0(&wr, &rc, &cst, p, pos_state, prob,
- lc, literal_pos_mask);
+ lc, literal_pos_mask, error);
else {
- process_bit1(&wr, &rc, &cst, p, pos_state, prob);
+ process_bit1(&wr, &rc, &cst, p, pos_state, prob, error);
if (cst.rep0 == 0)
break;
}