On Tue, Jan 27, 2015 at 11:15:06AM +0100, Denys Vlasenko wrote: > On Mon, Jan 26, 2015 at 6:13 PM, Tim Hentenaar <t...@hentenaar.com> 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 busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox