svn commit: trunk/busybox: archival/libunarchive include networking etc...

vda at busybox.net vda at busybox.net
Mon Dec 8 22:56:19 UTC 2008


Author: vda
Date: 2008-12-08 14:56:18 -0800 (Mon, 08 Dec 2008)
New Revision: 24334

Log:
optimize 16- and 32-bit moves

function                                             old     new   delta
udhcpd_main                                         1239    1257     +18
udhcp_add_simple_option                               93      92      -1
buffer_read_le_u32                                    19      18      -1
unpack_gz_stream_with_info                           526     520      -6
dnsd_main                                           1470    1463      -7
udhcp_run_script                                    1208    1186     -22
send_ACK                                             255     229     -26
arping_main                                         1661    1623     -38
send_offer                                           470     428     -42
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/8 up/down: 18/-143)          Total: -125 bytes



Modified:
   trunk/busybox/archival/libunarchive/decompress_unzip.c
   trunk/busybox/include/platform.h
   trunk/busybox/networking/arping.c
   trunk/busybox/networking/dnsd.c
   trunk/busybox/networking/libiproute/libnetlink.c
   trunk/busybox/networking/libiproute/ll_addr.c
   trunk/busybox/networking/udhcp/dhcpc.c
   trunk/busybox/networking/udhcp/dhcpd.c
   trunk/busybox/networking/udhcp/options.c
   trunk/busybox/networking/udhcp/script.c
   trunk/busybox/networking/udhcp/serverpacket.c
   trunk/busybox/networking/zcip.c
   trunk/busybox/util-linux/volume_id/linux_raid.c


