Introduce FEATURE_COPYBUF_KB.

People who want smaller stack at any cost may use it
to reduce cp's stack usage (FEATURE_COPYBUF_KB=1).
Desktop people may get faster copy of big files
(FEATURE_COPYBUF_KB=32 is ~30% faster than 4kb)
This commit is contained in:
Denis Vlasenko 2007-12-02 03:27:42 +00:00
parent e2532ab5f2
commit 4c13922961
2 changed files with 34 additions and 8 deletions

View File

@ -110,6 +110,16 @@ config FEATURE_EDITING_FANCY_PROMPT
Setting this option allows for prompts to use things like \w and Setting this option allows for prompts to use things like \w and
\$ and escape codes. \$ and escape codes.
config FEATURE_COPYBUF_KB
int "Copy buffer size, in kilobytes"
range 1 1024
default 4
help
Size of buffer used by cp, mv, install etc.
Buffers which are 4 kb or less will be allocated on stack.
Bigger buffers will be allocated with mmap, with fallback to 4 kb
stack buffer if mmap fails.
config MONOTONIC_SYSCALL config MONOTONIC_SYSCALL
bool "Use clock_gettime(CLOCK_MONOTONIC) syscall" bool "Use clock_gettime(CLOCK_MONOTONIC) syscall"
default y default y

View File

@ -9,31 +9,42 @@
#include "libbb.h" #include "libbb.h"
#if BUFSIZ < 4096
#undef BUFSIZ
#define BUFSIZ 4096
#endif
/* Used by NOFORK applets (e.g. cat) - must not use xmalloc */ /* Used by NOFORK applets (e.g. cat) - must not use xmalloc */
static off_t bb_full_fd_action(int src_fd, int dst_fd, off_t size) static off_t bb_full_fd_action(int src_fd, int dst_fd, off_t size)
{ {
int status = -1; int status = -1;
off_t total = 0; off_t total = 0;
char buffer[BUFSIZ]; #if CONFIG_FEATURE_COPYBUF_KB <= 4
char buffer[CONFIG_FEATURE_COPYBUF_KB * 1024];
enum { buffer_size = sizeof(buffer) };
#else
char *buffer;
int buffer_size;
buffer = mmap(NULL, CONFIG_FEATURE_COPYBUF_KB * 1024,
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON,
/* ignored: */ -1, 0);
buffer_size = CONFIG_FEATURE_COPYBUF_KB * 1024;
if (buffer == MAP_FAILED) {
buffer = alloca(4 * 1024);
buffer_size = 4 * 1024;
}
#endif
if (src_fd < 0) if (src_fd < 0)
goto out; goto out;
if (!size) { if (!size) {
size = BUFSIZ; size = buffer_size;
status = 1; /* copy until eof */ status = 1; /* copy until eof */
} }
while (1) { while (1) {
ssize_t rd; ssize_t rd;
rd = safe_read(src_fd, buffer, size > BUFSIZ ? BUFSIZ : size); rd = safe_read(src_fd, buffer, size > buffer_size ? buffer_size : size);
if (!rd) { /* eof - all done */ if (!rd) { /* eof - all done */
status = 0; status = 0;
@ -62,6 +73,11 @@ static off_t bb_full_fd_action(int src_fd, int dst_fd, off_t size)
} }
} }
out: out:
#if CONFIG_FEATURE_COPYBUF_KB > 4
if (buffer_size != 4 * 1024)
munmap(buffer, buffer_size);
#endif
return status ? -1 : total; return status ? -1 : total;
} }