Date: Wed, 22 Aug 2012 02:55:54 GMT From: Bruce Evans <bde@FreeBSD.org> To: freebsd-hackers@FreeBSD.org, jhb@FreeBSD.org Cc: freebsd-net@FreeBSD.org, mitya@cabletv.dp.ua Subject: Re: Replace bcopy() to update ether_addr Message-ID: <201208220255.q7M2tsxa020280@ref10-i386.freebsd.org> In-Reply-To: <201208210943.08341.jhb@freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
jhb wrote: > On Monday, August 20, 2012 10:46:12 am Mitya wrote: > > ... > > I propose this solution. > > > > In file /usr/src/include/net/ethernet.h add this lines: > > > > static inline void ether_addr_copy(ether_addr* src, ether_addr* dst) { > > #if defined(__i386__) || defined(__amd64__) > > *dst = *src; > > #else > > bcopy(src, dst, ETHER_ADDR_LEN); > > #endif > > } > > Doesn't '*dst = *src' just work on all platforms? It does when you have an actual struct, but often in networking code you only have an array of bytes, and then casting the pointers from uint8_t * to full object pointers fails iff there is an alignment problem. Even on i386, it may be pessimal to use struct copying for 6 bytes, The bytes should be copied as 4+2 or 2+4 depending on alignment of the first bytes. Oops, not even that -- this reminds me of a problem with penalties for mismatched loads and stores which affects at least AthlonXP and Athlon64 significantly (10-20 cycle penalty = enough to copy 80-160 bytes unpenalized). The 6 should probably be copied as 2+2+2 or even as 1+1+1+1+1+1 to match previous stores and later loads, also as 2+2+2, etc. But if the 6 are part of another struct, they might be accessed as 8+0 or 4+4 as part of copying the full struct. gcc is not smart about this. Bruce
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201208220255.q7M2tsxa020280>