Changeset:
Modified: trunk/busybox/archival/libunarchive/decompress_unzip.c
===================================================================
--- trunk/busybox/archival/libunarchive/decompress_unzip.c	2008-12-08 19:57:16 UTC (rev 24333)
+++ trunk/busybox/archival/libunarchive/decompress_unzip.c	2008-12-08 22:56:18 UTC (rev 24334)
@@ -1083,8 +1083,7 @@
 {
 	uint16_t res;
 #if BB_LITTLE_ENDIAN
-	/* gcc 4.2.1 is very clever */
-	memcpy(&res, &bytebuffer[bytebuffer_offset], 2);
+	move_from_unaligned16(res, &bytebuffer[bytebuffer_offset]);
 #else
 	res = bytebuffer[bytebuffer_offset];
 	res |= bytebuffer[bytebuffer_offset + 1] << 8;
@@ -1097,7 +1096,7 @@
 {
 	uint32_t res;
 #if BB_LITTLE_ENDIAN
-	memcpy(&res, &bytebuffer[bytebuffer_offset], 4);
+	move_from_unaligned32(res, &bytebuffer[bytebuffer_offset]);
 #else
 	res = bytebuffer[bytebuffer_offset];
 	res |= bytebuffer[bytebuffer_offset + 1] << 8;

Modified: trunk/busybox/include/platform.h
===================================================================
--- trunk/busybox/include/platform.h	2008-12-08 19:57:16 UTC (rev 24333)
+++ trunk/busybox/include/platform.h	2008-12-08 22:56:18 UTC (rev 24334)
@@ -151,13 +151,19 @@
 
 /* ---- Unaligned access ------------------------------------ */
 
-/* parameter is supposed to be an uint32_t* ptr */
+/* NB: unaligned parameter should be a pointer, aligned one -
+ * a lvalue. This makes it more likely to not swap them by mistake
+ */
 #if defined(i386) || defined(__x86_64__)
-#define get_unaligned_u32p(u32p) (*(u32p))
+#define move_from_unaligned16(v, u16p) ((v) = *(uint16_t*)(u16p))
+#define move_from_unaligned32(v, u32p) ((v) = *(uint32_t*)(u32p))
+#define move_to_unaligned32(u32p, v)   (*(uint32_t*)(u32p) = (v))
 /* #elif ... - add your favorite arch today! */
 #else
 /* performs reasonably well (gcc usually inlines memcpy here) */
-#define get_unaligned_u32p(u32p) ({ uint32_t __t; memcpy(&__t, (u32p), 4); __t; })
+#define move_from_unaligned16(v, u16p) (memcpy(&(v), (u16p), 2))
+#define move_from_unaligned32(v, u32p) (memcpy(&(v), (u32p), 4))
+#define move_to_unaligned32(u32p, v)   (memcpy((u32p), &(v), 4))
 #endif
 
 /* ---- Networking ------------------------------------------ */

Modified: trunk/busybox/networking/arping.c
===================================================================
--- trunk/busybox/networking/arping.c	2008-12-08 19:57:16 UTC (rev 24333)
+++ trunk/busybox/networking/arping.c	2008-12-08 22:56:18 UTC (rev 24334)
@@ -153,6 +153,15 @@
 	struct arphdr *ah = (struct arphdr *) buf;
 	unsigned char *p = (unsigned char *) (ah + 1);
 	struct in_addr src_ip, dst_ip;
+	/* moves below assume in_addr is 4 bytes big, ensure that */
+	struct BUG_in_addr_must_be_4 {
+		char BUG_in_addr_must_be_4[
+			sizeof(struct in_addr) == 4 ? 1 : -1
+		];
+		char BUG_s_addr_must_be_4[
+			sizeof(src_ip.s_addr) == 4 ? 1 : -1
+		];
+	};
 
 	/* Filter out wild packets */
 	if (FROM->sll_pkttype != PACKET_HOST
@@ -171,13 +180,13 @@
 
 	/* Protocol must be IP. */
 	if (ah->ar_pro != htons(ETH_P_IP)
-		|| (ah->ar_pln != 4)
-		|| (ah->ar_hln != me.sll_halen)
-		|| (len < (int)(sizeof(*ah) + 2 * (4 + ah->ar_hln))))
+	 || (ah->ar_pln != 4)
+	 || (ah->ar_hln != me.sll_halen)
+	 || (len < (int)(sizeof(*ah) + 2 * (4 + ah->ar_hln))))
 		return false;
 
-	memcpy(&src_ip, p + ah->ar_hln, 4);
-	memcpy(&dst_ip, p + ah->ar_hln + 4 + ah->ar_hln, 4);
+	move_from_unaligned32(src_ip.s_addr, p + ah->ar_hln);
+	move_from_unaligned32(dst_ip.s_addr, p + ah->ar_hln + 4 + ah->ar_hln);
 
 	if (dst.s_addr != src_ip.s_addr)
 		return false;
@@ -200,7 +209,7 @@
 		   dst_ip/dst_hw do not matter.
 		 */
 		if ((memcmp(p, &me.sll_addr, me.sll_halen) == 0)
-			|| (src.s_addr && src.s_addr != dst_ip.s_addr))
+		 || (src.s_addr && src.s_addr != dst_ip.s_addr))
 			return false;
 	}
 	if (!(option_mask32 & QUIET)) {
@@ -306,7 +315,7 @@
 	/* if (!inet_aton(target, &dst)) - not needed */ {
 		len_and_sockaddr *lsa;
 		lsa = xhost_and_af2sockaddr(target, 0, AF_INET);
-		memcpy(&dst, &lsa->u.sin.sin_addr.s_addr, 4);
+		dst = lsa->u.sin.sin_addr;
 		if (ENABLE_FEATURE_CLEAN_UP)
 			free(lsa);
 	}

Modified: trunk/busybox/networking/dnsd.c
===================================================================
--- trunk/busybox/networking/dnsd.c	2008-12-08 19:57:16 UTC (rev 24333)
+++ trunk/busybox/networking/dnsd.c	2008-12-08 22:56:18 UTC (rev 24334)
@@ -253,7 +253,7 @@
 			goto empty_packet;
 		}
 		v32 = a.s_addr; /* in case long != int */
