Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Linux Kernel Device Driver With C and C++

Reply
Thread Tools

Linux Kernel Device Driver With C and C++

 
 
Andrew Cooper
Guest
Posts: n/a
 
      11-03-2012
On 02/11/2012 22:45, James Kuyper wrote:
> On 11/02/2012 06:05 PM, Andrew Cooper wrote:
>> On a technical note, your chances of getting C++ working at all as a
>> kernel module is virtually 0. You certainly wont be able to do
>> exceptions or RTTI, and I cant offhand think of a way you would
>> implement even the simple things like global constructors/destructors.
>> On top of that, you will not have any libraries, and good luck using the
>> kernel internal headers with C++ (given all of the C-only syntax they use).

>
> Ordinarily, I'd expect that if I used a C++ compiler essential as if it
> were C compiler - using only features that C++ shares with C, and using
> them only in ways that have the same meaning in C as in C++, and making
> appropriate use of extern "C" - that it shouldn't be a problem.
> However, your comment about "C-only syntax" would suggest otherwise.
> What specific types of syntax are you referring to? Are these C90
> features that were dropped in C99, such as implicit int, or C99 features
> which have not yet been added to C++, such as restrict, or C features
> that were never supported in C++, but which few sane C programmers have
> voluntarily used for at least a decade, such as non-prototyped function
> declarations, or something else?


I was thinking of C99 struct initializer syntax which is invalid in C++,
although thinking about it, I am failing to think of any Linux examples
offhand. (The Xen headers are full of useful macros, such as the
spinlock ones, which wrap this functionality.)

However, the Linux headers certainly do have variables called 'new' in
prototypes and structure declarations, which are sure to spoil the day
of any well meaning C++ compiler.

>
> When I think of how C++ differs from C, ctors and dtors are an important
> part of it, but I also think about member functions, inheritance,
> (single and multiple), function overloading, operator overloads,
> template classes. template functions, member access restrictions,
> virtual members, and virtual inheritance. Do any of these features cause
> problems for kernal programming? Most of these features can be emulated
> in C code; which is in fact how the earliest C++ compilers were
> implemented, which is why I'd be surprised if they were problematic. If
> they are, would the corresponding C code be equally problematic?
>


Local static variables and global ctors and dtors require runtime
support, and the usual trick for c/dtors of trying to play section magic
to make this happen would require you to roll your own linked kernel
module rather than using the regular Kbuild system.

Local c/dtors are fine, as are most of the of the other language
features you list from a "it will compile" standpoint (other than
needing a symbol to link against for pure virtual calls)

A lot of these feature can be emulated in C code, and one could argue
that certain design patterns in the kernel are moving closer towards a
C++ way of thinking, most notably the PVOPS code looks very much like
virtual inheritance.


There are issues which arise from the C++ mentality. In code where
brevity and cache alignment is key for performance, the concept of
private member variables is unhelpful. The concept of inheritance tends
to lump some X along with something Y which is half-similar, but this is
not a data pattern commonly encountered. I am struggling to think of a
single situation where operator overloading would be useful, or indeed
clear in its context, given the typical data us.

And from a technical viewpoint, templates are fantastically bad for
compiled code and data size, typically making N identical or almost
identical copies of each different instantiation. Constructing objects
in C++ is far more work than making a new stuct in C, especially if
there is any inheritance involved. Optimising C++ is harder than
optimising C; The compiler, in general, cannot inline even the most
simple one-line virtual function call.


So overall, (other than the inclusion problem), excluding the C++
features which require runtime support, you can get a working solution.
However, because of the differences between C and C++, there is a large
difference between working and working well.

Don't get me wrong - there are times and places for both C and C++ and I
use both frequently, but in my opinion, a kernel is not a place for C++.

~Andrew
 
Reply With Quote
 
 
 
 
Jorgen Grahn
Guest
Posts: n/a
 
      11-03-2012
On Fri, 2012-11-02, Edward A. Falk wrote:
> In article <(E-Mail Removed)>,
> Angel <(E-Mail Removed)> wrote:
>>
>>Try this site:
>>http://kernelnewbies.org/
>>
>>Just a word of warning; Linux kernel development is done in C only and
>>many there are pretty hostile to any suggestions that it should be done
>>in C++.

>
> Good advice. Be aware that kernel programming is a radically different
> environment from user-level programming. Most significantly, there is
> no libc so many of the system services you take for granted in your usual
> programming environment are not available.


