aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorvda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2007-03-15 19:52:42 +0000
committervda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2007-03-15 19:52:42 +0000
commit53a0cadbe1f0a2bde37ca86e1185d286424181f0 (patch)
tree306d8ad4c9a20e971356afc3b3a76abc15263458 /docs
parentca274d1bbe798fbf3950c31e92c9f33d29cef48c (diff)
downloadbusybox-w32-53a0cadbe1f0a2bde37ca86e1185d286424181f0.tar.gz
busybox-w32-53a0cadbe1f0a2bde37ca86e1185d286424181f0.tar.bz2
busybox-w32-53a0cadbe1f0a2bde37ca86e1185d286424181f0.zip
mkfs_minix: stop using lots of bss/data.
data -3500 bytes, code -300 bytes keep_data_small: expand/fix git-svn-id: svn://busybox.net/trunk/busybox@18123 69ca8d6d-28ef-0310-b511-8ec308f3f277
Diffstat (limited to 'docs')
-rw-r--r--docs/keep_data_small.txt68
1 files changed, 52 insertions, 16 deletions
diff --git a/docs/keep_data_small.txt b/docs/keep_data_small.txt
index ec13b4d3f..5137dffc6 100644
--- a/docs/keep_data_small.txt
+++ b/docs/keep_data_small.txt
@@ -1,4 +1,4 @@
1 Keeping data small 1 Keeping data small
2 2
3When many applets are compiled into busybox, all rw data and 3When many applets are compiled into busybox, all rw data and
4bss for each applet are concatenated. Including those from libc, 4bss for each applet are concatenated. Including those from libc,
@@ -10,6 +10,11 @@ On nommu it's probably bites the most, actually using real
10RAM for rwdata and bss. On i386, bss is lazily allocated 10RAM for rwdata and bss. On i386, bss is lazily allocated
11by COWed zero pages. Not sure about rwdata - also COW? 11by COWed zero pages. Not sure about rwdata - also COW?
12 12
13In order to keep bbox NOMMU and small-mem systems friendly
14we should avoid large global data in our applets, and should
15minimize usage of libc functions which implicitly use
16such structures in libc.
17
13Small experiment measures "parasitic" bbox memory consumption. 18Small experiment measures "parasitic" bbox memory consumption.
14Here we start 1000 "busybox sleep 10" in parallel. 19Here we start 1000 "busybox sleep 10" in parallel.
15bbox binary is practically allyesconfig static one, 20bbox binary is practically allyesconfig static one,
@@ -34,14 +39,10 @@ bash-3.2# nmeter '%t %c %b %m %p %[pn]'
3423:17:43 .......... 0 0 168M 0 147 3923:17:43 .......... 0 0 168M 0 147
35 40
36This requires 55M of memory. Thus 1 trivial busybox applet 41This requires 55M of memory. Thus 1 trivial busybox applet
37takes 55k of userspace memory (nmeter doesn't account for kernel-side 42takes 55k of memory.
38allocations). Definitely can be improved.
39 43
40Thus we should avoid large global data in our applets,
41and should minimize usage of libc functions which implicitly use
42such structures in libc.
43 44
44 Example 1 45 Example 1
45 46
46One example how to reduce global data usage is in 47One example how to reduce global data usage is in
47archival/libunarchive/decompress_unzip.c: 48archival/libunarchive/decompress_unzip.c:
@@ -57,12 +58,15 @@ archival/libunarchive/decompress_unzip.c:
57#define STATE_IN_BSS 0 58#define STATE_IN_BSS 0
58#define STATE_IN_MALLOC 1 59#define STATE_IN_MALLOC 1
59 60
61(see the rest of the file to get the idea)
62
60This example completely eliminates globals in that module. 63This example completely eliminates globals in that module.
61Required memory is allocated in inflate_gunzip() [its main module] 64Required memory is allocated in inflate_gunzip() [its main module]
62and then passed down to all subroutines which need to access 'globals' 65and then passed down to all subroutines which need to access 'globals'
63as a parameter. 66as a parameter.
64 67
65 Example 2 68
69 Example 2
66 70
67In case you don't want to pass this additional parameter everywhere, 71In case you don't want to pass this additional parameter everywhere,
68take a look at archival/gzip.c. Here all global data is replaced by 72take a look at archival/gzip.c. Here all global data is replaced by
@@ -70,7 +74,7 @@ single global pointer (ptr_to_globals) to allocated storage.
70 74
71In order to not duplicate ptr_to_globals in every applet, you can 75In order to not duplicate ptr_to_globals in every applet, you can
72reuse single common one. It is defined in libbb/messages.c 76reuse single common one. It is defined in libbb/messages.c
73as struct globals *ptr_to_globals, but the struct globals is 77as struct globals *const ptr_to_globals, but the struct globals is
74NOT defined in libbb.h. You first define your own struct: 78NOT defined in libbb.h. You first define your own struct:
75 79
76struct globals { int a; char buf[1000]; }; 80struct globals { int a; char buf[1000]; };
@@ -79,13 +83,45 @@ and then declare that ptr_to_globals is a pointer to it:
79 83
80#define G (*ptr_to_globals) 84#define G (*ptr_to_globals)
81 85
82Linker magic ensures that these two merge into single pointer object. 86ptr_to_globals is declared as constant pointer.
83Now initialize it in <applet>_main(): 87This helps gcc understand that it won't change, resulting in noticeably
88smaller code. In order to assign it, use PTR_TO_GLOBALS macro:
89
90 PTR_TO_GLOBALS = xzalloc(sizeof(G));
91
92Typically it is done in <applet>_main().
93
94Now you can reference "globals" by G.a, G.buf and so on, in any function.
95
96
97 bb_common_bufsiz1
98
99There is one big common buffer in bss - bb_common_bufsiz1. It is a much
100earlier mechanism to reduce bss usage. Each applet can use it for
101its needs. Library functions are prohibited from using it.
102
103'G.' trick can be done using bb_common_bufsiz1 instead of malloced buffer:
104
105#define G (*(struct globals*)&bb_common_bufsiz1)
106
107Be careful, though, and use it only if
108sizeof(struct globals) <= sizeof(bb_common_bufsiz1).
109
110
111 Drawbacks
112
113You have to initialize it by hand. xzalloc() can be helpful in clearing
114allocated storage to 0, but anything more must be done by hand.
115
116All global variables are prefixed by 'G.' now. If this makes code
117less readable, use #defines:
118
119#define dev_fd (G.dev_fd)
120#define sector (G.sector)
84 121
85 ptr_to_globals = xzalloc(sizeof(G));
86 122
87and you can reference "globals" by G.a, G.buf and so on, in any function. 123 Word of caution
88 124
89The drawback is that now you have to initialize it by hand. xzalloc() 125If applet doesn't use much of global data, converting it to using
90can be helpful in clearing allocated storage to 0, but anything more 126one of above methods is not worth resulting code obfuscation.
91must be done by hand. 127If you have less that ~300 bytes of global data - don't bother.