Contenuto principale

MISRA C:2012 Rule 22.14

Thread synchronization objects shall be initialized before being accessed

Since R2025b

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 shall be initialized before being accessed.1

Rationale

If you do not initialize the thread synchronization objects before starting the threads, the threads might access these objects in an invalid state. Checking the validity of the synchronization objects in such code cannot be done deterministically.

Polyspace Implementation

Polyspace reports a violation of this rule if either of these conditions is true:

  • A cnd_t object is used in the code but it is not explicitly created using cnd_init().

  • A mtx_t object is used in the code but it is not explicitly created using mtx_init().

  • Multiple functions call the functions cnd_init() and mtx_init(). Polyspace expects each these functions to be called from a unique initialization function.

Extend Checker

To extend this checker, in a Datalog file specify either or both:

  • A unique function that calls cnd_init().

  • A unique function that calls mtx_init().

For example, this Datalog code designates foo() as the function that calls cnd_init() and bar() as the function that calls mtx_init(). Then, it instructs Polyspace to report a violation when either of these conditions are true:

  • A thread starts before the bar().

  • A thread starts before the foo().

.include "models/interfaces/concurrency.dl"
Concurrency.Basic.raise_if_thread_start_before_mtx_init().
Concurrency.Basic.raise_if_thread_start_before_cnd_init().
Concurrency.Basic.is_unique_function_cnd_init("foo").
Concurrency.Basic.is_unique_function_mutex_init("bar").
The function names are specified without the trailing parentheses. Save this code as a Datalog (.dl) file and use it as an input to the option -code-behavior-specifications. For more details about modifying checker behavior using Datalog, see Modify Bug Finder Checkers Through Code Behavior Specifications.

Troubleshooting

If you expect a rule violation but Polyspace does not report it, see Diagnose Why Coding Standard Violations Do Not Appear as Expected.

Examples

expand all

This code uses mtx_t and cnd_t objects without initialization. Polyspace reports violations.

#include <stdio.h>
#include <threads.h>

cnd_t condition; // Noncompliant - Undefined behavior
mtx_t mutex; // Noncompliant - Undefined behavior

int main() {
    // Using condition variable and mutex without initialization
    mtx_lock(&mutex); 
    cnd_wait(&condition, &mutex); 
    mtx_unlock(&mutex);
    return 0;
}

In this code, the mutex and condition objects are initialized unique initialization functions outside main. Polyspace reports no violations.

#include <stdio.h>
#include <threads.h>

cnd_t condition1, condition2;
mtx_t mutex1, mutex2;

void initialize_mtx() {
	mtx_init(&mutex1, mtx_plain); //Compliant
	mtx_init(&mutex2, mtx_plain); //Compliant
}

void initialize_cnd() {
	cnd_init(&condition1); //Compliant
	cnd_init(&condition2); //Compliant
}



int main() {
	initialize_mtx();
	initialize_cnd();


	mtx_lock(&mutex1);
	cnd_wait(&condition1, &mutex1);
	mtx_unlock(&mutex1);

	mtx_lock(&mutex2);
	cnd_wait(&condition2, &mutex2);
	mtx_unlock(&mutex2);

	mtx_destroy(&mutex1);
	mtx_destroy(&mutex2);
	cnd_destroy(&condition1);
	cnd_destroy(&condition2);

	return 0;
}

In this code, the initializer functions for mutex and condition objects are specified in a Datalog file. Initializing these objects in main() results in violations.

#include <stdio.h>
#include <threads.h>

cnd_t condition1, condition2, condition3;
mtx_t mutex1, mutex2;

void initialize_mtx() {
	mtx_init(&mutex1, mtx_plain); //Compliant
	mtx_init(&mutex2, mtx_plain); //Compliant
}

void initialize_cnd() {
	cnd_init(&condition1); //Compliant
	cnd_init(&condition2); //Compliant
}



int main() {
	initialize_mtx();
	initialize_cnd();


	mtx_lock(&mutex1);
	cnd_wait(&condition1, &mutex1);
	mtx_unlock(&mutex1);

	mtx_lock(&mutex2);
	cnd_wait(&condition2, &mutex2);
	mtx_unlock(&mutex2);
  
	//..
	cnd_init(&condition3);   //Noncompliant
	mtx_destroy(&mutex1);
	mtx_destroy(&mutex2);
	cnd_destroy(&condition1);
	cnd_destroy(&condition2);

	return 0;
}

Specify the initialization function using this Datalog code as an input to -code-behavior-specification

.include "models/interfaces/concurrency.dl"
Concurrency.Basic.raise_if_thread_start_before_mtx_init().
Concurrency.Basic.raise_if_thread_start_before_cnd_init().
Concurrency.Basic.is_unique_function_cnd_init("initialize_cnd").
Concurrency.Basic.is_unique_function_mutex_init("initialize_mtx").

Check Information

Group: Resources
Category: Mandatory
AGC Category: Mandatory

Version History

Introduced in R2025b


1 All MISRA coding rules and directives are © Copyright The MISRA Consortium Limited 2021.

The MISRA coding standards referenced in the Polyspace Bug Finder™ documentation are from the following MISRA standards:

  • MISRA C:2004

  • MISRA C:2012

  • MISRA C:2023

  • MISRA C++:2008

  • MISRA C++:2023

MISRA and MISRA C are registered trademarks of The MISRA Consortium Limited 2021.