diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2024-05-31 12:01:43 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2024-05-31 16:03:23 +0200 |
commit | 2075553a1b0eb843d4ee73a039b3e30bed9274e0 (patch) | |
tree | 904f192fa9d7c920c9dde6a7bc26b208c3b03312 /networking | |
parent | 5a68a246e750359819d63bcff5ef97dd9c7788fc (diff) | |
download | busybox-w32-2075553a1b0eb843d4ee73a039b3e30bed9274e0.tar.gz busybox-w32-2075553a1b0eb843d4ee73a039b3e30bed9274e0.tar.bz2 busybox-w32-2075553a1b0eb843d4ee73a039b3e30bed9274e0.zip |
libbb: add bit counting function, use where appropriate
Although "naive" counting function is not too slow and is smaller,
using it on e.g. each of 1024 words of CPU mask feels wrong.
function old new delta
bb_popcnt_32 - 52 +52
get_prefix 323 321 -2
nproc_main 206 199 -7
d4_run_script 739 731 -8
ipcalc_main 533 507 -26
------------------------------------------------------------------------------
(add/remove: 2/0 grow/shrink: 0/4 up/down: 52/-43) Total: 9 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'networking')
-rw-r--r-- | networking/ifupdown.c | 8 | ||||
-rw-r--r-- | networking/ipcalc.c | 21 | ||||
-rw-r--r-- | networking/libiproute/utils.c | 11 | ||||
-rw-r--r-- | networking/udhcp/dhcpc.c | 15 |
4 files changed, 9 insertions, 46 deletions
diff --git a/networking/ifupdown.c b/networking/ifupdown.c index 6c4ae27f2..9c3640be7 100644 --- a/networking/ifupdown.c +++ b/networking/ifupdown.c | |||
@@ -306,7 +306,6 @@ static int count_netmask_bits(const char *dotted_quad) | |||
306 | // d = ~d; /* 11110000 -> 00001111 */ | 306 | // d = ~d; /* 11110000 -> 00001111 */ |
307 | 307 | ||
308 | /* Shorter version */ | 308 | /* Shorter version */ |
309 | int result; | ||
310 | struct in_addr ip; | 309 | struct in_addr ip; |
311 | unsigned d; | 310 | unsigned d; |
312 | 311 | ||
@@ -316,12 +315,7 @@ static int count_netmask_bits(const char *dotted_quad) | |||
316 | d = ~d; /* 11110000 -> 00001111 */ | 315 | d = ~d; /* 11110000 -> 00001111 */ |
317 | if (d & (d+1)) /* check that it is in 00001111 form */ | 316 | if (d & (d+1)) /* check that it is in 00001111 form */ |
318 | return -1; /* no it is not */ | 317 | return -1; /* no it is not */ |
319 | result = 32; | 318 | return bb_popcnt_32(~d); |
320 | while (d) { | ||
321 | d >>= 1; | ||
322 | result--; | ||
323 | } | ||
324 | return result; | ||
325 | } | 319 | } |
326 | # endif | 320 | # endif |
327 | 321 | ||
diff --git a/networking/ipcalc.c b/networking/ipcalc.c index 92e7b289d..3ec473c6b 100644 --- a/networking/ipcalc.c +++ b/networking/ipcalc.c | |||
@@ -71,25 +71,6 @@ static unsigned long get_netmask(unsigned long ipaddr) | |||
71 | return 0; | 71 | return 0; |
72 | } | 72 | } |
73 | 73 | ||
74 | #if ENABLE_FEATURE_IPCALC_FANCY | ||
75 | static int get_prefix(unsigned long netmask) | ||
76 | { | ||
77 | unsigned long msk = 0x80000000; | ||
78 | int ret = 0; | ||
79 | |||
80 | netmask = htonl(netmask); | ||
81 | while (msk) { | ||
82 | if (netmask & msk) | ||
83 | ret++; | ||
84 | msk >>= 1; | ||
85 | } | ||
86 | return ret; | ||
87 | } | ||
88 | #else | ||
89 | int get_prefix(unsigned long netmask); | ||
90 | #endif | ||
91 | |||
92 | |||
93 | #define NETMASK 0x01 | 74 | #define NETMASK 0x01 |
94 | #define BROADCAST 0x02 | 75 | #define BROADCAST 0x02 |
95 | #define NETWORK 0x04 | 76 | #define NETWORK 0x04 |
@@ -210,7 +191,7 @@ int ipcalc_main(int argc UNUSED_PARAM, char **argv) | |||
210 | 191 | ||
211 | if (ENABLE_FEATURE_IPCALC_FANCY) { | 192 | if (ENABLE_FEATURE_IPCALC_FANCY) { |
212 | if (opt & NETPREFIX) { | 193 | if (opt & NETPREFIX) { |
213 | printf("PREFIX=%i\n", get_prefix(netmask)); | 194 | printf("PREFIX=%i\n", bb_popcnt_32(netmask)); |
214 | } | 195 | } |
215 | 196 | ||
216 | if (opt & HOSTNAME) { | 197 | if (opt & HOSTNAME) { |
diff --git a/networking/libiproute/utils.c b/networking/libiproute/utils.c index 4ce230356..3cce4a06e 100644 --- a/networking/libiproute/utils.c +++ b/networking/libiproute/utils.c | |||
@@ -175,14 +175,13 @@ static void get_prefix_1(inet_prefix *dst, char *arg, int family) | |||
175 | if (netmask_pfx.family == AF_INET) { | 175 | if (netmask_pfx.family == AF_INET) { |
176 | /* fill in prefix length of dotted quad */ | 176 | /* fill in prefix length of dotted quad */ |
177 | uint32_t mask = ntohl(netmask_pfx.data[0]); | 177 | uint32_t mask = ntohl(netmask_pfx.data[0]); |
178 | uint32_t host = ~mask; | 178 | uint32_t inv = ~mask; |
179 | 179 | ||
180 | /* a valid netmask must be 2^n - 1 */ | 180 | /* a valid netmask must be 11..10..00 */ |
181 | if (host & (host + 1)) | 181 | if (inv & (inv + 1)) |
182 | goto bad; | 182 | goto bad; /* inv is not 00..01..11 */ |
183 | 183 | ||
184 | for (plen = 0; mask; mask <<= 1) | 184 | plen = bb_popcnt_32(mask); |
185 | ++plen; | ||
186 | if (plen > dst->bitlen) | 185 | if (plen > dst->bitlen) |
187 | goto bad; | 186 | goto bad; |
188 | /* dst->flags |= PREFIXLEN_SPECIFIED; */ | 187 | /* dst->flags |= PREFIXLEN_SPECIFIED; */ |
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 07e2eadfe..e44086c2e 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c | |||
@@ -150,18 +150,6 @@ static int sprint_nip(char *dest, const char *pre, const uint8_t *ip) | |||
150 | return sprintf(dest, "%s%u.%u.%u.%u", pre, ip[0], ip[1], ip[2], ip[3]); | 150 | return sprintf(dest, "%s%u.%u.%u.%u", pre, ip[0], ip[1], ip[2], ip[3]); |
151 | } | 151 | } |
152 | 152 | ||
153 | /* really simple implementation, just count the bits */ | ||
154 | static int mton(uint32_t mask) | ||
155 | { | ||
156 | int i = 0; | ||
157 | mask = ntohl(mask); /* 111110000-like bit pattern */ | ||
158 | while (mask) { | ||
159 | i++; | ||
160 | mask <<= 1; | ||
161 | } | ||
162 | return i; | ||
163 | } | ||
164 | |||
165 | #if ENABLE_FEATURE_UDHCPC_SANITIZEOPT | 153 | #if ENABLE_FEATURE_UDHCPC_SANITIZEOPT |
166 | /* Check if a given name represents a valid DNS name */ | 154 | /* Check if a given name represents a valid DNS name */ |
167 | /* See RFC1035, 2.3.1 */ | 155 | /* See RFC1035, 2.3.1 */ |
@@ -508,7 +496,8 @@ static void fill_envp(struct dhcp_packet *packet) | |||
508 | /* Generate extra envvar for DHCP_SUBNET, $mask */ | 496 | /* Generate extra envvar for DHCP_SUBNET, $mask */ |
509 | uint32_t subnet; | 497 | uint32_t subnet; |
510 | move_from_unaligned32(subnet, opt_item->data); | 498 | move_from_unaligned32(subnet, opt_item->data); |
511 | putenvp(xasprintf("mask=%u", mton(subnet))); | 499 | //FIXME: we do not check that subnet has bit pattern 11..10..0 |
500 | putenvp(xasprintf("mask=%u", bb_popcnt_32(subnet))); | ||
512 | } | 501 | } |
513 | } else { | 502 | } else { |
514 | unsigned ofs; | 503 | unsigned ofs; |