Search code examples
cpthreads

wrong usage of pthread_create?


I am trying to understand if my approach may result in undefined behavior.

I have allocated 10 elements of my structure using calloc in this manner:

struct myStructure {
    int index;
    int myNum;
    char myLetter[1024];
    void *udata;
};

static void *threads(void *thread_data) {
    struct myStructure *arg = (struct myStructure*)thread_data;
}

struct myStructure *elements = (struct myStructure *)calloc(10, sizeof(*elements));
pthread_t *pthread_e = calloc(10, sizeof(*pthread_e));

for (unsigned int i = 0; i < 10; ++i) {
    elements[i].index = i;
    pthread_create(&pthread_e[i], NULL, threads, (void *)&elements[i]);
    pthread_detach(pthread_e[i]);
}

If the threads attempt to access each other's thread_data using pointer arithmetic and modify data such as 'myNum', 'myLetter', or 'udata', would it cause problems or violate the restrict rules (note: I plan to use mutex/spinlocks during modification)? I ask because the last argument I provide to pthread_create - (void *)&elements[i] - is defined as void *restrict arg.

I hope someone can help me to understand and also confirm if what i'm doing is wrong


Solution

  • The reason why pthread_create has restict-qualified parameters is to ensure that the function can assume that the thread handle or attributes aren't passed along as the callback arg parameter. Since arg is void*, the function cannot assume that this is not the case unless restrict is added. This is some manner of micro-optimization of internals in the pthread library and won't affect the application unless you are doing really strange things there.

    As far as pointer aliasing goes, you point to a region returned from malloc/calloc and it has no "effective type" yet - it won't get that until the first access. And that doesn't matter here either, as long as you only ever access it through a struct myStructure* pointer.

    So nope, no problems with pointer aliasing here. The only thing which is undefined behavior is the lack of a return statement in your callback. Normal thread safety concerns do of course also apply - you may need to protect against race conditions etc.