That part is not so bad IME. Most of the relevant parts are there. The
irrelevant ones are not, of course; there is no normal file I/O
because there is no normal file system, and so on.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
 
Reply With Quote
 
 
 
 
Jorgen Grahn
Guest
Posts: n/a
 
      11-03-2012
On Sat, 2012-11-03, Andrew Cooper wrote:

[C++ in Linux kernel code]

> There are issues which arise from the C++ mentality.

[...]

There are different C++ mentalities. You seem to be thinking of
heavy-handed object-oriented programming, but that's not the only way
to use the language.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      11-03-2012
On 11/02/2012 10:34 PM, Andrew Cooper wrote:
> On 02/11/2012 22:45, James Kuyper wrote:

....
>> Ordinarily, I'd expect that if I used a C++ compiler essential as if it
>> were C compiler - using only features that C++ shares with C, and using
>> them only in ways that have the same meaning in C as in C++, and making
>> appropriate use of extern "C" - that it shouldn't be a problem.
>> However, your comment about "C-only syntax" would suggest otherwise.
>> What specific types of syntax are you referring to? Are these C90
>> features that were dropped in C99, such as implicit int, or C99 features
>> which have not yet been added to C++, such as restrict, or C features
>> that were never supported in C++, but which few sane C programmers have
>> voluntarily used for at least a decade, such as non-prototyped function
>> declarations, or something else?

....
> However, the Linux headers certainly do have variables called 'new' in
> prototypes and structure declarations, which are sure to spoil the day
> of any well meaning C++ compiler.


Yes, use of C++ reserved identifiers would certainly be a problem.

>> When I think of how C++ differs from C, ctors and dtors are an important
>> part of it, but I also think about member functions, inheritance,
>> (single and multiple), function overloading, operator overloads,
>> template classes. template functions, member access restrictions,
>> virtual members, and virtual inheritance. Do any of these features cause
>> problems for kernal programming? Most of these features can be emulated
>> in C code; which is in fact how the earliest C++ compilers were
>> implemented, which is why I'd be surprised if they were problematic. If
>> they are, would the corresponding C code be equally problematic?
>>

>
> Local static variables and global ctors and dtors require runtime
> support, ...



I've never had to do any kernal programming, so I don't understand what
the relevant restrictions are, or why they exist. What is problematic
about local static variables? They're not specific to C++, so I assume
that the following C code would also be problematic?:

int save_val(int i)
{
static int saved;
int retval = saved;
saved = i;
return retval;
}

> There are issues which arise from the C++ mentality. In code where
> brevity and cache alignment is key for performance, the concept of
> private member variables is unhelpful. The concept of inheritance tends
> to lump some X along with something Y which is half-similar, but this is
> not a data pattern commonly encountered. I am struggling to think of a
> single situation where operator overloading would be useful, or indeed
> clear in its context, given the typical data us.


The built-in C types fall into a number of categories, based upon which
operators work on them: arithmetic types, pointer types, array types,
functions. Operator overloads work best when they make something that is
of class type work like a member of one of those categories: extended
numeric types such as quaternions or arrays, smart pointers, containers,
or function objects. They only lead to confusion when used for other
purposes. I don't imagine there's much need for extended arithmetic
types in kernal programming. However, it seems to me that various kinds
of smart pointers or containers could be useful, unless they can't be
properly implemented. If there's any place where kernel code passes
around function pointers, passing around function objects might be a
reasonable alternative.

> And from a technical viewpoint, templates are fantastically bad for
> compiled code and data size, typically making N identical or almost
> identical copies of each different instantiation.


The point of having a template is that you have code that needs to be
duplicated, depending upon the template's parameters. Properly used, you
shouldn't be able to avoid the duplication by using C (or the C subset
of C++). If there's code that wouldn't have to be duplicated if you were
using C, then in C++ that code should be factored outside of the template.
Of course, not everything that should be done, is done - I've seen that
a lot in C, and now that I've working on a C++ project, I'm seeing the
same thing in C++. But that's due to misuse of templates, not because of
templates themselves.

> ... Constructing objects
> in C++ is far more work than making a new stuct in C, especially if
> there is any inheritance involved.


If you can construct an object in C without much work, you can write C++
code that requires no more work than the C code to construct it; it
will, in general, be the same (or almost the same) code. The only reason
why C++ construction gets more complicated is if you want to make use of
a C++ feature not supported by C, and if you're sane, you only do that
if that feature provides some benefit that justifies the extra work. I
don't see that as justifying an avoidance of C++.


