Re: Compiling C++ modules



Dmitry Torokhov wrote:
No, it's optimized out. gcc notices that &lock doesn't change and that
'l' never escapes the function.

"l" that propects critical section gets thrown away???
Calm down, the storage for 'l' is thrown away, but its effects remain.

Would you mind explaining implemenation details a little bit?
(I don't know how familiar you are with C++ so I'm explaining it from the basics, apologies if I'm repeating things you know)

Very often one needs to acquire a resource, do something with it, and then free the resource. Here, "resource" can mean a file descriptor, a reference into a reference counted object, or, in our case, a spinlock. And we want "free" to mean "free no matter what", e.g. on a normal path or an exception path.

In C++, you code it as a guard object:

struct spinlock_guard {
spinlock_guard(spinlock_t *lock) { sl = lock; spin_lock(sl); }
~spinlock_guard() { spin_unlock(sl); }

spinlock_t *sl;
};

(this would be coded differently, trying to keep it C-like)

To use it, create a spinlock_guard object that goes into scope before you use the data you want to protect:

spinlock_t some_lock.;

void f()
{
blah();
spinlock_guard guard(&some_lock);
__f(); /* do nonatomic stuff */
if (__g())
return;
__h()
}

C++ treats this as if you've written:

spinlock_t some_lock;

void f()
{
spinlock_guard guard;

blah();
guard.sl = &some_lock;
spin_lock(guard.sl);
__f();
if (__g())
goto out;
__h();
out:
spin_unlock(guard.sl);
}

Additionally, C++ guarantees that if an exception is thrown after spin_lock() is called, then the spin_unlock() will also be called. That's an interesting mechanism by itself.

Now, the optimizer sees that guard.sl is a constant expression (&some_lock), and that guard.sl's address is not passed to any function, so it eliminates the variable entirely, leaving us with


spinlock_t some_lock;

void f()
{
blah();
spin_lock(&some_lock);
__f();
if (__g())
goto out;
__h();
out:
spin_unlock(&some_lock);
}

(the original C++ compiler actually worked by writing out the C code and letting the C compiler compile it; nowadays both compilers use the same intermediate representation, optimizer, and code generator).

--
Do not meddle in the internals of kernels, for they are subtle and quick to panic.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



Relevant Pages

  • Re: fields for methods?
    ... void A::foo{ ... but only by a compiler that is allowed to ... int static_instance i = 0; ... it totally breaks the idea of encapsulation, which is the reason a lot ...
    (comp.programming)
  • Re: HLA v2.x and / or LASM suggestion: Win32 Resources
    ... > With Microsoft's RC compiler, I've just noticed that it's less capable ... > binary resource converted into readable, ... selecting the particular assembler syntax you want to output for. ... > are using that RC compiler via HLA or whatever;)... ...
    (alt.lang.asm)
  • HLA v2.x and / or LASM suggestion: Win32 Resources
    ... With Microsoft's RC compiler, I've just noticed that it's less capable ... binary resource converted into readable, ... possible to create an icon or bitmap on-the-fly in the actual program ... make a separate tool and then all of them can share ...
    (alt.lang.asm)
  • Re: fields for methods?
    ... but only by a compiler that is allowed to ... struct A {void foo();}; ... int static_instance i = 0; ... Is not possible because foo is the only member of A... ...
    (comp.programming)
  • Re: Calling a matlab dll in java
    ... I compiled it with mcc to dll shared library ... all compiler and linker options in VS took me a while, ... JNIEXPORT void JNICALL Java_JNITest_JNITest_initializeApplication ... public void launchThread() ...
    (comp.soft-sys.matlab)

Loading