Are std::mutex and std::unique_ptr sufficient to guarantee that there will be no concurrent calls to an object? In the following code snippet will Object not have any concurrent calls?
class Example {
public:
std::mutex Mutex;
Example(){...
};
//
private:
static std::unique_ptr<Object> Mutex;
};
No, you would have to lock and unlock the mutex, when you need it. Just the existance of a mutex in no guarantee. Also a unique_ptr cannot change this!
mutex example is in the reference: http://en.cppreference.com/w/cpp/thread/mutex
Const however does now guarantee that nothing can change your object at the same time than you are using the const.
This obviously suppose you use a well coded object (like STL containers) and that no one tried to work around the compiler checks.
See : http://herbsutter.com/2013/01/01/video-you-dont-know-const-and-mutable/
unique_ptr is mainly related with resources management and RAII idiom. You don't need to use unique_ptr to achieve thread safety even in some scenarios it may prove useful. However, the example that you provided is a bit unusual, you used the identifier Mutex twice to indicate a std::mutex and a std::unique_ptr.
I suggest to get some good books on C++ before to dwelve in more complex topics like concurrency and resources management.
This nice article of Diego Dagum explains what is new regarding concurency in C++11
http://msdn.microsoft.com/en-us/magazine/hh852594.aspx
And an article about unique_ptr:
http://www.drdobbs.com/cpp/c11-uniqueptr/240002708
Related
FreeRTOS and ESP-IDF provide xSemaphoreCreateMutex() which allocates and initializes a mutex. Their docs say:
If a mutex is created using xSemaphoreCreateMutex() then the required
memory is automatically dynamically allocated inside the
xSemaphoreCreateMutex() function. (see
http://www.freertos.org/a00111.html).
However, I can't find any info on whether it is necessary to free the memory created by the mutex. This would be important if using C++ with a mutex member variable, like:
class MyClass
{
MyClass::MyClass()
{
mAccessMutex = xSemaphoreCreateMutex();
}
MyClass::~MyClass()
{
// What to do here??
}
SemaphoreHandle_t mAccessMutex;
}
REFERENCE
https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/freertos.html?highlight=xsemaphore#semaphore-api
According to FreeRTOS API reference, the proper way to destroy/delete a mutex is vSemaphoreDelete()
Deletes a semaphore, including mutex type semaphores and recursive
semaphores.
Do not delete a semaphore that has tasks blocked on it.
If you're using heap_1, deleting is not possible. Also, make sure that you fully understand the perils of dynamic memory allocation in embedded systems before using it. If MyClass is going to be created and destroyed in a regular/periodic basis, this may cause problems.
So yes, it's necessary to call vSemaphoreDelete(mAccessMutex) in ~MyClass(). But it's probably best to make sure that MyClass instances never get destroyed. In my projects, I generally use one-time dynamic allocation during initialization and forget to implement a proper destructor (which is a bad habit that I need to fix).
The venerated book Linux Driver Development says that
The flags argument passed to spin_unlock_irqrestore must be the same variable passed to spin_lock_irqsave. You must also call spin_lock_irqsave and spin_unlock_irqrestore in the same function; otherwise your code may break on some architectures.
Yet I can't find any such restriction required by the official documentation bundled with the kernel code itself. And I find driver code that violates this guidance.
Obviously it isn't a good idea to call spin_lock_irqsave and spin_unlock_irqrestore from separate functions, because you're supposed to minimize the work done while holding a lock (with interrupts disabled, no less!). But have changes to the kernel made it possible if done with care, was it never actually against the API contract, or is it still verboten to do so?
If the restriction has been removed at some point, did it apply to version 3.10.17?
This is just a guess, but the might be unclearly referring to a potential bug which could happen if you try to use a nonlocal variable or storage location for flags.
Basically, flags has to be private to the current execution context, which is why spin_lock_irqsave is a macro which takes the name of the flags. While flags is being saved, you don't have the spinlock yet.
How this is related to locking and unlocking in a different function:
Consider two functions that some driver developer might write:
void my_lock(my_object *ctx)
{
spin_lock_irqsave(&ctx->mylock, ctx->myflags); /* BUG */
}
void my_unlock(my_object *ctx)
{
spin_unlock_irqrestore(&ctx->mylock, ctx->myflags);
}
This is a bug because at the time ctx->myflags is written, the lock is not yet held, and it is a shared variable visible to other contexts and processors. The local flags must be saved to a private location on the stack. Then when the lock is owned, by the caller, a copy of the flags can be saved into the exclusively owned object. In other words, it can be fixed like this:
void my_lock(my_object *ctx)
{
unsigned long flags;
spin_lock_irqsave(&ctx->mylock, flag);
ctx->myflags = flags;
}
void my_unlock(my_object *ctx)
{
unsigned long flags = ctx->myflags; /* probably unnecessary */
spin_unlock_irqrestore(&ctx->mylock, flags);
}
If it couldn't be fixed like that, it would be very difficult to implement higher level primitives which need to wrap IRQ spinlocks.
How it could be arch-dependent:
Suppose that spin_lock_irqsave expands into machine code which saves the current flags in some register, then acquires the lock, and then saves that register into specified flags destination. In that case, the buggy code is actually safe. If the expanded code saves the flags into the actual flags object designated by the caller and then tries to acquire the lock, then it's broken.
I have never see that constraint aside from the book. Probably, given information in the book is just outdated, or .. simply wrong.
In the current kernel(and at least since 2.6.32, which I start to work with) actual locking is done through many level of nested calls from spin_lock_irqsave(see, e.g. __raw_spin_lock_irqsave, which is called in the middle). So different function's context for lock and unlock may hardly be a reason for misfunction.
I was watching Bjarne Stroustrup's talk "The Essence of C++".
In 44:26 he mentioned "C++11 specifies a GC Interface".
May I ask what is the interface, and how to implement it?
Any more detailed good introduction online, or some sample codes to demonstrate it pls?
Stroustrup extends this discussion in his C++ FAQ, the thing is that GC usage is optional, library vendors are free to implement one or not :
Garbage collection (automatic recycling of unreferenced regions of
memory) is optional in C++; that is, a garbage collector is not a
compulsory part of an implementation. However, C++11 provides a
definition of what a GC can do if one is used and an ABI (Application
Binary Interface) to help control its actions.
The rules for pointers and lifetimes are expressed in terms of "safely
derived pointer" (3.7.4.3); roughly: "pointer to something allocated
by new or to a sub-object thereof."
to ordinary mortals: [...]
The functions in the C++ standard supporting this (the "interface" to which Stroustrup is referring to) are :
std::declare_reachable
std::undeclare_reachable
std::declare_no_pointers
std::undeclare_no_pointers
These functions are presented in the N2670 proposal :
Its purpose is to support both garbage collected implementations and
reachability-based leak detectors. This is done by giving undefined
behavior to programs that "hide a pointer" by, for example, xor-ing it
with another value, and then later turn it back into an ordinary
pointer and dereference it. Such programs may currently produce
incorrect results with conservative garbage collectors, since an
object referenced only by such a "hidden pointer" may be prematurely
collected. For the same reason, reachability-based leak detectors may
erroneously report that such programs leak memory.
Either your implementation supports "strict pointer safety" in which case implementing a GC is possible, or it has a "relaxed pointer safety" (by default), in which case it is not. You can determine that by looking at the result of std::get_pointer_safety(), if available.
I don't know of any actual standard C++ GC implementation, but at least the standard is preparing the ground for it to happen.
In addition to the good answer by quantdev, which I've upvoted, I wanted to provide a little more information here (which would not fit in a comment).
Here is a C++11 conforming program which demonstrates whether or not an implementation supports the GC interface:
#include <iostream>
#include <memory>
int
main()
{
#ifdef __STDCPP_STRICT_POINTER_SAFETY__
std::cout << __STDCPP_STRICT_POINTER_SAFETY__ << '\n';
#endif
switch (std::get_pointer_safety())
{
case std::pointer_safety::relaxed:
std::cout << "relaxed\n";
break;
case std::pointer_safety::preferred:
std::cout << "preferred\n";
break;
case std::pointer_safety::strict:
std::cout << "strict\n";
break;
}
}
An output of:
relaxed
means that the implementation has a trivial implementation which does nothing at all.
libc++ outputs:
relaxed
VS-2015 outputs:
relaxed
gcc 5.0 outputs:
prog.cc: In function 'int main()':
prog.cc:10:13: error: 'get_pointer_safety' is not a member of 'std'
switch (std::get_pointer_safety())
^
The bottleneck of my current project is heap allocation... profiling stated about 50% of the time one critical thread spends with/in the new operator.
The application cannot use stack memory here and needs to allocate a lot of one central job structure—a custom job/buffer implementation: small and short-lived but variable in size. The object are itself heap memory std::shared_ptr/std::weak_ptr objects and carry a classic C-Array (char*) payload.
Depending on the runtime configuration and workload in different parts 300k-500k object might get created and are in use at the same time (but this should usually not happen). Since its a x64 application memory fragmentation isn't that big a deal (but it might get when also targeted at x86).
To increase speed and packet throughput and as well be save to memory fragmentation in the future I was thinking about using some memory management pool which lead me to boost::pool.
Almost all examples use fixed size object... but I'm unsure how to deal with a variable lengthed payload? A simplified object like this could be created using a boost::pool but I'm unsure what to do with the payload? Is it usable with a boost:pool at all?
class job {
public:
static std::shared_ptr<job> newObj();
private:
delegate_t call;
args_t * args;
unsigned char * payload;
size_t payload_size;
}
Usually the objects are destroyed when all references to the shared_ptr run out of scope and I wouldn't want to change the shared-ptr back to a c-ptr. A deferred destruction of the objects should also work to increase performance and from what I read should work better with a boost:pool. I haven't found if the pool supports an interaction with the smart_ptr? The alternative but quirky way would be to save a reference to the shared_ptr on creation together with the pool and release them in blocks.
Does anyone have experiences with the two? boost:pool usage with variable sized objects and smart pointer interaction?
Thank you!
I'm writing some COM and ATL code, and for some reason all the code uses CoTaskMemAlloc to allocate memory instead of new or malloc. So I followed along this coding style and I also use CoTaskMemAlloc.
My teachers taught me to always delete or free when allocating memory. However I'm not sure if I should always be calling CoTaskMemFree if I use CoTaskMemAlloc?
Using the CRT's provided new/malloc and delete/free is a problem in COM interop. To make them work, it is very important that the same copy of the CRT both allocates and releases the memory. That's impossible to enforce in a COM interop scenario, your COM server and the client are practically guaranteed to use different versions of the CRT. Each using their own heap to allocate from. This causes undiagnosable memory leaks on Windows XP, a hard exception on Vista and up.
Which is why the COM heap exists, a single predefined heap in a process that's used both by the server and the client. IMalloc is the generic interface to access that shared heap, CoTaskMemAlloc() and CoTaskMemFree() are the system provided helper functions to use that interface.
That said, this is only necessary in a case where the server allocates memory and the client has to release it. Or the other way around. Which should always be rare in an interop scenario, the odds for accidents are just too large. In COM Automation there are just two such cases, a BSTR and a SAFEARRAY, types that are already wrapped. You avoid it in other cases by having the method caller provide the memory and the callee fill it in. Which also allows a strong optimization, the memory could come from the caller's stack.
Review the code and check who allocates the memory and who needs to release it. If both exist in the same module then using new/malloc is fine because there's now a hard guarantee that the same CRT instance takes care of it. If that's not the case then consider fixing it so the caller provides the memory and releases it.
The allocation and freeing of memory must always come from the same source. If you use CoTaskMemAlloc then you must use CoTaskMemFree to free the memory.
Note in C++ though the act of managing memory and object construction / destruction (new / delete) are independent actions. It's possible to customize specific objects to use a different memory allocator and still allow for the standard new / delete syntax which is preferred. For example
class MyClass {
public:
void* operator new(size_t size) {
return ::CoTaskMemAlloc(size);
}
void* operator new[](size_t size) {
return ::CoTaskMemAlloc(size);
}
void operator delete(void* pMemory) {
::CoTaskMemFree(pMemory);
}
void operator delete[](void* pMemory) {
::CoTaskMemFree(pMemory);
}
};
Now I can use this type just like any other C++ type and yet the memory will come from the COM heap
// Normal object construction but memory comes from CoTaskMemAlloc
MyClass *pClass = new MyClass();
...
// Normal object destruction and memory freed from CoTaskMemFree
delete pClass;
The answer to the question is: Yes, you should use CoTaskMemFree to free memory allocated with CoTaskMemAlloc.
The other answers do a good job explaining why CoTaskMemAlloc and CoTaskMemFree are necessary for memory passed between COM servers and COM clients, but they didn't directly answer your question.
Your teacher was right: You should always use the corresponding release function for any resource. If you use new, use delete. If you use malloc, use free. If you use CreateFile, use CloseHandle. Etc.
Better yet, in C++, use RAII objects that allocate the resource in the constructor and release the resource in the destructor, and then use those RAII wrappers instead of the bare functions. This makes it easier and cleaner to write code that doesn't leak, even if you get something like an exception.
The standard template library provides containers that implement RAII, which is why you should learn to use a std::vector or std::string rather than allocating bare memory and trying to manage it yourself. There are also smart pointers like std::shared_ptr and std::unique_ptr that can be used to make sure the right release call is always made at the right time.
ATL provides some classes like ATL::CComPtr which are wrapper objects that handle the reference counting of COM objects for you. They are not foolproof to use correctly, and, in fact, have a few more gotchas than most of the modern STL classes, so read the documentation carefully. When used correctly, it's relatively easy to make sure the AddRef and Release calls all match up.