-		memcpy(answstr, &v32, 4);
+		move_to_unaligned32(answstr, v32);
 		outr_rlen = 4;			// uint32_t IP
 	} else
 		outr_rlen = strlen((char *)answstr) + 1;	// a host name

Modified: trunk/busybox/networking/libiproute/libnetlink.c
===================================================================
--- trunk/busybox/networking/libiproute/libnetlink.c	2008-12-08 19:57:16 UTC (rev 24333)
+++ trunk/busybox/networking/libiproute/libnetlink.c	2008-12-08 22:56:18 UTC (rev 24334)
@@ -341,7 +341,7 @@
 	rta = (struct rtattr*)(((char*)n) + NLMSG_ALIGN(n->nlmsg_len));
 	rta->rta_type = type;
 	rta->rta_len = len;
-	memcpy(RTA_DATA(rta), &data, 4);
+	move_to_unaligned32(RTA_DATA(rta), data);
 	n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len;
 	return 0;
 }
@@ -372,7 +372,7 @@
 	subrta = (struct rtattr*)(((char*)rta) + RTA_ALIGN(rta->rta_len));
 	subrta->rta_type = type;
 	subrta->rta_len = len;
-	memcpy(RTA_DATA(subrta), &data, 4);
+	move_to_unaligned32(RTA_DATA(subrta), data);
 	rta->rta_len = NLMSG_ALIGN(rta->rta_len) + len;
 	return 0;
 }

Modified: trunk/busybox/networking/libiproute/ll_addr.c
===================================================================
--- trunk/busybox/networking/libiproute/ll_addr.c	2008-12-08 19:57:16 UTC (rev 24333)
+++ trunk/busybox/networking/libiproute/ll_addr.c	2008-12-08 22:56:18 UTC (rev 24334)
@@ -43,6 +43,8 @@
 
 int ll_addr_a2n(unsigned char *lladdr, int len, char *arg)
 {
+	int i;
+
 	if (strchr(arg, '.')) {
 		inet_prefix pfx;
 		if (get_addr_1(&pfx, arg, AF_INET)) {
@@ -54,26 +56,24 @@
 		}
 		memcpy(lladdr, pfx.data, 4);
 		return 4;
-	} else {
-		int i;
+	}
 
-		for (i=0; i<len; i++) {
-			int temp;
-			char *cp = strchr(arg, ':');
-			if (cp) {
-				*cp = 0;
-				cp++;
-			}
-			if (sscanf(arg, "%x", &temp) != 1 || (temp < 0 || temp > 255)) {
-				bb_error_msg("\"%s\" is invalid lladdr", arg);
-				return -1;
-			}
-			lladdr[i] = temp;
-			if (!cp) {
-				break;
-			}
-			arg = cp;
+	for (i = 0; i < len; i++) {
+		int temp;
+		char *cp = strchr(arg, ':');
+		if (cp) {
+			*cp = 0;
+			cp++;
 		}
-		return i+1;
+		if (sscanf(arg, "%x", &temp) != 1 || (temp < 0 || temp > 255)) {
+			bb_error_msg("\"%s\" is invalid lladdr", arg);
+			return -1;
+		}
+		lladdr[i] = temp;
+		if (!cp) {
+			break;
+		}
+		arg = cp;
 	}
+	return i+1;
 }

Modified: trunk/busybox/networking/udhcp/dhcpc.c
===================================================================
--- trunk/busybox/networking/udhcp/dhcpc.c	2008-12-08 19:57:16 UTC (rev 24333)
+++ trunk/busybox/networking/udhcp/dhcpc.c	2008-12-08 22:56:18 UTC (rev 24334)
@@ -503,7 +503,7 @@
 						/* still selecting - this server looks bad */
 					}
 					/* it IS unaligned sometimes, don't "optimize" */
-					server_addr = get_unaligned_u32p((uint32_t*)temp);
+					move_from_unaligned32(server_addr, temp);
 					xid = packet.xid;
 					requested_ip = packet.yiaddr;
 
