"Fossies" - the Fresh Open Source Software Archive

Member "FunctionCheck-3.2.0/src/share/fc_semaphore.c" (26 May 2012, 3516 Bytes) of package /linux/privat/old/FunctionCheck-3.2.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /*
    2  * FunctionCheck profiler
    3  * (C) Copyright 2000-2012 Yannick Perret
    4  *
    5  *  This program is free software; you can redistribute it and/or
    6  *  modify it under the terms of the GNU General Public License as
    7  *  published by the Free Software Foundation; either version 2 of the
    8  *  License, or (at your option) any later version.
    9  *
   10  *  This program is distributed in the hope that it will be useful,
   11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   13  *  General Public License for more details.
   14  *
   15  *  You should have received a copy of the GNU General Public License
   16  *  along with this program; if not, write to the Free Software
   17  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   18  */
   19 
   20 #include <stdio.h>
   21 #include <stdlib.h>
   22 #include <string.h>
   23 #include <sys/time.h>
   24 #include "fc_semaphore.h"
   25 #include "fc_tools.h"
   26 #include "fc_global.h"
   27 
   28 /*
   29  * Bakery Algorithm
   30  * Lesly Lamport
   31  */
   32 
   33 /* initialize a semaphore */
   34 inline void fc_semaphore_init(FC_Semaphore *s)
   35 {
   36     memset(s, 0, sizeof (*s));
   37 }
   38 
   39 /* search the given PID in the PID list, and returns
   40      the corresponding offset in the 'sem' array */
   41 static int fc_semaphore_find_process(FC_Semaphore *s, int pid)
   42 {
   43     int i;
   44 
   45     /* change this for a faster access method */
   46     for (i = 0; (i < s->number_pid) && (i < FC_MAX_SCLIENTS); i++)
   47     {
   48         if (s->pids[i] == pid)
   49             return i;
   50     }
   51     /* full */
   52     if (i == FC_MAX_SCLIENTS)
   53     {
   54         fc_message("table of processes in the semaphore is full.");
   55         fc_message_fatal(FC_ERR_OTHER, "cannot resume. Sorry.");
   56     }
   57     /* not found */
   58     /* WARNING: this part sould be protected against multiple access */
   59     s->pids[i] = pid;
   60     s->number_pid++;
   61     return i;
   62 }
   63 
   64 /* lock the semaphore */
   65 void fc_semaphore_get(FC_Semaphore volatile*s, unsigned int pid)
   66 {
   67     int i, process;
   68     struct timeval tv;
   69 
   70     process = fc_semaphore_find_process((FC_Semaphore*) s, pid);
   71 
   72     if (s->sem[process].number)
   73     {
   74         /*
   75          * Lock a yet locked
   76          */
   77         s->number_of_recursive_lock++;
   78         return;
   79     }
   80 
   81     s->sem[process].choosing = 1;
   82     for (i = 0; i < FC_MAX_SCLIENTS; i++)
   83         if (s->sem[i].number > s->sem[process].number)
   84             s->sem[process].number = s->sem[i].number;
   85     s->sem[process].number++;
   86     s->sem[process].choosing = 0;
   87 
   88     for (i = 0; i < FC_MAX_SCLIENTS; i++)
   89     {
   90         while (s->sem[i].choosing)
   91         {
   92             tv.tv_sec = 0;
   93             tv.tv_usec = 1000;
   94             select(0, NULL, NULL, NULL, &tv);
   95         }
   96 
   97         while (s->sem[i].number &&
   98                 (
   99                 s->sem[i].number < s->sem[process].number ||
  100                 (
  101                 s->sem[i].number == s->sem[process].number && i < process
  102                 )
  103                 )
  104                 )
  105         {
  106             tv.tv_sec = 0;
  107             tv.tv_usec = 1000;
  108             select(0, NULL, NULL, NULL, &tv);
  109         }
  110     }
  111 }
  112 
  113 /* unlock the semaphore */
  114 void fc_semaphore_put(FC_Semaphore volatile*s, unsigned int pid)
  115 {
  116     int process;
  117 
  118     process = fc_semaphore_find_process((FC_Semaphore*) s, pid);
  119 
  120     if (s->number_of_recursive_lock)
  121         s->number_of_recursive_lock--;
  122     else
  123         s->sem[process].number = 0;
  124 }
  125 
  126 /* test if the semaphore is locked */
  127 int fc_semaphore_locked(FC_Semaphore *s)
  128 {
  129     int i;
  130 
  131     for (i = 0; i < FC_MAX_SCLIENTS; i++)
  132         if (s->sem[i].number)
  133             return (1);
  134 
  135     return 0;
  136 }