[PATCH] smbstatus doesn't show lease info

Ralph Boehme rb at sernet.de
Tue Oct 13 09:27:50 UTC 2015


On Mon, Oct 12, 2015 at 12:53:35PM -0700, Jeremy Allison wrote:
> On Mon, Oct 12, 2015 at 09:45:20PM +0200, Ralph Boehme wrote:
> > On Mon, Oct 12, 2015 at 09:59:05AM -0700, Jeremy Allison wrote:
> > > On Mon, Oct 12, 2015 at 01:17:59PM +0200, Ralph Boehme wrote:
> > > > Hi,
> > > > 
> > > > attached is a fix for bug 11549.
> > > > 
> > > > Please review & push if ok. Thanks!
> > > 
> > > I think you should have a helper variable
> > > here to make it more efficient (this is used
> > > in may other places in the code).
> > > 
> > > How about the attached instead ?
> > 
> > sure, if you prefer. But I doubt this makes a difference for a decent
> > optimizing compiler.
> 
> I used to believe that too... But lots of Volkers
> experiments have convinced me otherwise :-).

:) So let's do another experiment. As we'd never know without looking
at the generated machine code, I did just that.

Test program attached. The code tries to ensure the compiler can't
optimize some parts away.

One function func1 loops through a struct array inside another struct,
modifying two member variables without a helper variable

Another function func2 uses a helper variable for the indirection.

/* Helper function */
static int __attribute__ ((noinline)) foo(int n)
{
        static int state;

        state += n;
        return state;
}

static void __attribute__ ((noinline)) func1(struct a *a, int loop, int num_struct)
{
        int i, j;

        for (i = 0; i < loop; i++) {
                for (j = 0; j < num_struct; j++) {
                        a->b[j].n1 = i * foo(i);
                        a->b[j].n2 = j * foo(j);
                }
        }
}

static void __attribute__ ((noinline)) func2(struct a *a, int loop, int num_struct)
{
        int i, j;

        for (i = 0; i < loop; i++) {
                for (j = 0; j < num_struct; j++) {
                        struct b *b = &a->b[j];
                        b->n1 = i * foo(i);
                        b->n2 = j * foo(j);
                }
        }
}

Both functions generate slightly different machine code with gcc -O3:

(gdb) disassemble func1
Dump of assembler code for function func1:
   0x0000000000400890 <+0>:     push   %r15
   0x0000000000400892 <+2>:     push   %r14
   0x0000000000400894 <+4>:     mov    %esi,%r14d
   0x0000000000400897 <+7>:     push   %r13
   0x0000000000400899 <+9>:     push   %r12
   0x000000000040089b <+11>:    xor    %r12d,%r12d
   0x000000000040089e <+14>:    test   %esi,%esi
   0x00000000004008a0 <+16>:    push   %rbp
   0x00000000004008a1 <+17>:    mov    %rdi,%r13
   0x00000000004008a4 <+20>:    push   %rbx
   0x00000000004008a5 <+21>:    jle    0x4008fe <func1+110>
   0x00000000004008a7 <+23>:    nopw   0x0(%rax,%rax,1)
   0x00000000004008b0 <+32>:    xor    %ebp,%ebp
   0x00000000004008b2 <+34>:    xor    %ebx,%ebx
   0x00000000004008b4 <+36>:    nopl   0x0(%rax)
   0x00000000004008b8 <+40>:    mov    %rbp,%r15
   0x00000000004008bb <+43>:    mov    %r12d,%edi
   0x00000000004008be <+46>:    add    0x0(%r13),%r15
   0x00000000004008c2 <+50>:    callq  0x400800 <foo>
   0x00000000004008c7 <+55>:    imul   %r12d,%eax
   0x00000000004008cb <+59>:    mov    %ebx,%edi
   0x00000000004008cd <+61>:    mov    %eax,(%r15)
   0x00000000004008d0 <+64>:    mov    %rbp,%r15
   0x00000000004008d3 <+67>:    add    0x0(%r13),%r15
   0x00000000004008d7 <+71>:    callq  0x400800 <foo>
   0x00000000004008dc <+76>:    imul   %ebx,%eax
   0x00000000004008df <+79>:    add    $0x1,%ebx
   0x00000000004008e2 <+82>:    add    $0x208,%rbp
   0x00000000004008e9 <+89>:    cmp    $0x3e8,%ebx
   0x00000000004008ef <+95>:    mov    %eax,0x4(%r15)
   0x00000000004008f3 <+99>:    jne    0x4008b8 <func1+40>
   0x00000000004008f5 <+101>:   add    $0x1,%r12d
   0x00000000004008f9 <+105>:   cmp    %r14d,%r12d
   0x00000000004008fc <+108>:   jne    0x4008b0 <func1+32>
   0x00000000004008fe <+110>:   pop    %rbx
   0x00000000004008ff <+111>:   pop    %rbp
   0x0000000000400900 <+112>:   pop    %r12
   0x0000000000400902 <+114>:   pop    %r13
   0x0000000000400904 <+116>:   pop    %r14
   0x0000000000400906 <+118>:   pop    %r15
   0x0000000000400908 <+120>:   retq   
End of assembler dump.

