Hello Rafael,
This is *UNTESTED* suggestion for switching into lzo without the memcpy.
Please see if I missed something as I the code combination of global variables,
local memory pool and unrelated sizes is difficult to understand/maintain.
Basically, I've modify the init_swap_writer() so that it is the only function
knowing the size of the swap_map_handle needs. When you call it with
NULL you get the number of bytes it needs.
I also don't fully understand why the encryption and compression/write blocks
are related in size.... And why you remove the encryption block from mem_size.
Alon.
---
diff -urNp suspend.org/Makefile suspend.compress/Makefile
--- suspend.org/Makefile 2007-07-29 21:30:27.000000000 +0300
+++ suspend.compress/Makefile 2007-08-04 02:29:36.000000000 +0300
@@ -41,7 +41,7 @@ endif
ifdef CONFIG_COMPRESS
CC_FLAGS += -DCONFIG_COMPRESS
-SWSUSP_LD_FLAGS += -llzf
+SWSUSP_LD_FLAGS += -llzo2
endif
ifdef CONFIG_ENCRYPT
diff -urNp suspend.org/resume.c suspend.compress/resume.c
--- suspend.org/resume.c 2007-05-13 20:53:13.000000000 +0300
+++ suspend.compress/resume.c 2007-08-04 02:26:11.000000000 +0300
@@ -26,9 +26,7 @@
#include <string.h>
#include <errno.h>
#ifdef CONFIG_COMPRESS
-#include <lzf.h>
-#else
-#define lzf_decompress(a, b, c, d) 0
+#include <lzo/lzo1x.h>
#endif
#include "swsusp.h"
@@ -276,21 +274,28 @@ static int restore(struct swap_map_handl
void *buf = handle->page_buffer;
block = (struct buf_block *)(handle->read_buffer + disp);
+#ifdef CONFIG_COMPRESS
if (decompress) {
unsigned short cnt = block->size;
if (cnt == page_size) {
memcpy(buf, block->data, page_size);
} else if (cnt < page_size) {
- cnt = lzf_decompress(block->data, cnt, buf, page_size);
- if (cnt != page_size)
+ lzo_uint result_len = page_size;
+
+ if (
+ lzo1x_decompress_safe((lzo_bytep)block->data,
cnt, buf, &result_len, NULL) != LZO_E_OK ||
+ result_len != page_size
+ ) {
return -ENODATA;
+ }
} else {
return -EINVAL;
}
block->size += sizeof(short);
return block->size;
}
+#endif
memcpy(buf, block, page_size);
return page_size;
}
@@ -589,6 +594,10 @@ static int read_image(int dev, int fd, s
printf("resume: Compressed image\n");
#ifdef CONFIG_COMPRESS
decompress = 1;
+ if (lzo_init() != LZO_E_OK) {
+ fprintf(stderr, "suspend: Could not initialize
compress\n");
+ error = -ENOPKG;
+ }
#else
fprintf(stderr,"resume: Compression not supported\n");
error = -EINVAL;
diff -urNp suspend.org/suspend.c suspend.compress/suspend.c
--- suspend.org/suspend.c 2007-07-29 21:30:27.000000000 +0300
+++ suspend.compress/suspend.c 2007-08-04 02:29:13.000000000 +0300
@@ -33,9 +33,7 @@
#include <signal.h>
#include <termios.h>
#ifdef CONFIG_COMPRESS
-#include <lzf.h>
-#else
-#define lzf_compress(a, b, c, d) 0
+#include <lzo/lzo1x.h>
#endif
#include "swsusp.h"
@@ -61,6 +59,7 @@ static int suspend_loglevel = SUSPEND_LO
static char compute_checksum;
#ifdef CONFIG_COMPRESS
static char compress;
+static lzo_byte compress_work_buffer[LZO1X_1_MEM_COMPRESS];
#else
#define compress 0
#endif
@@ -268,21 +267,36 @@ struct swap_map_handle {
#endif
};
+/*
+ * If handle and buf are NULL, returns required memory size
+ */
static int
init_swap_writer(struct swap_map_handle *handle, int dev, int fd, void *buf)
{
- if (!buf)
+ char *p = (char *)buf;
+ if (handle != NULL && buf == NULL)
return -EINVAL;
- handle->areas = buf;
- handle->areas_per_page = (page_size - sizeof(loff_t)) /
- sizeof(struct swap_area);
- handle->next_swap = (loff_t *)(handle->areas + handle->areas_per_page);
- handle->page_buffer = (char *)buf + page_size;
- handle->write_buffer = handle->page_buffer + page_size;
+ if (handle != NULL) {
+ handle->areas = (struct swap_area *)p;
+ handle->areas_per_page = (page_size - sizeof(loff_t)) /
+ sizeof(struct swap_area);
+ handle->next_swap = (loff_t *)p;
+ }
+ p += page_size;
+ if (handle != NULL)
+ handle->page_buffer = p;
+ p += page_size;
+ if (handle != NULL)
+ handle->write_buffer = p;
+ p += buffer_size;
#ifdef CONFIG_ENCRYPT
- handle->encrypt_buffer = (unsigned char *)(handle->write_buffer +
- buffer_size);
+ if (handle != NULL)
+ handle->encrypt_buffer = (unsigned char *)p;
+ p += buffer_size;
#endif
+ if (handle == NULL)
+ return p-(char *)buf;
+
memset(handle->areas, 0, page_size);
handle->cur_swap = get_swap_page(dev);
if (!handle->cur_swap)
@@ -306,12 +320,15 @@ static int prepare(struct swap_map_handl
void *buf = handle->page_buffer;
block = (struct buf_block *)(handle->write_buffer + disp);
+#ifdef CONFIG_COMPRESS
if (compress) {
- unsigned short cnt;
+ lzo_uint cnt = 0;
- cnt = lzf_compress(buf, page_size,
- block->data, page_size - sizeof(short));
- if (!cnt) {
+ /* NOTICE: Assuming block->data large enough as lzo does not
check for limits */
+ if (
+ lzo1x_1_compress(buf, page_size,
(lzo_bytep)block->data, &cnt, compress_work_buffer) != LZO_E_OK ||
+ cnt >= page_size - sizeof(short)
+ ) {
memcpy(block->data, buf, page_size);
cnt = page_size;
} else {
@@ -322,6 +339,7 @@ static int prepare(struct swap_map_handl
cnt += sizeof(short);
return cnt;
}
+#endif
memcpy(block, buf, page_size);
return page_size;
}
@@ -1348,8 +1366,21 @@ int main(int argc, char *argv[])
page_size = getpagesize();
buffer_size = BUFFER_PAGES * page_size;
+ #define COMPRESS_BUFFER_SIZE(b) ((b) + (b)/16 + 64 + 3)
+ if (buffer_size < COMPRESS_BUFFER_SIZE(page_size)) {
+ buffer_size = COMPRESS_BUFFER_SIZE(page_size);
+ }
- mem_size = 3 * page_size + buffer_size;
+ /* The extra page is work area */
+ mem_size = page_size + init_swap_writer (NULL, 0, 0, NULL);
+#ifdef CONFIG_COMPRESS
+ if (compress) {
+ if (lzo_init() != LZO_E_OK) {
+ fprintf(stderr, "suspend: Could not initialize
compress\n");
+ return ENOPKG;
+ }
+ }
+#endif
#ifdef CONFIG_ENCRYPT
if (encrypt)
mem_size += buffer_size;
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Suspend-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/suspend-devel