What is PTHREAD_MUTEX_INITIALIZER? - multithreading

I read a lot of articles about PTHREAD_MUTEX_INITIALIZER, I understood what does it do, however, I am unable to understand how does it do that? How a macro can be used to initialize a variable just by assigning its name to that variable?
What I know about macros is that they can be used just as functions, such as:
#define MAX(a, b) ((a) > (b) ? (a) : (b))
Now we can use this macro as a function like Max(a, b).
But how can we write a macro that can be used in the way which PTHREAD_MUTEX_INITIALIZER is used like:
int x = Macro_Name;
Then x will be initialized to a specific value (like when a mutex is initialized once PTHREAD_MUTEX_INITIALIZER is assigned to it).

Here is a snippet from the source code of libpthread, taken from http://git.savannah.gnu.org/cgit/hurd/libpthread.git/tree/sysdeps/pthread/bits/types/struct___pthread_mutex.h (I only removed comments that are irrelevant to the question)
/* User visible part of a mutex. */
struct __pthread_mutex
{
__pthread_spinlock_t __held;
__pthread_spinlock_t __lock;
char *__cthreadscompat1;
struct __pthread *__queue;
struct __pthread_mutexattr *__attr;
void *__data;
void *__owner;
unsigned __locks;
};
# define __PTHREAD_MUTEX_INITIALIZER \
{ __PTHREAD_SPIN_LOCK_INITIALIZER, __PTHREAD_SPIN_LOCK_INITIALIZER, 0, 0, 0, 0, 0, 0 }
From that, it can be seen that the macro hides an initializer list for the structure that represents the "user visible part of a mutex". Most members of the struct (including pointers) are set to 0, and internal spin locks are initialized with their own initializer macro, which is probably defined similarly.
Of course it's just one implementation, but I guess other implementations might have something similar.

Related

Debugging in threading building Blocks

I would like to program in threading building blocks with tasks. But how does one do the debugging in practice?
In general the print method is a solid technique for debugging programs.
In my experience with MPI parallelization, the right way to do logging is that each thread print its debugging information in its own file (say "debug_irank" with irank the rank in the MPI_COMM_WORLD) so that the logical errors can be found.
How can something similar be achieved with TBB? It is not clear how to access the thread number in the thread pool as this is obviously something internal to tbb.
Alternatively, one could add an additional index specifying the rank when a task is generated but this makes the code rather complicated since the whole program has to take care of that.
First, get the program working with 1 thread. To do this, construct a task_scheduler_init as the first thing in main, like this:
#include "tbb/tbb.h"
int main() {
tbb::task_scheduler_init init(1);
...
}
Be sure to compile with the macro TBB_USE_DEBUG set to 1 so that TBB's checking will be enabled.
If the single-threaded version works, but the multi-threaded version does not, consider using Intel Inspector to spot race conditions. Be sure to compile with TBB_USE_THREADING_TOOLS so that Inspector gets enough information.
Otherwise, I usually first start by adding assertions, because the machine can check assertions much faster than I can read log messages. If I am really puzzled about why an assertion is failing, I use printfs and task ids (not thread ids). Easiest way to create a task id is to allocate one by post-incrementing a tbb::atomic<size_t> and storing the result in the task.
If I'm having a really bad day and the printfs are changing program behavior so that the error does not show up, I use "delayed printfs". Stuff the printf arguments in a circular buffer, and run printf on the records later after the failure is detected. Typically for the buffer, I use an array of structs containing the format string and a few word-size values, and make the array size a power of two. Then an atomic increment and mask suffices to allocate slots. E.g., something like this:
const size_t bufSize = 1024;
struct record {
const char* format;
void *arg0, *arg1;
};
tbb::atomic<size_t> head;
record buf[bufSize];
void recf(const char* fmt, void* a, void* b) {
record* r = &buf[head++ & bufSize-1];
r->format = fmt;
r->arg0 = a;
r->arg1 = b;
}
void recf(const char* fmt, int a, int b) {
record* r = &buf[head++ & bufSize-1];
r->format = fmt;
r->arg0 = (void*)a;
r->arg1 = (void*)b;
}
The two recf routines record the format and the values. The casting is somewhat abusive, but on most architectures you can print the record correctly in practice with printf(r->format, r->arg0, r->arg1) even if the the 2nd overload of recf created the record.
~
~

using a for each loop with pointers

