views:

93

answers:

4

This is related to an issue I have been discussing here and here, but as my investigations have led me away from the STL as the potential issue, and towards "new" as my nemisis, I thought it best to start a new thread.

To reiterate, I am using an arm-linux cross compiler (version 2.95.2) supplied by the embedded platform vendor.

When I run the application below on my Linux PC, it of course works never fails. However when running it on the embedded device, I get segmentation faults every time. Using "malloc" never fails. Synchronising the "new" allocation using the mutex will stop the issue, but this is not practical in my main application.

Can anyone suggest why this might be occurring, or have any ideas how I can get around this issue?

Thanks.

#include <stdio.h>
#include <pthread.h>


pthread_mutex_t _logLock = PTHREAD_MUTEX_INITIALIZER;

static void* Thread(void *arg)
{
    int i = 0;
    while (i++ < 500)
    {
        // pthread_mutex_lock(&_logLock);
        char* myDyn = (char*) new char[1023];

        //        char* buffer = (char*) malloc(1023);
        //        if (buffer == NULL)
        //            printf("Out of mem\n");
        //        free(buffer);


        delete[] myDyn;

        //pthread_mutex_unlock(&_logLock);


    }
    pthread_exit(NULL);
}

int main(int argc, char** argv)
{
    int threads = 50;
    pthread_t _rx_thread[threads];
    for (int i = 0; i < threads; i++)
    {
        printf("Start Thread: %i\n", i);
        pthread_create(&_rx_thread[i], NULL, Thread, NULL);
    }

    for (int i = 0; i < threads; i++)
    {
        pthread_join(_rx_thread[i], NULL);
        printf("End Thread: %i\n", i);
    }
}
+1  A: 

Yeah, new is probably not threadsafe. You need synchronization mechanisms around the memory allocation and, separately, around the deletion. Look into the Boost.thread library, which provides mutex types that should help you out.

gregg
+3  A: 

If the heap on your device isn't thread-safe, then you need to lock. You could just write your own new and delete functions that lock for the duration of new or delete -- you don't need to hold the lock across the whole lifetime of the allocated memory.

Check to see if there are compiler switches to make the allocator thread-safe.

Lou Franco
Lou, I appreciate that I can overload the new / delete operators and am in the process of investigating this option. However I am concerned that these will not be used by the libraries I call (e.g. STL). What sort of compiler switches have you come across? I cannot find anything suitable at first glance.
Brad
For STL, override the allocators. http://www.codeguru.com/Cpp/Cpp/cpp_mfc/stl/article.php/c4079/
Lou Franco
I don't know what compiler you're using -- but some have switches that make it use multithread safe versions of the runtime (Visual Studio has this). You might want to talk to the vendor of your embedded device.
Lou Franco
+1  A: 

How about using malloc (you say it never fails on the embedded platform) to get the required memory then using placement new (void* operator new[] (std::size_t size, void* ptr) throw()) assuming it is available, for construction. See new[] operator

Also see stackoverflow article

and MSDN

Sam
+2  A: 

As others have stated, chances are that the toolset's default memory allocation behavior is not thread-safe. I just checked with the 2 ARM cross-development toolsets I use the most, and indeed this is the case with one of them.

Most toolsets offer ways of making the libraries thread-safe, either by re-implementing functions or by linking in a different (thread-safe) version of the library. Without more information from you, it's hard to say what your particular toolset is doing.

Hate to say it, but the best information is probably in your toolset documentation.

Dan
Dan, I am relatively new to cross compiling, and am using the toolset supplied by the vendor of the device I am using. How would I check?
Brad