> Optimising C++ is harder than
> optimising C; The compiler, in general, cannot inline even the most
> simple one-line virtual function call.


It's only meaningful to compare optimization of equivalent code. C
doesn't support virtual function calls; the closest equivalent is C
requires use of a function pointer. Can a typical C compiler do any
better of a job inlining calls through function pointers than a C++
compiler can do of inlining virtual function calls?
--
James Kuyper
 
Reply With Quote
 
Andrew Cooper
Guest
Posts: n/a
 
      11-03-2012
On 03/11/2012 13:33, James Kuyper wrote:
>>
>> Local static variables and global ctors and dtors require runtime
>> support, ...

>
>
> I've never had to do any kernal programming, so I don't understand what
> the relevant restrictions are, or why they exist. What is problematic
> about local static variables? They're not specific to C++, so I assume
> that the following C code would also be problematic?:


Sorry - let me be more clear. In an environment you completely control,
adding 'runtime support' for global c/dtors and local static variables
is quite easy (See http://wiki.osdev.org/C++ ). My issue, in this case,
with them is that I cant think of a way of a Linux kernel module adding
its own runtime support (other than bypassing the Kbuild system and
attempting to link it up yourself)

>
> int save_val(int i)
> {
> static int saved;
> int retval = saved;
> saved = i;
> return retval;
> }


There is a difference between how GCC and G++ treat static local
variables. G++ generates extra code to put a mutex around it to prevent
concurrent initialisation, and this is what requires the runtime
support. (Admittedly this is only G++. Other C++ compilers wont, but
best of luck to you trying to compile even the kernel header files

>
>> There are issues which arise from the C++ mentality. In code where
>> brevity and cache alignment is key for performance, the concept of
>> private member variables is unhelpful. The concept of inheritance tends
>> to lump some X along with something Y which is half-similar, but this is
>> not a data pattern commonly encountered. I am struggling to think of a
>> single situation where operator overloading would be useful, or indeed
>> clear in its context, given the typical data us.

>
> The built-in C types fall into a number of categories, based upon which
> operators work on them: arithmetic types, pointer types, array types,
> functions. Operator overloads work best when they make something that is
> of class type work like a member of one of those categories: extended
> numeric types such as quaternions or arrays, smart pointers, containers,
> or function objects.


And this is all perfectly reasonable in userspace, but not in kernel
space. Floating point calculations are to be avoided at almost any
cost, because they are not useful in the vast majority of cases, and
incur extra overhead if the kernel needs to save/restore its own
floating point state as well as that of the tasks it is scheduling.

> ...They only lead to confusion when used for other
> purposes. I don't imagine there's much need for extended arithmetic
> types in kernal programming. However, it seems to me that various kinds
> of smart pointers or containers could be useful, unless they can't be
> properly implemented. If there's any place where kernel code passes
> around function pointers, passing around function objects might be a
> reasonable alternative.


What form of smart pointers? I assume you mean shared_ptr. They are
just a pointer and a reference count. In the C++ world, the refcount
lives with the pointer, while in the kernel, objects needing refcounting
have a ref count in them. The C world has better locality of data in
the cache, while the C++ world also suffers from the same indirection
problem as function pointer objects.

Lets consider the difference between passing a function pointer in C
(which fits in a register, or single word on the stack), with passing a
C++ function pointer object. The C++ function pointer object is
necessarily as large.

How about calling this function pointer? In C, you would load it off
the stack, or from ram, into a register, and 'call's the address in the
register. In C++, you grab a pointer to the function pointer object,
pass it to the operator() function for your object, which deferences the
pointer, finds the function pointer member variable, loads this into a
register and 'call's the address in the register.

So yes - both of these will indeed work, but see the difference between
working and working and working well. One of the worst things a kernel
can do is needlessly follow pointers, as this takes more time, and leads
to cache misses. The C way of doing things results in less memory
overhead, (both in terms of code size and data size), involves fewer
pointers to follow, and has better cache locality.

>
>> And from a technical viewpoint, templates are fantastically bad for
>> compiled code and data size, typically making N identical or almost
>> identical copies of each different instantiation.

>
> The point of having a template is that you have code that needs to be
> duplicated, depending upon the template's parameters. Properly used, you
> shouldn't be able to avoid the duplication by using C (or the C subset
> of C++). If there's code that wouldn't have to be duplicated if you were
> using C, then in C++ that code should be factored outside of the template.
> Of course, not everything that should be done, is done - I've seen that
> a lot in C, and now that I've working on a C++ project, I'm seeing the
> same thing in C++. But that's due to misuse of templates, not because of
> templates themselves.


Agreed, subject to your statement of "Properly used". However, I cant
think of a single case where templates would be useful.

>
>> ... Constructing objects
>> in C++ is far more work than making a new stuct in C, especially if
>> there is any inheritance involved.

>
> If you can construct an object in C without much work, you can write C++
> code that requires no more work than the C code to construct it; it
> will, in general, be the same (or almost the same) code. The only reason
> why C++ construction gets more complicated is if you want to make use of
> a C++ feature not supported by C, and if you're sane, you only do that
> if that feature provides some benefit that justifies the extra work. I
> don't see that as justifying an avoidance of C++.
>
>
>> Optimising C++ is harder than
>> optimising C; The compiler, in general, cannot inline even the most
>> simple one-line virtual function call.

>
> It's only meaningful to compare optimization of equivalent code. C
> doesn't support virtual function calls; the closest equivalent is C
> requires use of a function pointer. Can a typical C compiler do any
> better of a job inlining calls through function pointers than a C++
> compiler can do of inlining virtual function calls?
>


Ok - fair points. As with templates, I cant think of a useful use case
for compound objects. From a naive point of view, virtual functions via
an interface design model could seem very attractive and useful in a
kernel environment. However, a virtual function call is 2 pointers to
follow rather than one, going back to the performance aspect.

The point I was trying to get across is that C++ opens up a whole
toolkit of new and shiny features which are not needed and when used
with the best of intentions lead to poor performance. This alone is the
biggest reason why I believe C++ should not be used.
 
Reply With Quote
 
Öö Tiib
Guest
Posts: n/a
 
      11-03-2012
On Saturday, 3 November 2012 17:44:23 UTC+2, Andrew Cooper wrote:
> On 03/11/2012 13:33, James Kuyper wrote:
> > ...They only lead to confusion when used for other
> > purposes. I don't imagine there's much need for extended arithmetic
> > types in kernal programming. However, it seems to me that various kinds
> > of smart pointers or containers could be useful, unless they can't be
> > properly implemented. If there's any place where kernel code passes
> > around function pointers, passing around function objects might be a
> > reasonable alternative.

>
> What form of smart pointers? I assume you mean shared_ptr.


I expect with "smart_pointer" mentioned that std::unique_ptr is used.
It causes minimal overhead compared to raw pointer (one instruction per
access) but adds lot of clarity and safety.

> They are
> just a pointer and a reference count. In the C++ world, the refcount
> lives with the pointer, while in the kernel, objects needing refcounting
> have a ref count in them. The C world has better locality of data in
> the cache, while the C++ world also suffers from the same indirection
> problem as function pointer objects.


std::shared_ptr? It is truly heavyweight so one should not use it just like
that for everything (like lot of noobs seem to do). It has separate dynamic
object for containing weak_count, shared_count, deleter functor and raw
pointer.

You assign to it also some sins that you think it has but it does not have.
Locality equal to C of that ref-counter object is gained by using
std::make_shared that achieves that both objects are allocated adjacent
in memory with a single malloc.

> Lets consider the difference between passing a function pointer in C
> (which fits in a register, or single word on the stack), with passing a
> C++ function pointer object. The C++ function pointer object is
> necessarily as large.


"Function pointer object"??? You are confused here. Function object, usually
passed by value. The function if it is simple is often inlined by optimizing
compiler to point of usage and the optimization will cause efficiency
gain. That is the reason why std::sort<>() usually outperforms qsort().

In general, noobs needing tutorials should start with something simpler
than writing drivers for OS kernels on any case, neither C nor C++ can
help them enough there.
 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      11-03-2012
On 11/03/2012 11:44 AM, Andrew Cooper wrote:
> On 03/11/2012 13:33, James Kuyper wrote:

....
>> The built-in C types fall into a number of categories, based upon which
>> operators work on them: arithmetic types, pointer types, array types,
>> functions. Operator overloads work best when they make something that is
>> of class type work like a member of one of those categories: extended
>> numeric types such as quaternions or arrays, smart pointers, containers,
>> or function objects.

....
>> ...They only lead to confusion when used for other
>> purposes. I don't imagine there's much need for extended arithmetic
>> types in kernal programming. However, it seems to me that various kinds
>> of smart pointers or containers could be useful, unless they can't be
>> properly implemented.

....
> What form of smart pointers? I assume you mean shared_ptr.


I meant smart pointers in general: any class type that uses operator
overloads to emulate a pointer type, but with extra features added. Any
feature that reduces the likelihood of dereferencing a pointer that
cannot be safely dereferenced, or of producing a memory leak, has some
potential value in user space programming, though it's always a matter o
judgment whether the value is worth the associated cost. Is there no
such feature that would be of any use in kernel programming?
--
James Kuyper
 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      11-03-2012
On 11/04/12 04:44, Andrew Cooper wrote:
> On 03/11/2012 13:33, James Kuyper wrote:
>>
>> The built-in C types fall into a number of categories, based upon which
>> operators work on them: arithmetic types, pointer types, array types,
>> functions. Operator overloads work best when they make something that is
>> of class type work like a member of one of those categories: extended
>> numeric types such as quaternions or arrays, smart pointers, containers,
>> or function objects.

>
> And this is all perfectly reasonable in userspace, but not in kernel
> space. Floating point calculations are to be avoided at almost any
> cost, because they are not useful in the vast majority of cases, and
> incur extra overhead if the kernel needs to save/restore its own
> floating point state as well as that of the tasks it is scheduling.
>
>> ...They only lead to confusion when used for other
>> purposes. I don't imagine there's much need for extended arithmetic
>> types in kernal programming. However, it seems to me that various kinds
>> of smart pointers or containers could be useful, unless they can't be
>> properly implemented. If there's any place where kernel code passes
>> around function pointers, passing around function objects might be a
>> reasonable alternative.

>
> What form of smart pointers? I assume you mean shared_ptr. They are
> just a pointer and a reference count. In the C++ world, the refcount
> lives with the pointer, while in the kernel, objects needing refcounting
> have a ref count in them. The C world has better locality of data in
> the cache, while the C++ world also suffers from the same indirection
> problem as function pointer objects.


In C++, you can choose how you associate the object pointer and the
reference count, so there's no loss of efficiency there. There isn't
any loss with access either (modulo any optional error checking).

> Lets consider the difference between passing a function pointer in C
> (which fits in a register, or single word on the stack), with passing a
> C++ function pointer object. The C++ function pointer object is
> necessarily as large.


If the function pointer object isn't reference counted, it will be the
same size as the equivalent raw pointer.

> How about calling this function pointer? In C, you would load it off
> the stack, or from ram, into a register, and 'call's the address in the
> register. In C++, you grab a pointer to the function pointer object,
> pass it to the operator() function for your object, which deferences the
> pointer, finds the function pointer member variable, loads this into a
> register and 'call's the address in the register.


Er, no. Calling a function pointer compiles to the exact same code a
calling a raw pointer, modulo any optional error checking. The caveat
is important there, with a C++ smart pointer you can globally enable
access checking without an awful lot of messy conditional compilations.

> So yes - both of these will indeed work, but see the difference between
> working and working and working well. One of the worst things a kernel
> can do is needlessly follow pointers, as this takes more time, and leads
> to cache misses. The C way of doing things results in less memory
> overhead, (both in terms of code size and data size), involves fewer
> pointers to follow, and has better cache locality.


In practice, the two techniques have the same overhead.

>> The point of having a template is that you have code that needs to be
>> duplicated, depending upon the template's parameters. Properly used, you
>> shouldn't be able to avoid the duplication by using C (or the C subset
>> of C++). If there's code that wouldn't have to be duplicated if you were
>> using C, then in C++ that code should be factored outside of the template.
>> Of course, not everything that should be done, is done - I've seen that
>> a lot in C, and now that I've working on a C++ project, I'm seeing the
>> same thing in C++. But that's due to misuse of templates, not because of
>> templates themselves.

