Search code examples
cmultithreadingpthreadslockingspinlock

What exact "resources" are released, when calling pthread_spin_destroy()?



I have a question regarding the phread_spin_destroy() function. In the posix standard it is defined as follows:

The pthread_spin_destroy() function shall destroy the spin lock referenced by lock and release any resources used by the lock.

So if there are 2 functions. One function, that gets called by many threads, holds a spinock and increments for example a global variable (in the example foo() called).
And another function (in the example destroy() called), who gets called by one thread, after the first function gets called and calls pthread_spin_destroy(). These functions could look like this for example:

void* foo(void* i) {
   pthread_spin_lock(&LOCK); //lock the spinlock
   sleep(2); //sleep a little
   globalvariable++; //increment
   printf("globalvariable: %d\n", globalvariable); //print for debug purpose
   pthread_spin_unlock(&LOCK); //spinlock gets unlocked
   return NULL;
}

void* destroy(void* i) {
    sleep(5); //sleep
    pthread_spin_destroy(&LOCK); //destroy the lock
    return NULL; //return
}

Please note, that "LOCK" is a global declared variable from type pthread_spin_t and that LOCK gets initialised with (pthread_spin_init(&LOCK,0)) before foo() gets called.

The output BEFORE calling destroy() is as expected: the function increments the global variable very slowly (because of the sleep(2)).
But if i call the destroy() function, nothing changes. And this part is confusing me.
My question is: Is my understanding of pthread_spin_destroy() wrong? Is it only releasing the resource "LOCK" (I mean this one pthread_spin_t LOCK variable)?
I would expect that the spinlock gets destroyed and the other threads can act as if there is no lock.
Thank you in advance


Solution

  • The resources released by pthread_spin_destroy() are whatever resources the implementation needed to allocate to implement the spinlock as part of pthread_spin_init() (which, depending on the implementation, may be "none at all").

    It's undefined behaviour to call pthread_spin_lock() again on the lock after you've called pthread_spin_destroy(), until another call to pthread_spin_init(). It's just a deallocation function: don't call it unless you're completely done with the lock and won't need to lock it again (typically, you'd call pthread_spin_destroy() on a spin lock that is embedded in another data structure that you're about to free).