"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 }