[BusyBox] choice for reserving buffers

Larry Doolittle ldoolitt at recycle.lbl.gov
Thu Jan 25 06:10:39 UTC 2001


Completed submission for BB_FEATURE_BUFFERS_GO_ON_STACK,
compile-time selection of xmalloc() vs. on-stack buffers.

Usage of char lfile[] in syslogd.c looks semi-broken.  My patch
doesn't attempt to fix it, and I don't think it makes it worse.
Would a syslogd expert please look at this?

The vector[] array in tr.c was declared unsigned.  I took the
conservative way out, and added an unsigned char version of the
macro.  Chances are, though, _all_ char variables and char arrays
in BusyBox should be declared unsigned.  I wasn't willing to make
that jump at this point in the game.

The only thing I have tested so far is that BusyBox compiles
both with and without BB_FEATURE_BUFFERS_GO_ON_STACK.  I did
turn on tr, and it behaves normally enough.  Unless I'm stupider
than usual, I haven't broken anything else with this change.

Usage count--
   cp_mv.c:     1
   gunzip.c:    2
   rpmunpack.c: 1
   syslogd.c:   2
   tr.c:        5

diff -ur /home/larry/cvs/busybox/Config.h busybox-choice/Config.h
--- /home/larry/cvs/busybox/Config.h	Wed Jan 24 20:48:16 2001
+++ busybox-choice/Config.h	Wed Jan 24 21:25:21 2001
@@ -128,6 +128,11 @@
 // pretty/useful).
 //
 //
+// BusyBox will, by default, malloc space for its buffers.  This
+// costs code size for the call to xmalloc.  You can use the
+// following feature to have them put on the stack.  Please realize
+// that can be deadly for some small machines with limited stack space.
+//#define BB_FEATURE_BUFFERS_GO_ON_STACK
 //
 // Turn this on to use Erik's very cool devps, and devmtab kernel drivers,
 // thereby eliminating the need for the /proc filesystem and thereby saving
diff -ur /home/larry/cvs/busybox/busybox.h busybox-choice/busybox.h
--- /home/larry/cvs/busybox/busybox.h	Wed Jan 24 20:48:16 2001
+++ busybox-choice/busybox.h	Wed Jan 24 21:52:42 2001
@@ -266,4 +266,12 @@
 #define GIGABYTE (MEGABYTE*1024)
 #endif
 
+#ifdef BB_FEATURE_BUFFERS_GO_ON_STACK
+#define RESERVE_BB_BUFFER(buffer,len)           char buffer[len]
+#define RESERVE_BB_UBUFFER(buffer,len) unsigned char buffer[len]
+#else
+#define RESERVE_BB_BUFFER(buffer,len)           char *buffer=xmalloc(len)
+#define RESERVE_BB_UBUFFER(buffer,len) unsigned char *buffer=xmalloc(len)
+#endif
+
 #endif /* _BB_INTERNAL_H_ */