@@ -525,7 +525,7 @@
 						lease_seconds = 60 * 60;
 					} else {
 						/* it IS unaligned sometimes, don't "optimize" */
-						lease_seconds = get_unaligned_u32p((uint32_t*)temp);
+						move_from_unaligned32(lease_seconds, temp);
 						lease_seconds = ntohl(lease_seconds);
 						lease_seconds &= 0x0fffffff; /* paranoia: must not be prone to overflows */
 						if (lease_seconds < 10) /* and not too small */

Modified: trunk/busybox/networking/udhcp/dhcpd.c
===================================================================
--- trunk/busybox/networking/udhcp/dhcpd.c	2008-12-08 19:57:16 UTC (rev 24333)
+++ trunk/busybox/networking/udhcp/dhcpd.c	2008-12-08 22:56:18 UTC (rev 24334)
@@ -30,7 +30,9 @@
 	int server_socket = -1, bytes, retval, max_sock;
 	struct dhcpMessage packet;
 	uint8_t *state, *server_id, *requested;
-	uint32_t server_id_align, requested_align, static_lease_ip;
+	uint32_t server_id_aligned = server_id_aligned; /* for compiler */
+	uint32_t requested_aligned = requested_aligned;
+	uint32_t static_lease_ip;
 	unsigned timeout_end;
 	unsigned num_ips;
 	unsigned opt;
@@ -79,7 +81,7 @@
 	option = find_option(server_config.options, DHCP_LEASE_TIME);
 	server_config.lease = LEASE_TIME;
 	if (option) {
-		memcpy(&server_config.lease, option->data + 2, 4);
+		move_from_unaligned32(server_config.lease, option->data + 2);
 		server_config.lease = ntohl(server_config.lease);
 	}
 
@@ -190,21 +192,24 @@
 			requested = get_option(&packet, DHCP_REQUESTED_IP);
 			server_id = get_option(&packet, DHCP_SERVER_ID);
 
-			if (requested) memcpy(&requested_align, requested, 4);
-			if (server_id) memcpy(&server_id_align, server_id, 4);
+			if (requested)
+				move_from_unaligned32(requested_aligned, requested);
+			if (server_id)
+				move_from_unaligned32(server_id_aligned, server_id);
 
 			if (lease) {
 				if (server_id) {
 					/* SELECTING State */
-					DEBUG("server_id = %08x", ntohl(server_id_align));
-					if (server_id_align == server_config.server && requested
-					 && requested_align == lease->yiaddr
+					DEBUG("server_id = %08x", ntohl(server_id_aligned));
+					if (server_id_aligned == server_config.server
+					 && requested
+					 && requested_aligned == lease->yiaddr
 					) {
 						send_ACK(&packet, lease->yiaddr);
 					}
 				} else if (requested) {
 					/* INIT-REBOOT State */
-					if (lease->yiaddr == requested_align)
+					if (lease->yiaddr == requested_aligned)
 						send_ACK(&packet, lease->yiaddr);
 					else
 						send_NAK(&packet);
@@ -221,7 +226,7 @@
 
 			} else if (requested) {
 				/* INIT-REBOOT State */
-				lease = find_lease_by_yiaddr(requested_align);
+				lease = find_lease_by_yiaddr(requested_aligned);
 				if (lease) {
 					if (lease_expired(lease)) {
 						/* probably best if we drop this lease */
@@ -230,7 +235,7 @@
 					} else
 						send_NAK(&packet);
 				} else {
-					uint32_t r = ntohl(requested_align);
+					uint32_t r = ntohl(requested_aligned);
 					if (r < server_config.start_ip
 				         || r > server_config.end_ip
 					) {

Modified: trunk/busybox/networking/udhcp/options.c
===================================================================
--- trunk/busybox/networking/udhcp/options.c	2008-12-08 19:57:16 UTC (rev 24333)
+++ trunk/busybox/networking/udhcp/options.c	2008-12-08 22:56:18 UTC (rev 24334)
@@ -224,9 +224,8 @@
 			option[OPT_LEN] = len;
 			if (BB_BIG_ENDIAN)
 				data <<= 8 * (4 - len);
-			/* This memcpy is for processors which can't
-			 * handle a simple unaligned 32-bit assignment */
-			memcpy(&option[OPT_DATA], &data, 4);
+			/* Assignment is unaligned! */
+			move_to_unaligned32(&option[OPT_DATA], data);
 			return add_option_string(optionptr, option);
 		}
 	}

Modified: trunk/busybox/networking/udhcp/script.c
===================================================================
--- trunk/busybox/networking/udhcp/script.c	2008-12-08 19:57:16 UTC (rev 24333)
+++ trunk/busybox/networking/udhcp/script.c	2008-12-08 22:56:18 UTC (rev 24334)
@@ -90,19 +90,19 @@
 			dest += sprintf(dest, "%u", *option);
 			break;
 		case OPTION_U16:
-			memcpy(&val_u16, option, 2);
+			move_from_unaligned16(val_u16, option);
 			dest += sprintf(dest, "%u", ntohs(val_u16));
 			break;
 		case OPTION_S16:
-			memcpy(&val_s16, option, 2);
+			move_from_unaligned16(val_s16, option);
 			dest += sprintf(dest, "%d", ntohs(val_s16));
 			break;
 		case OPTION_U32:
-			memcpy(&val_u32, option, 4);
+			move_from_unaligned32(val_u32, option);
 			dest += sprintf(dest, "%lu", (unsigned long) ntohl(val_u32));
 			break;
 		case OPTION_S32:
-			memcpy(&val_s32, option, 4);
+			move_from_unaligned32(val_s32, option);
 			dest += sprintf(dest, "%ld", (long) ntohl(val_s32));
 			break;
 		case OPTION_STRING:
@@ -183,7 +183,7 @@
 		/* Fill in a subnet bits option for things like /24 */
 		if (dhcp_options[i].code == DHCP_SUBNET) {
 			uint32_t subnet;
-			memcpy(&subnet, temp, 4);
+			move_from_unaligned32(subnet, temp);
 			envp[j++] = xasprintf("mask=%d", mton(subnet));
 		}
  next:

Modified: trunk/busybox/networking/udhcp/serverpacket.c
===================================================================
--- trunk/busybox/networking/udhcp/serverpacket.c	2008-12-08 19:57:16 UTC (rev 24333)
+++ trunk/busybox/networking/udhcp/serverpacket.c	2008-12-08 22:56:18 UTC (rev 24334)
@@ -103,7 +103,8 @@
 {
 	struct dhcpMessage packet;
 	struct dhcpOfferedAddr *lease = NULL;
-	uint32_t req_align, lease_time_align = server_config.lease;
+	uint32_t req_align;
+	uint32_t lease_time_aligned = server_config.lease;
 	uint8_t *req, *lease_time;
 	struct option_set *curr;
 	struct in_addr addr;
@@ -120,7 +121,7 @@
 		lease = find_lease_by_chaddr(oldpacket->chaddr);
 		if (lease) {
 			if (!lease_expired(lease))
-				lease_time_align = lease->expires - time(0);
+				lease_time_aligned = lease->expires - time(0);
 			packet.yiaddr = lease->yiaddr;
 		/* Or the client has a requested ip */
 		} else if ((req = get_option(oldpacket, DHCP_REQUESTED_IP))
@@ -155,22 +156,22 @@
 		}
 		lease_time = get_option(oldpacket, DHCP_LEASE_TIME);
 		if (lease_time) {
-			memcpy(&lease_time_align, lease_time, 4);
-			lease_time_align = ntohl(lease_time_align);
-			if (lease_time_align > server_config.lease)
-				lease_time_align = server_config.lease;
+			move_from_unaligned32(lease_time_aligned, lease_time);
+			lease_time_aligned = ntohl(lease_time_aligned);
+			if (lease_time_aligned > server_config.lease)
+				lease_time_aligned = server_config.lease;
 		}
 
 		/* Make sure we aren't just using the lease time from the previous offer */
-		if (lease_time_align < server_config.min_lease)
-			lease_time_align = server_config.lease;
+		if (lease_time_aligned < server_config.min_lease)
+			lease_time_aligned = server_config.lease;
 		/* ADDME: end of short circuit */
 	} else {
 		/* It is a static lease... use it */
 		packet.yiaddr = static_lease_ip;
 	}
 
-	add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_align));
+	add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_aligned));
 
 	curr = server_config.options;
 	while (curr) {
@@ -203,7 +204,7 @@
 	struct dhcpMessage packet;
 	struct option_set *curr;
 	uint8_t *lease_time;
-	uint32_t lease_time_align = server_config.lease;
+	uint32_t lease_time_aligned = server_config.lease;
 	struct in_addr addr;
 
 	init_packet(&packet, oldpacket, DHCPACK);
@@ -211,15 +212,15 @@
 
 	lease_time = get_option(oldpacket, DHCP_LEASE_TIME);
 	if (lease_time) {
-		memcpy(&lease_time_align, lease_time, 4);
-		lease_time_align = ntohl(lease_time_align);
-		if (lease_time_align > server_config.lease)
-			lease_time_align = server_config.lease;
-		else if (lease_time_align < server_config.min_lease)
-			lease_time_align = server_config.lease;
+		move_from_unaligned32(lease_time_aligned, lease_time);
+		lease_time_aligned = ntohl(lease_time_aligned);
+		if (lease_time_aligned > server_config.lease)
+			lease_time_aligned = server_config.lease;
+		else if (lease_time_aligned < server_config.min_lease)
+			lease_time_aligned = server_config.lease;
 	}
 
-	add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_align));
+	add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_aligned));
 
 	curr = server_config.options;
 	while (curr) {
@@ -236,7 +237,7 @@
 	if (send_packet(&packet, 0) < 0)
 		return -1;
 
-	add_lease(packet.chaddr, packet.yiaddr, lease_time_align);
+	add_lease(packet.chaddr, packet.yiaddr, lease_time_aligned);
 	if (ENABLE_FEATURE_UDHCPD_WRITE_LEASES_EARLY) {
 		/* rewrite the file with leases at every new acceptance */
 		write_leases();

Modified: trunk/busybox/networking/zcip.c
===================================================================
--- trunk/busybox/networking/zcip.c	2008-12-08 19:57:16 UTC (rev 24333)
+++ trunk/busybox/networking/zcip.c	2008-12-08 22:56:18 UTC (rev 24334)
@@ -279,7 +279,8 @@
 	// NOTE: the sequence of addresses we try changes only
 	// depending on when we detect conflicts.
 	{
-		uint32_t t = get_unaligned_u32p((uint32_t *) ((char *)&eth_addr + 2));
+		uint32_t t;
+		move_from_unaligned32(t, ((char *)&eth_addr + 2));
 		srand(t);
 	}
 	if (ip.s_addr == 0)

Modified: trunk/busybox/util-linux/volume_id/linux_raid.c
===================================================================
--- trunk/busybox/util-linux/volume_id/linux_raid.c	2008-12-08 19:57:16 UTC (rev 24333)
+++ trunk/busybox/util-linux/volume_id/linux_raid.c	2008-12-08 22:56:18 UTC (rev 24334)
@@ -62,7 +62,7 @@
 	if (mdp->md_magic != cpu_to_le32(MD_MAGIC))
 		return -1;
 
-	memcpy(uuid, &mdp->set_uuid0, 4);
+	*(uint32_t*)uuid = mdp->set_uuid0;
 	memcpy(&uuid[4], &mdp->set_uuid1, 12);
 	volume_id_set_uuid(id, uuid, UUID_DCE);
 




More information about the busybox-cvs mailing list