(gdb) disassemble func2
Dump of assembler code for function func2:
   0x0000000000400810 <+0>:     push   %r15
   0x0000000000400812 <+2>:     push   %r14
   0x0000000000400814 <+4>:     mov    %esi,%r14d
   0x0000000000400817 <+7>:     push   %r13
   0x0000000000400819 <+9>:     push   %r12
   0x000000000040081b <+11>:    xor    %r12d,%r12d
   0x000000000040081e <+14>:    test   %esi,%esi
   0x0000000000400820 <+16>:    push   %rbp
   0x0000000000400821 <+17>:    mov    %rdi,%r13
   0x0000000000400824 <+20>:    push   %rbx
   0x0000000000400825 <+21>:    jle    0x400876 <func2+102>
   0x0000000000400827 <+23>:    nopw   0x0(%rax,%rax,1)
   0x0000000000400830 <+32>:    xor    %r15d,%r15d
   0x0000000000400833 <+35>:    xor    %ebx,%ebx
   0x0000000000400835 <+37>:    nopl   (%rax)
   0x0000000000400838 <+40>:    mov    %r15,%rbp
   0x000000000040083b <+43>:    mov    %r12d,%edi
   0x000000000040083e <+46>:    add    0x0(%r13),%rbp
   0x0000000000400842 <+50>:    callq  0x400800 <foo>
   0x0000000000400847 <+55>:    imul   %r12d,%eax
   0x000000000040084b <+59>:    mov    %ebx,%edi
   0x000000000040084d <+61>:    add    $0x208,%r15
   0x0000000000400854 <+68>:    mov    %eax,0x0(%rbp)
   0x0000000000400857 <+71>:    callq  0x400800 <foo>
   0x000000000040085c <+76>:    imul   %ebx,%eax
   0x000000000040085f <+79>:    add    $0x1,%ebx
   0x0000000000400862 <+82>:    cmp    $0x3e8,%ebx
   0x0000000000400868 <+88>:    mov    %eax,0x4(%rbp)
   0x000000000040086b <+91>:    jne    0x400838 <func2+40>
   0x000000000040086d <+93>:    add    $0x1,%r12d
   0x0000000000400871 <+97>:    cmp    %r14d,%r12d
   0x0000000000400874 <+100>:   jne    0x400830 <func2+32>
   0x0000000000400876 <+102>:   pop    %rbx
   0x0000000000400877 <+103>:   pop    %rbp
   0x0000000000400878 <+104>:   pop    %r12
   0x000000000040087a <+106>:   pop    %r13
   0x000000000040087c <+108>:   pop    %r14
   0x000000000040087e <+110>:   pop    %r15
   0x0000000000400880 <+112>:   retq   
End of assembler dump.

One mov and one add less in func2. You won! :)

Cheerio!
-slow

-- 
SerNet GmbH, Bahnhofsallee 1b, 37081 Göttingen
phone: +49-551-370000-0, fax: +49-551-370000-9
AG Göttingen, HRB 2816, GF: Dr. Johannes Loxen
http://www.sernet.de,mailto:kontakt@sernet.de
-------------- next part --------------
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>

#define ARRAY_SIZE 1000

struct b {
	int n1, n2;
	/* struct b must not fit in a cache line */
	char c[512];
};

struct a {
	int b_count;
	struct b *b;
};

static int __attribute__ ((noinline)) foo(int n)
{
	static int state;

	state += n;
	return state;
}

static void __attribute__ ((noinline)) func1(struct a *a, int loop, int num_struct)
{
	int i, j;

	for (i = 0; i < loop; i++) {
		for (j = 0; j < num_struct; j++) {
			a->b[j].n1 = i * foo(i);
			a->b[j].n2 = j * foo(j);
		}
	}
}

static void __attribute__ ((noinline)) func2(struct a *a, int loop, int num_struct)
{
	int i, j;

	for (i = 0; i < loop; i++) {
		for (j = 0; j < num_struct; j++) {
			struct b *b = &a->b[j];
			b->n1 = i * foo(i);
			b->n2 = j * foo(j);
		}
	}
}

static void func3(struct a *a, int n)
{
	int i = n % ARRAY_SIZE;

	printf("b[%d]: %d, %d\n", i, a->b[i].n1, a->b[i].n2);
}

int main(int argc, char **argv)
{
	int loop;
	int num_struct = ARRAY_SIZE;
	struct a *a;
	int func;

	if (argc != 3) {
		printf("usage: %s 1|2 N\n", argv[0]);
		return 1;
	}

	func = atoi(argv[1]);
	if (func != 1 && func != 2) {
		printf("usage: %s 1|2 N\n", argv[0]);
		return 1;
	}
	printf("calling func %d\n", func);

	loop = atoi(argv[2]);
	printf("looping %d times\n", loop);

	a = calloc(1, sizeof(struct a));
	if (a == NULL) {
		perror("calloc");
		return 2;
	}

	a->b = calloc(num_struct, sizeof(struct b));

	if (func == 1) {
		func1(a, loop, num_struct);
	} else {
		func2(a, loop, num_struct);
	}

	/*
	 * Do something with struct a, otherwise gcc optimizes it all
	 * away.
	 */
	srandom((unsigned int)time(NULL));
	func3(a, random());

	return 0;
}


More information about the samba-technical mailing list