On Tue, Jan 27, 2015 at 11:15:06AM +0100, Denys Vlasenko wrote: > On Mon, Jan 26, 2015 at 6:13 PM, Tim Hentenaar <[email protected]> wrote: > > Hi Denys, > > > > On Sun, Jan 25, 2015 at 09:58:50PM +0100, Denys Vlasenko wrote: > >> I don't understand why current code does not reach write_leases(). > >> If tv.tv_sec is negative, we should not reach select() here - > >> > >> retval = 0; > >> if (!server_config.auto_time || tv.tv_sec > 0) { > >> retval = select(max_sock + 1, &rfds, NULL, NULL, > >> server_config.auto_time ? &tv : > >> NULL); > >> } > >> if (retval == 0) { > >> write_leases(); > >> goto continue_with_autotime; > >> } > >> > >> and therefore, retval == 0 and we should reach write_leases(). > >> > >> What am I missing? > > > > I wondered the same thing at first. Here's the relevent code as > > generated by GCC. Interestingly, the "tv_sec > 0" check seems to get > > optimized out (I'm compiling with -O2), and select() gets called as long > > as tv_sec is non-zero. Looks almost as if it's treating tv_sec as > > unsigned... > > Can't be, "v > 0" is a valid test even for unsigned types. > > Can you run "make networking/udhcp/dhcpd.s" and post the resulting file? > I'm seeing this code with gcc 4.3.1:
Of course. In your case, with 32-bit code it seems fine.
But, I still see the same incorrect comparison:
.L88:
xorl %r8d, %r8d # iftmp.12
.L87:
movq (%rsp), %rsi # %sfp,
leal 1(%rbx), %edi #, D.9843
xorl %ecx, %ecx #
xorl %edx, %edx #
call select@PLT #
testl %eax, %eax # retval
jne .L182 #,
.L179:
call write_leases #
.p2align 4,,6
jmp .L83 #
.L86:
.p2align 4,,8
call monotonic_sec #
movl 24(%rsp), %ecx # %sfp, D.9844
movl 52+bb_common_bufsiz1(%rip), %r14d # MEM[(struct
server_config_t * {ref-all})&bb_common_bufsiz1].auto_time,
movq $0, 88(%rsp) #, tv.tv_usec
subl %eax, %ecx # D.9836, D.9844
testl %r14d, %r14d #
movq %rcx, 80(%rsp) # D.9844, tv.tv_sec
je .L88 #,
testq %rcx, %rcx # D.9844
je .L179 #,
leaq 80(%rsp), %r8 #, iftmp.12
jmp .L87 #
Are you using a 32-bit x86 arch? If not, what do you get if you compile
it in 64-bit mode?
I wonder why at -O2 it generates je here instead of jle. The ops would
be the same size and speed. At -Os, and -O0 it generates the correct
instruction.
At -Os:
.L78:
xorl %r8d, %r8d # iftmp.12
cmpl $0, 52+bb_common_bufsiz1(%rip) #, MEM[(struct server_config_t
* {ref-all})&bb_common_bufsiz1].auto_time
je .L79 #,
cmpq $0, 80(%rsp) #, tv.tv_sec
jle .L170 #,
At -O0:
.L59:
movl $0, 32(%rsp) #, retval
leaq bb_common_bufsiz1(%rip), %rax #, bb_common_bufsiz1.62
movl 52(%rax), %eax # MEM[(struct server_config_t *
{ref-all})bb_common_bufsiz1.62_111].auto_time, D.8648
testl %eax, %eax # D.8648
je .L60 #,
movq 144(%rsp), %rax # tv.tv_sec, D.8656
testq %rax, %rax # D.8656
jle .L61 #,
I even wrote a small test case to see if I could reproduce this behavior
with a smaller body of code, to no avail.
Tim
pgprs0ZtBHMOV.pgp
Description: PGP signature
_______________________________________________ busybox mailing list [email protected] http://lists.busybox.net/mailman/listinfo/busybox