>
> Agreed, subject to your statement of "Properly used". However, I cant
> think of a single case where templates would be useful.


The case we have just been discussing: resource management.

> The point I was trying to get across is that C++ opens up a whole
> toolkit of new and shiny features which are not needed and when used
> with the best of intentions lead to poor performance. This alone is the
> biggest reason why I believe C++ should not be used.


Any more capable tool used incorrectly can cause you problems. Using
that argument as the justification for not using it is poor reasoning.

I've been countering the same FUD (usually be actually using C++ in
those areas) for more than a decade now in the embedded/driver/kernel
space and I'm amazed it's still being propagated.

--
Ian Collins
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      11-03-2012
Andrew Cooper <(E-Mail Removed)> writes:
> On 03/11/2012 13:33, James Kuyper wrote:

[...]
>> int save_val(int i)
>> {
>> static int saved;
>> int retval = saved;
>> saved = i;
>> return retval;
>> }

>
> There is a difference between how GCC and G++ treat static local
> variables. G++ generates extra code to put a mutex around it to prevent
> concurrent initialisation, and this is what requires the runtime
> support. (Admittedly this is only G++. Other C++ compilers wont, but
> best of luck to you trying to compile even the kernel header files

[...]

I just compiled the above function with both gcc and g++ (version
4.7.0). The generated code was identical apart from a few different
identifiers.

Is there some g++ option that tells it to create a mutex?

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
SG
Guest
Posts: n/a
 
      11-03-2012
Am 03.11.2012 21:22, schrieb Keith Thompson:
> Andrew Cooper <(E-Mail Removed)> writes:
>> On 03/11/2012 13:33, James Kuyper wrote:

> [...]
>>> int save_val(int i)
>>> {
>>> static int saved;
>>> int retval = saved;
>>> saved = i;
>>> return retval;
>>> }

>>
>> There is a difference between how GCC and G++ treat static local
>> variables. G++ generates extra code to put a mutex around it to prevent
>> concurrent initialisation, and this is what requires the runtime
>> support. (Admittedly this is only G++. Other C++ compilers wont, but
>> best of luck to you trying to compile even the kernel header files

> [...]
>
> I just compiled the above function with both gcc and g++ (version
> 4.7.0). The generated code was identical apart from a few different
> identifiers.
>
> Is there some g++ option that tells it to create a mutex?


It does not surprize me that the code is equal. There is no dynamic
initialization of 'saved' going on. What C++11 guarantees is that a
dynamic initialization is thread-safe. But C doesn't even allow this
kind of dynamic initializations. What do I mean by "dynamic
initialization"? Here's a C++ example:

int reverse_increment_256(int j)
{
int bitmask = 128;
while (bitmask) {
j ^= bitmask;
if ((j & bitmask)!=0) break;
bitmask >>= 1;
}
return j;
}

const unsigned char* get_bit_reverse_256_table()
{
static const int* table = []()->unsigned char*{
unsigned char* table = new int[256];
for (int i=0, j=0; i<256; ++i) {
table[i] = j;
j = reverse_increment(j);
}
return table;
}();
return table;
}

(untested)

Here, the initializer of the static variable 'table' is dynamic in the
sense that the function call has to be performed during runtime. C++11
makes sure that this dynamic initialization is properly locked so that
in case the table has not yet been computed and two threads invoke
get_bit_reverse_256_table concurrently, the table is just computed once
properly.

I don't know whether G++ already supports that. Maybe you have to turn
on this behaviour by using -std=c++0x or -std=c++11 .

Cheers!
SG

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Kernel#autoload ignores custom monkey patched Kernel#require Lars Gierth Ruby 6 03-20-2010 10:35 PM
Why "Kernel.puts" and not "Kernel.put"? shadytrees@gmail.com Ruby 3 04-08-2006 01:42 PM
ERROR [HY000] [Microsoft][ODBC Microsoft Access Driver]General error Unable to open registry key 'Temporary (volatile) Jet DSN for process 0x8fc Thread 0x934 DBC 0x437b94 Jet'. ERROR [IM006] [Microsoft][ODBC Driver Manager] Driver's SQLSetConnectAttr bazzer ASP .Net 1 03-24-2006 04:20 PM
ERROR [HY000] [Microsoft][ODBC Microsoft Access Driver]General error Unable to open registry key 'Temporary (volatile) Jet DSN for process 0x8fc Thread 0x934 DBC 0x437b94 Jet'. ERROR [IM006] [Microsoft][ODBC Driver Manager] Driver's SQLSetConnectAttr bazzer ASP .Net 0 03-24-2006 02:22 PM
kernel hangs after "UNCOMPRESSING KERNEL OK BOOTING KERNEL" yogesh C Programming 3 02-12-2006 11:19 AM



Advertisments