Main Content

MISRA C:2012 Rule 22.16

All mutex objects locked by a thread shall be explicitly unlocked by the same thread

Since R2024b

Description

This checker is deactivated in a default Polyspace® as You Code analysis. See Checkers Deactivated in Polyspace as You Code Analysis (Polyspace Access).

Rule Definition

Thread synchronization objects and thread-specific storage pointers shall not be destroyed until after all threads accessing them have terminated.

This rule comes from MISRA C™: 2012 Amendment 4.

Rationale

If a thread locks a mutex but fails to unlock the mutex before the thread termination, the mutex remains locked. Other threads can remain waiting for the locked mutex to be unlocked for an indeterminate time, resulting in undefined behavior.

To avoid a violation of this rule, unlock previously locked mutex objects explicitly and for all execution paths in a thread.

Polyspace Implementation

Polyspace reports a violation of this rule when these events happen in sequence:

  1. A task calls the lock function mtx_lock().

  2. The task ends without a call to an unlock function mtx_unlock().

A task is a function that you specify as an entry point using the option Tasks (-entry-points).

Troubleshooting

If you expect a rule violation but do not see it, refer to Diagnose Why Coding Standard Violations Do Not Appear as Expected.

Examples

expand all

This example shows compliant and noncompliant use of mutex objects:

  • The mutex myMutex1 is locked by mtx_lock() and then explicitly unlocked by mtx_unlock(). This use of myMutex1 is compliant with this rule.

  • The mutex myMutex2 is locked by mtx_lock(). This mutex is unlocked only in the execution path where returnFlag() returns true. Undefined behavior results when returnFlag() returns false. Because myMutex2 is not unlocked in all execution paths, Polyspace reports a violation of this rule.



#include <threads.h>
#include <stdint.h>
#include <stdbool.h>

mtx_t myMutex1;
mtx_t myMutex2;

extern bool returnFlag();
int32_t foo(void)          /* Thread 1 */
{

	//Compliant use
	mtx_lock(&myMutex1);         /*Compliant - myMutex1 unlocked before thread termination*/
	//...
	mtx_unlock(&myMutex1);

	//Noncompliant use
	mtx_lock(&myMutex2);    /* Noncompliant - myMutex2 unlocked conditionally */
	if(returnFlag())
	{
		//...
        mtx_unlock(&myMutex2);
	}
	return 0;
}

In this example, to emulate multitasking behavior, specify theseoptions:

Alternatively, use this command on the command-line:

polyspace-bug-finder
   -entry-points foo

Check Information

Group: Resources
Category: Required
AGC Category: Required

Version History

Introduced in R2024b