Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: xref CON44-C

...

The following noncompliant code example consists of a given number of threads (5) that should execute one after another according to the step level assigned to each thread when it is created (serialized processing). The current_step variable holds the current step level and is incremented as soon as the respective thread finishes its processing. Finally, another thread is signaled so that the next step can be executed. Each thread waits until its step level is ready, and the cnd_wait() function call is wrapped inside a while loop, in compliance with CON44-C. Wrap functions that can fail spuriously in a loop.

Code Block
bgColor#FFcccc
langc
#include <stdio.h>
#include <threads.h>

enum { NTHREADS = 5 };

mtx_t mutex;
cnd_t cond;

int run_step(void *t) {
  static int current_step = 0;
  int my_step = (int)t;

  if (thrd_success != mtx_lock(&mutex)) {
    /* Handle error condition. */
  }

  printf("Thread %d has the lock\n", my_step);

  while (current_step != my_step) {
    printf("Thread %d is sleeping...\n", my_step);

    if (thrd_success != cnd_wait(&cond, &mutex)) {
      /* Handle error condition. */
    }

    printf("Thread %d woke up\n", my_step);
  }

  /* Do processing... */
  printf("Thread %d is processing...\n", my_step);

  current_step++;

  /* Signal a waiting task. */
  if (thrd_success != cnd_signal(&cond)) {
    /* Handle error condition. */
  }

  printf("Thread %d is exiting...\n", my_step);

  if (thrd_success != mtx_unlock(&mutex)) {
    /* Handle error condition. */
  }
  return 0;
}

int main(int argc, char** argv) {
  int i;
  thrd_t threads[NTHREADS];
  int step[NTHREADS];

  if (thrd_success != mtx_init(&mutex, mtx_plain)) {
    /* Handle error condition. */
  }
  if (thrd_success != cnd_init(&cond)) {
    /* Handle error condition. */
  }

  /* Create threads. */
  for (i = 0; i < NTHREADS; ++i) {
    step[i] = i;
    if (thrd_success != thrd_create(&threads[i], run_step,
                                    (void *)step[i])) {
      /* Handle error condition */
    }
  }

  /* Wait for all threads to complete. */
  for (i = NTHREADS - 1; i >= 0; --i) {
    if (thrd_success != thrd_join(threads[i], NULL)) {
      /* Handle error condition */
    }
  }

  mtx_destroy(&mutex);
  cnd_destroy(&cond);
  return 0;
}

...