Using a semaphore

The following example demonstrates how to utilize a semaphore object to regulate access to a shared resource.

#include <stdio.h>
#include <conio.h>
#include "OS_API.h"


#define TASK_COUNT  7
#define SEM_COUNT   3
#define SEM_NAME    "Sem1"

INDEX Counters[TASK_COUNT];
INDEX Progress[TASK_COUNT];


ERROR Task(PVOID Arg)
{
  HANDLE SemaphoreHandle;
  INDEX i, TaskID;

  /* Get the semaphore handle */
  SemaphoreHandle = osOpenSemaphore(SEM_NAME);

  /* Get task ID passed in the task startup function parameter */
  TaskID = (INDEX) Arg;

  /* Infinite loop */
  while(1)
  {
    /* Acquire the semaphore */
    osWaitForObject(SemaphoreHandle, OS_INFINITE);

    /* Perform some job for one second */
    Counters[TaskID]++;
    for(i = 0; i < 10; i++)
    {
      Progress[TaskID] = 10 * (i + 1);
      osSleep(AR_TICKS_PER_SECOND / 10);
    }
    Progress[TaskID] = 0;

    /* Release the semaphore when job is finished */
    osReleaseSemaphore(SemaphoreHandle, 1, NULL);
  }
}


ERROR MainTask(PVOID Arg)
{
  INDEX i;

  /* Create named semaphore (its handle is not necessary) */
  osCreateSemaphore(SEM_NAME, SEM_COUNT, SEM_COUNT);

  /* Create tasks and initialize variables */
  for(i = 0; i < TASK_COUNT; i++)
  {                 
    Counters[i] = 0;
    Progress[i] = 0;
    osCreateTask(Task, (PVOID) i, 0, 1, FALSE);
  }

  /* Display counters value on every 1/10 second */
  while(1)
  {
    /* Display counters value */
    for(i = 0; i < TASK_COUNT; i++)
    {
      gotoxy(1, 1 + i);
      printf("Task %i: %3i %% / %i", i, Progress[i], Counters[i]);
    }

    /* Sleep for 1/10 second */
    osSleep(AR_TICKS_PER_SECOND / 10);
  }
}


int main(void)
{
  /* Initialization */
  arInit();
  stInit();
  osInit();

  /* Create main task */
  osCreateTask(MainTask, NULL, 0, 0, FALSE);

  /* Start the operating system */
  osStart();

  /* Deinitialization */
  osDeinit();
  arDeinit();
  return 0;
}
SpaceShadow documentation