diff -ur /home/larry/cvs/busybox/cp_mv.c busybox-choice/cp_mv.c
--- /home/larry/cvs/busybox/cp_mv.c	Wed Jan 24 20:48:16 2001
+++ busybox-choice/cp_mv.c	Wed Jan 24 21:25:21 2001
@@ -175,8 +175,8 @@
 {
 	volatile int i;
 	int c;
-	char baseDestName[BUFSIZ + 1]; /* not declared globally == less bss used */
-	pBaseDestName = baseDestName; /* but available globally */
+	RESERVE_BB_BUFFER(baseDestName,BUFSIZ + 1);
+	pBaseDestName = baseDestName; /* available globally */
 
 	if (*applet_name == 'c' && *(applet_name + 1) == 'p')
 		dz_i = is_cp;
diff -ur /home/larry/cvs/busybox/docs/style-guide.txt busybox-choice/docs/style-guide.txt
--- /home/larry/cvs/busybox/docs/style-guide.txt	Wed Jan 24 20:48:19 2001
+++ busybox-choice/docs/style-guide.txt	Wed Jan 24 21:57:17 2001
@@ -402,7 +402,7 @@
 memory penalty for this buffer, even if the applet that uses said buffer is
 not run. This can be fixed, thusly:
 
-	static char *buffer
+	static char *buffer;
 	...
 	other_func()
 	{
@@ -418,7 +418,7 @@
 declared on the stack in the *_main() function and made available globally by
 assigning them to a global pointer thusly:
 
-	static char *pbuffer
+	static char *pbuffer;
 	...
 	other_func()
 	{
@@ -430,13 +430,13 @@
 		pbuffer = buffer;     /* but available globally */
 	...
 
-Thus:
- - global static buffers are eliminated
- - we don't grow the text segment as much because no malloc() call is made;
-   memory is automatically allocated on the stack when execution context
-   enters the function. (We still grow text a little bit because of the
-   assignment, but that's cheap compared to a function call.)
- - the buffer is still available globally via the pointer
+This last approach has some advantages (low code size, space not used until
+it's needed), but can be a problem in some low resource machines that have
+very limited stack space (e.g., uCLinux).  busybox.h declares a macro that
+implements compile-time selection between xmalloc() and stack creation, so
+you can code the line in question as
+		RESERVE_BB_BUFFER(buffer, BUFSIZ);
+and the right thing will happen, based on the customer's configuration.
 
 
 
diff -ur /home/larry/cvs/busybox/gunzip.c busybox-choice/gunzip.c
--- /home/larry/cvs/busybox/gunzip.c	Wed Jan 24 20:48:17 2001
+++ busybox-choice/gunzip.c	Wed Jan 24 21:55:15 2001
@@ -1222,8 +1222,8 @@
 	int force = 0;
 	struct stat statBuf;
 	char *delFileName;
-	char ifname[MAX_PATH_LEN + 1];	/* input file name */
-	char ofname[MAX_PATH_LEN + 1];	/* output file name */
+	RESERVE_BB_BUFFER(ifname, MAX_PATH_LEN+1);  /* input file name */
+	RESERVE_BB_BUFFER(ofname, MAX_PATH_LEN+1);  /* output file name */
 
 	method = DEFLATED;	/* default compression method */
 	exit_code = OK;	/* let's go out on a limb and assume everything will run fine (wink wink) */
diff -ur /home/larry/cvs/busybox/rpmunpack.c busybox-choice/rpmunpack.c
--- /home/larry/cvs/busybox/rpmunpack.c	Wed Jan 24 20:48:17 2001
+++ busybox-choice/rpmunpack.c	Wed Jan 24 21:29:18 2001
@@ -51,7 +51,7 @@
 int rpmunpack_main(int argc, char **argv)
 {
   int len, status = 0;
-  char buffer[BUFSIZ];
+  RESERVE_BB_BUFFER(buffer, BUFSIZ);
 
   /* Get our own program name */
   if ((progname = strrchr(argv[0], '/')) == NULL)
diff -ur /home/larry/cvs/busybox/syslogd.c busybox-choice/syslogd.c
--- /home/larry/cvs/busybox/syslogd.c	Wed Jan 24 20:48:17 2001
+++ busybox-choice/syslogd.c	Wed Jan 24 21:56:30 2001
@@ -209,7 +209,7 @@
 static const int BUFSIZE = 1023;
 static int serveConnection (int conn)
 {
-	char   buf[ BUFSIZE + 1 ];
+	RESERVE_BB_BUFFER(buf, BUFSIZE + 1);
 	int    n_read;
 
 	while ((n_read = read (conn, buf, BUFSIZE )) > 0) {
@@ -296,7 +296,7 @@
 	int sock_fd;
 	fd_set fds;
 
-	char lfile[BUFSIZ];
+	RESERVE_BB_BUFFER(lfile, BUFSIZ);
 
 	/* Set up signal handlers. */
 	signal (SIGINT,  quit_signal);
diff -ur /home/larry/cvs/busybox/tr.c busybox-choice/tr.c
--- /home/larry/cvs/busybox/tr.c	Wed Jan 24 20:48:18 2001
+++ busybox-choice/tr.c	Wed Jan 24 21:51:19 2001
@@ -144,10 +144,11 @@
 	int output_length=0, input_length;
 	int index = 1;
 	int i;
-	/* set up big arrays here (better than making a bunch of static arrays up top) */
-	unsigned char output[BUFSIZ], input[BUFSIZ];
-	unsigned char vector[ASCII + 1];
-	char invec[ASCII + 1], outvec[ASCII + 1];
+	RESERVE_BB_BUFFER(output, BUFSIZ);
+	RESERVE_BB_BUFFER(input,  BUFSIZ);
+	RESERVE_BB_UBUFFER(vector, ASCII+1);
+	RESERVE_BB_BUFFER(invec,  ASCII+1);
+	RESERVE_BB_BUFFER(outvec, ASCII+1);
 
 	/* ... but make them available globally */
 	poutput = output;





More information about the busybox mailing list