First of I have 2 Classes in 2 files (both .h and .cpp files), Create.h and AI.h.
Create.h has this struct in it:
public:
struct Cell
{
//some stuff
vector<Cell*> neighbors;
State state;
};
Here is the enum class State (stored in the Create.h file):
enum class State : char
{
//some states like "empty"
};
Now in AI.cpp I have a function like this:
void AI::Function(Create::Cell cell)
{
for each (Create::Cell* var in cell.neighbors)
{
if (var->state == State::empty)
{
}
}
}
So basically I am trying to access each individual Cell which is stored in cell.neighbors with a for each so I can do some stuff to each one of them.
According to my debugger though it doesn't even reach the if (var->state == State::empty) part. Am I using the for each wrong?
EDIT: The neighbors vector has definitely elements in it
If you are compiling with optimizations enabled, then an empty if statement like that might be completely removed (it has no side-effects).
(Although, I think the debugger won't let you set a breakpoint on that line, if it were removed. So this is an easy test -- try to set a breakpoint on the if itself.)
it seems that the vector is empty. You can check this printing its size before the loop.
And I would like to answer some comments. This form of the for loop is MS VC++ language extension. It is not C++/CLI.

vtk memory management when importing data

I am using vtkImageImport to convert from an opencv matrix to vtkImageData.
vtkImageData* convertImage(const cv::Mat& image)
{
int width = image.cols;
int height = image.rows;
vtkSmartPointer<vtkImageImport> importer = vtkSmartPointer<vtkImageImport>::New();
importer->SetDataScalarTypeToUnsignedChar();
importer->SetImportVoidPointer(image.data);
importer->SetWholeExtent(0,width-1,0, height-1, 0, 0);
importer->SetDataExtentToWholeExtent();
importer->Update();
return importer->GetOutput();
}
I have 2 questions on how pointers and memory are managed when doing this kind of import.
Does the importer create and allocate a new data pointer for the vtkImageData created, so that the vtk image is not affected when the opencv matrix is destroyed.
Will the returned vtkImageData* still be valid once the importer is destroyed, or should I return a smart pointer to keep the reference counting > 0? My reasoning is that if the importer uses smart pointers for the vtkImageData internally, then the image will be destroyed as the importer is destroyed. VTK examples always use the importer in the same scope as where the data is then used.
Thank you
The importer does a copy when you ask to do it.
void vtkImageImport::SetImportVoidPointer (void* ptr, int save); stores your void* pointer without copying the data, save arg is used in the destructor of ImgImport, if save is 1, your stored pointer will not be deleted.
void SetImportVoidPointer (void *ptr) calls previous methods with save=1, so in your code, data from CV::Mat, will not be destroyed. Be careful : both use the same pointer : Modify your CV::Mat; and the result from importer will be different.
void CopyImportVoidPointer (void *ptr, vtkIdType size); make a copy of your data, in this case, internally, ImgImport will copy the data, store the new pointer, and delete it in the destructor. You can delete your CV::Mat, it may not affect the Importer.
For the second question, i'm not sure of the internally behavior for retrieve the output but storing the output from a vtkAlgorithm in a vtkSmartPointer allows you to delete the algorithm without corrupt the data.
vtkSmartPointer<vtkImageData> convertImage(const cv::Mat& image)
{
int width = image.cols;
int height = image.rows;
vtkSmartPointer<vtkImageImport> importer = vtkSmartPointer<vtkImageImport>::New();
importer->SetDataScalarTypeToUnsignedChar();
importer->SetImportVoidPointer(image.data);
importer->SetWholeExtent(0,width-1,0, height-1, 0, 0);
importer->SetDataExtentToWholeExtent();
importer->Update();
vtkSmartPointer<vtkImageData> outp = importer->GetOutput();
importer->Delete (); // this line cause the destruction of the output, unless it's stored in a smartPointer.
return outp;
}
Importer->Delete() is just for example. I tried with a basic exemple, and I as able to use the output from a vtkAlgorithm, without storing the output in a smartPointer.
But reading the Vtk official tutorials (section "Getting an Object with a Smart Pointer"), if you don't store the output in a smartpointer, the importer may be deleted at the end of the scope, the data too.
That's why i'm not sure : I can still use the "direct" pointer returned by the convertImage methods. You must use the smartpointers as describes in the VTK tutos. It's the best way to be sure your data is valid .
Hope it help.

Two structs, one references another

typedef struct Radios_Frequencia {
char tipo_radio[3];
int qt_radio;
int frequencia;
}Radiof;
typedef struct Radio_Cidade {
char nome_cidade[30];
char nome_radio[30];
char dono_radio[3];
int numero_horas;
int audiencia;
Radiof *fre;
}R_cidade;
void Cadastrar_Radio(R_cidade**q){
printf("%d\n",i);
q[0]=(R_cidade*)malloc(sizeof(R_cidade));
printf("informa a frequencia da radio\n");
scanf("%d",&q[0]->fre->frequencia); //problem here
printf("%d\n",q[0]->fre->frequencia); // problem here
}
i want to know why this function void Cadastrar_Radio(R_cidade**q) does not print the data
You allocated storage for your primary structure but not the secondary one. Change
q[0]=(R_cidade*)malloc(sizeof(R_cidade));
to:
q[0]=(R_cidade*)malloc(sizeof(R_cidade));
q[0]->fre = malloc(sizeof(Radiof));
which will allocate both. Without that, there's a very good chance that fre will point off into never-never land (as in "you can never never tell what's going to happen since it's undefined behaviour).
You've allocated some storage, but you've not properly initialized any of it.
You won't get anything reliable to print until you put reliable values into the structures.
Additionally, as PaxDiablo also pointed out, you've allocated the space for the R_cidade structure, but not for the Radiof component of it. You're using scanf() to read a value into space that has not been allocated; that is not reliable - undefined behaviour at best, but most usually core dump time.
Note that although the two types are linked, the C compiler most certainly doesn't do any allocation of Radiof simply because R_cidade mentions it. It can't tell whether the pointer in R_cidade is meant to be to a single structure or the start of an array of structures, for example, so it cannot tell how much space to allocate. Besides, you might not want to initialize that structure every time - you might be happy to have left pointing nowhere (a null pointer) except in some special circumstances known only to you.
You should also verify that the memory allocation succeeded, or use a memory allocator that guarantees never to return a null or invalid pointer. Classically, that might be a cover function for the standard malloc() function:
#undef NDEBUG
#include <assert.h>
void *emalloc(size_t nbytes)
{
void *space = malloc(nbytes);
assert(space != 0);
return(space);
}
That's crude but effective. I use non-crashing error reporting routines of my own devising in place of the assert:
#include "stderr.h"
void *emalloc(size_t nbytes)
{
void *space = malloc(nbytes);
if (space == 0)
err_error("Out of memory\n");
return space;
}

MFC multithreading with delete[] , dbgheap.c

I've got a strange problem and really don't understand what's going on.
I made my application multi-threaded using the MFC multithreadclasses.
Everything works well so far, but now:
Somewhere in the beginning of the code I create the threads:
m_bucketCreator = new BucketCreator(128,128,32);
CEvent* updateEvent = new CEvent(FALSE, FALSE);
CWinThread** threads = new CWinThread*[numThreads];
for(int i=0; i<8; i++){
threads[i]=AfxBeginThread(&MyClass::threadfunction, updateEvent);
m_activeRenderThreads++;
}
this creates 8 threads working on this function:
UINT MyClass::threadfunction( LPVOID params ) //executed in new Thread
{
Bucket* bucket=m_bucketCreator.getNextBucket();
...do something with bucket...
delete bucket;
}
m_bucketCreator is a static member. Now I get some thread error in the deconstructor of Bucket on the attempt to delete a buffer (however, the way I understand it this buffer should be in the memory of this thread, so I don't get why there is an error). On the attempt of delete[] buffer, the error happens in _CrtIsValidHeapPointer() in dbgheap.c.
Visual studio outputs the message that it trapped a halting point and this can be either due to heap corruption or because the user pressed f12 (I didn't ;) )
class BucketCreator {
public:
BucketCreator();
~BucketCreator(void);
void init(int resX, int resY, int bucketSize);
Bucket* getNextBucket(){
Bucket* bucket=NULL;
//enter critical section
CSingleLock singleLock(&m_criticalSection);
singleLock.Lock();
int height = min(m_resolutionY-m_nextY,m_bucketSize);
int width = min(m_resolutionX-m_nextX,m_bucketSize);
bucket = new Bucket(width, height);
//leave critical section
singleLock.Unlock();
return bucket;
}
private:
int m_resolutionX;
int m_resolutionY;
int m_bucketSize;
int m_nextX;
int m_nextY;
//multithreading:
CCriticalSection m_criticalSection;
};
and class Bucket:
class Bucket : public CObject{
DECLARE_DYNAMIC(RenderBucket)
public:
Bucket(int a_resX, int a_resY){
resX = a_resX;
resY = a_resY;
buffer = new float[3 * resX * resY];
int buffersize = 3*resX * resY;
for (int i=0; i<buffersize; i++){
buffer[i] = 0;
}
}
~Bucket(void){
delete[] buffer;
buffer=NULL;
}
int getResX(){return resX;}
int getResY(){return resY;}
float* getBuffer(){return buffer;}
private:
int resX;
int resY;
float* buffer;
Bucket& operator = (const Bucket& other) { /*..*/}
Bucket(const Bucket& other) {/*..*/}
};
Can anyone tell me what could be the problem here?
edit: this is the other static function I'm calling from the threads. Is this safe to do?
static std::vector<Vector3> generate_poisson(double width, double height, double min_dist, int k, std::vector<std::vector<Vector3> > existingPoints)
{
CSingleLock singleLock(&m_criticalSection);
singleLock.Lock();
std::vector<Vector3> samplePoints = std::vector<Vector3>();
...fill the vector...
singleLock.Unlock();
return samplePoints;
}
All the previous replies are sound. For the copy constructor, make sure that it doesn't just copy the buffer pointer, otherwise that will cause the problem. It needs to allocate a new buffer, not the pointer value, which would cause an error in 'delete'. But I don't get the impression that the copy contructor will get called in your code.
I've looked at the code and I am not seeing any error in it as is. Note that the thread synchronization isn't even necessary in this GetNextBucket code, since it's returning a local variable and those are pre-thread.
Errors in ValidateHeapPointer occur because something has corrupted the heap, which happens when a pointer writes past a block of memory. Often it's a for() loop that goes too far, a buffer that wasn't allocated large enough, etc.
The error is reported during a call to 'delete' because that's when the heap is validated for bugs in debug mode. However, the error has occurred before that time, it just happens that the heap is checked only in 'new' and 'delete'. Also, it isn't necessarily related to the 'Bucket' class.
What you need to need to find this bug, short of using tools like BoundsChecker or HeapValidator, is comment out sections of your code until it goes away, and then you'll find the offending code.
There is another method to narrow down the problem. In debug mode, include in your code, and sprinkle calls to _CrtCheckMemory() at various points of interest. That will generate the error when the heap is corrupted. Simply move the calls in your code to narrow down at what point the corruption begins to occur.
I don't know which version of Visual C++ you are using. If you're using a earlier one like VC++ 6.0, make sure that you are using the Multitreaded DLL version of the C Run Time Library in the compiler option.
You're constructing a RenderBucket. Are you sure you're calling the 'Bucket' class's constructor from there? It should look like this:
class RenderBucket : public Bucket {
RenderBucket( int a_resX, int a_resY )
: Bucket( a_resX, a_resY )
{
}
}
Initializers in the Bucket class to set the buffer to NULL is a good idea... Also making the Default constructor and copy constructor private will help to make double sure those aren't being used. Remember.. the compiler will create these automatically if you don't:
Bucket(); <-- default constructor
Bucket( int a_resx = 0, int a_resy = 0 ) <-- Another way to make your default constructor
Bucket(const class Bucket &B) <-- copy constructor
You haven't made a private copy constructor, or any default constructor. If class Bucket is constructed via one of these implicitly-defined methods, buffer will either be uninitialized, or it will be a copied pointer made by a copy constructor.
The copy constructor for class Bucket is Bucket(const Bucket &B) -- if you do not explicitly declare a copy constructor, the compiler will generate a "naive" copy constructor for you.
In particular, if this object is assigned, returned, or otherwise copied, the copy constructor will copy the pointer to a new object. Eventually, both objects' destructors will attempt to delete[] the same pointer and the second attempt will be a double deletion, a type of heap corruption.
I recommend you make class Bucket's copy constructor private, which will cause attempted copy construction to generate a compile error. As an alternative, you could implement a copy constructor which allocates new space for the copied buffer.
Exactly the same applies to the assignment operator, operator=.
The need for a copy constructor is one of the 55 tips in Scott Meyer's excellent book, Effective C++: 55 Specific Ways to Improve Your Programs and Designs:
This book should be required reading for all C++ programmers.
If you add:
class Bucket {
/* Existing code as-is ... */
private:
Bucket() { buffer = NULL; } // No default construction
Bucket(const Bucket &B) { ; } // No copy construction
Bucket& operator= (const Bucket &B) {;} // No assignment
}
and re-compile, you are likely to find your problem.
There is also another possibility: If your code contains other uses of new and delete, then it is possible these other uses of allocated memory are corrupting the linked-list structure which defines the heap memory. It is common to detect this corruption during a call to delete, because delete must utilize these data structures.

Resources