Thread protection for overloaded operator

Although the standard does not guarantee thread safety for new , most multithreaded operating systems support thread-safe operator new .

I use my own memory management to dynamically allocate a specific class (say MyClass ) in my code. For the security of MyClass threads, I may need the pthread or boost:: library.

I thought that if new is already thread safe, then I can overload it for MyClass and use its security without worrying about using these libraries.

 class MyClass { // data public: void* operator new (size_t); void operator delete (void*); }; 

Is this a fair assumption for C ++ 03 / compiler systems?

Change Since my question is not accompanied by multiple users. I will detail this part:

If I have 2 threads that do new int() and new int() , then 2 unique memory addresses will be returned. Now in my overloaded MyClass::new I do not use global ::new() or any thread library; but its own memory manager (which knows nothing about threads). Pseudocode:

 char pool[BIG_SIZE]; void* MyClass::operator new (size_t size) { // get some memory from 'pool' without using any thread library return p; } 

My assumption is that global ::new is thread safe, this overloaded operator new should also be thread safe. In other words, the compiler must emit the code associated with the stream wherever it encounters the new keyword. Is this the correct assumption?

+4
source share
3 answers

It.

However, note that in C ++ 11 new is thread safe.

Of course, when you add unsafe thread code, it makes your operator new thread unsafe.

After your editing (which changed the whole question):

The assumption that the compiler adds thread safety code around a new call is pretty wrong. The implementation of Sane will always ensure thread safety in the internal implementation of the new operator (already for performance reasons, such as memory pools for threads).

That is, when you write an unsafe function of thread allocation, simply calling it operator new will not magically make it thread safe, since it is just like any other function, only with a special way to call it.

+2
source

I think with your edited question, the answer will be a definite "No".

You are also confused about new operators and new expressions (there is no such thing as ::new() , there are only ::new and ::operator new() ), so it might be best to break this.

When you write T * p = new T; , where T has an overloaded operator-new, then a sequence equivalent to the following occurs:

 void * addr = T::operator new(sizeof(T)); // #1 ::new (addr) T; // global placement-new 

A function call in # 1 matters. Is this call thread safe? Well, it totally depends on how you define this function! There is nothing in the standard that guarantees any particular behavior of this function, which in the end is a completely normal function.

The only thing that the standard (or new), or the compiler provider, is that the global function void * ::operator new(std::size_t) throw(std::bad_alloc); provided by default is thread safe. Therefore, if you write your own function using this, you are fine; otherwise you yourself:

 struct Foo { static void * operator new(size_t n) { return ::operator new(n); } // OK }; struct Bar { static void * operator new(size_t n) { horribly_broken_function(); return 0x0505; } // probably not OK } 
+1
source

From the updated question:

My assumption is that since global :: new is thread safe, this overloaded new operator should also be thread safe. In other words, the compiler must emit code associated with the stream wherever it encounters a new keyword. Is this a correct guess?

No.

Or, yes, in the banal sense, that it is important for all the code that the compiler generates, namely, that the compiler is not allowed to enter races of data that were not in the source code (in principle, the previous wording found in the C ++ 11 memory model , but in practice it doesn’t matter that C ++ 98 compilers that support threads follow it, because otherwise it would be impossible to create reliable threading programs)

The IOW compiler helps you create thread-safe code to the extent that it will not create thread-safe code that you write insecurely. However, this does not happen otherwise; there is no pixie magic dust that the compiler can sprinkle on top of your insecure code to make it thread safe.

Another explanation is specifically for. new operator, copied with the comments "nm":

MyClass :: operator new is just a regular function with somewhat weird syntax. It is not associated with any new :: operator of the new variant and does not magically inherit their thread safety

or the same from Kerrek SB:

Like n.m. above, I am not following your question - an overloaded operator is just an ordinary (static) member function. It is as good or bad as you do! If the memory in your operator uses :: operator new (n); then this particular call is thread safe and you have to do the rest thread-safe, too

In truth, it’s hard for me to understand what is still unclear.

0
source

All Articles