You have a bad design. A thread must contain a mutex only when it needs to access shared data structures. This should be a small fraction of the execution time of the thread, not the vast majority of them. If you see the type of template that you are developing, the time has come to redesign.
One possible pattern is for a compute thread to hold a pointer to global data during operation without saving the mutex. The user interface thread can then create a new version of the global data based on user interface input, and then publish a pointer to the new data so that the compute thread sees it the next time it leaves to get the pointer. Thus, the computation flow only needs to hold the mutex for as long as it takes it to copy the pointer.
Here's a simplified layout for the calculation flow:
pthread_mutex_lock(&mutex); my_pointer = shared_pointer; pthread_mutex_unlock(&mutex); do_calculations();
And for the user interface thread, the logic is as follows: you are modifying a copy of the data. You create a new copy of the data. You get a mutex. You change shared_pointer to point to one of two copies of the data. You save another copy for change in the next pass.
source share