Main Content

CERT C: Rec. POS04-C

Avoid using PTHREAD_MUTEX_NORMAL type mutex locks

Since R2026a

Description

Avoid using PTHREAD_MUTEX_NORMALL type mutex locks1

Polyspace Implementation

The rule checker checks for Use of PTHREAD_MUTEX_NORMAL type mutex locks.

Examples

expand all

Issue

This issue occurs when the second argument of a call to the function pthread_mutexattr_settype() is PTHREAD_MUTEX_NORMAL instead of PTHREAD_MUTEX_RECURSIVE or PTHREAD_MUTEX_ERRORCHECK.

Risk

Mutex locks of type PTHREAD_MUTEX_NORMAL do not detect deadlocks. As a result, use of this type of mutex can lead to unexpected deadlocks and undefined behaviors.

Say your code declares a PTHREAD_MUTEX_NORMAL mutex called normal_mutex. These outcomes can result from using such a mutex:

  • If a thread attempts to relock normal_mutex without unlocking it first, execution deadlocks without returning an error to the caller.

  • If a thread attempts to unlock normal_mutex after it is locked by a different thread, the behavior of the code is undefined.

  • If a thread attempts to unlock normal_mutex after it is unlocked, the behavior of the code is undefined.

Fix

Use PTHREAD_MUTEX_RECURSIVE or PTHREAD_MUTEX_ERRORCHECK instead of PTHREAD_MUTEX_NORMAL.

Example

This example uses a PTHREAD_MUTEX_NORMAL type mutex counter_mutex to protect the shared resource counter. Polyspace® reports a violation.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define NUM_THREADS 5
#define NUM_INCREMENTS 100000

// Shared resource
int counter = 0;

// Mutex for protecting the shared resource
pthread_mutex_t counter_mutex;

// Function executed by each thread
void* incrementCounter(void* arg) {
    for (int i = 0; i < NUM_INCREMENTS; i++) {
        // Lock the mutex before accessing the shared resource
        pthread_mutex_lock(&counter_mutex);
        
        // Increment the shared counter
        counter++;
        
        // Unlock the mutex after accessing the shared resource
        pthread_mutex_unlock(&counter_mutex);
    }
    return NULL;
}

int main() {
    pthread_t threads[NUM_THREADS];
    pthread_mutexattr_t attr;

    // Initialize the mutex attribute
    pthread_mutexattr_init(&attr);
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);  //Noncompliant

    // Initialize the mutex with the specified attributes
    pthread_mutex_init(&counter_mutex, &attr);

    // Create threads
    for (int i = 0; i < NUM_THREADS; i++) {
        if (pthread_create(&threads[i], NULL, incrementCounter, NULL) != 0) {
            perror("Failed to create thread");
            return EXIT_FAILURE;
        }
    }

    // Wait for all threads to finish
    for (int i = 0; i < NUM_THREADS; i++) {
        if (pthread_join(threads[i], NULL) != 0) {
            perror("Failed to join thread");
            return EXIT_FAILURE;
        }
    }

    // Print the final value of the counter
    printf("Final counter value: %d\n", counter);

    // Destroy the mutex
    pthread_mutex_destroy(&counter_mutex);

    return EXIT_SUCCESS;
}

Correction

To fix this issue, define counter_mutex as a PTHREAD_MUTEX_ERRORCHECK type mutex.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define NUM_THREADS 5
#define NUM_INCREMENTS 100000

// Shared resource
int counter = 0;

// Mutex for protecting the shared resource
pthread_mutex_t counter_mutex;

// Function executed by each thread
void* incrementCounter(void* arg) {
    for (int i = 0; i < NUM_INCREMENTS; i++) {
        // Lock the mutex before accessing the shared resource
        pthread_mutex_lock(&counter_mutex);
        
        // Increment the shared counter
        counter++;
        
        // Unlock the mutex after accessing the shared resource
        pthread_mutex_unlock(&counter_mutex);
    }
    return NULL;
}

int main() {
    pthread_t threads[NUM_THREADS];
    pthread_mutexattr_t attr;

    // Initialize the mutex attribute
    pthread_mutexattr_init(&attr);
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);  //Compliant

    // Initialize the mutex with the specified attributes
    pthread_mutex_init(&counter_mutex, &attr);

    // Create threads
    for (int i = 0; i < NUM_THREADS; i++) {
        if (pthread_create(&threads[i], NULL, incrementCounter, NULL) != 0) {
            perror("Failed to create thread");
            return EXIT_FAILURE;
        }
    }

    // Wait for all threads to finish
    for (int i = 0; i < NUM_THREADS; i++) {
        if (pthread_join(threads[i], NULL) != 0) {
            perror("Failed to join thread");
            return EXIT_FAILURE;
        }
    }

    // Print the final value of the counter
    printf("Final counter value: %d\n", counter);

    // Destroy the mutex
    pthread_mutex_destroy(&counter_mutex);

    return EXIT_SUCCESS;
}

Check Information

Group: Rec. 50. POSIX (POS)
PQL Name: std.cert.POS04_C

Version History

Introduced in R2026a


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.