[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