Golem  v0.1.1
Generic Operating system Libraries for Embedded Multitasking
 All Data Structures Files Functions Variables Pages
/home/ruud/Engineering/software/projects/golem-project-code/trunk/glm_signal.c
1 
11 /* INCLUDES *******************************************************************/
12 #include "glm_signal.h"
13 #include "glm_alarm.h"
14 
15 
16 /* TYPES **********************************************************************/
17 typedef uint_base_t counter_t;
18 
19 
20 typedef struct
21 {
22  counter_t *counters;
23  counter_t length;
24 } flag_counters_t;
25 
26 
27 typedef struct
28 {
29  flag_t *flags;
30  counter_t length;
31 } flags_t;
32 
33 
34 typedef struct
35 {
36  flags_t *registry;
37  counter_t length;
38 } signal_registry_t;
39 
40 
41 /* PRIVATE VARIABLES **********************************************************/
42 static signal_registry_t m_sigreg;
43 static flag_counters_t m_counters;
44 static heap_id_t m_heap_id = 0;
45 
46 /* PRIVATE CONSTANTS **********************************************************/
47 static const char *m_name = "glm_signal";
48 
49 
50 /* PRIVATE FUNCTION DECLARATIONS **********************************************/
51 static bool signal_valid(signal_t signal);
52 static bool signal_flag_connected(signal_t signal, flag_t flag);
53 static bool signal_flag_valid(flag_t flag);
54 static void signal_flag_set(flag_t flag);
55 
56 
57 /* PUBLIC FUNCTIONS ***********************************************************/
58 
59 bool
60 signal_init()
61 {
62  return heap_create_hid((char*) m_name, &m_heap_id);
63 }
64 
65 
66 void
67 signal_reset()
68 {
69  uint_base_t i;
70 
71  // Free memory occupied by all signal-flag connections
72  for(i=0 ; i<m_sigreg.length ; i++)
73  {
74  signal_reset_connections(i);
75  }
76  heap_free(m_sigreg.registry);
77  m_sigreg.length = 0;
78 
79  // Free memory occupied by all flag counters
80  for(i=0 ; i<m_counters.length ; i++)
81  {
82  heap_free(&m_counters.counters[i]);
83  }
84  heap_free(m_counters.counters);
85  m_counters.length = 0;
86 
87  // Reset heap-ID
88  m_heap_id = 0;
89 }
90 
91 
92 char *
93 signal_name()
94 {
95  return (char*) m_name;
96 }
97 
98 
99 bool
100 signal_create(signal_t * signal)
101 {
102  bool retval = false;
103  flags_t *flags = NULL;
104  size_t size = sizeof(flags_t);
105  signal_t i = m_sigreg.length;
106 
107  // First, invalidate signal
108  *signal = 0;
109 
110  // Calculate total memory to allocate the new 'flags_t' included
111  size *= i + 1;
112 
113  if(0 != m_heap_id)
114  {
115  // Allocate the required memory
116  if(0 == m_sigreg.length)
117  {
118  flags = (flags_t*) heap_malloc(m_heap_id, size);
119  }
120  else
121  {
122  flags = (flags_t*) heap_realloc(m_sigreg.registry, size );
123  }
124 
125  // Check if allocation was successful
126  if(NULL != flags)
127  {
128  // Update signal-registry administration and initialize new item
129  m_sigreg.registry = flags;
130  m_sigreg.length++;
131  m_sigreg.registry[i].flags = NULL;
132  m_sigreg.registry[i].length = 0;
133 
134  // Pass new signal back to caller with an offset so that no signal
135  // ID of 0 can exist.
136  *signal = i + 1;
137  retval = true;
138  }
139  }
140 
141  return retval;
142 }
143 
144 
145 bool
146 signal_create_flag( flag_t * flag )
147 {
148  bool retval = false;
149  counter_t *counters = NULL;
150  size_t size = sizeof(counter_t);
151  counter_t i = m_counters.length;
152 
153  // First, invalidate flag
154  *flag = 0;
155 
156  // Calculate total memory to allocate the new 'counter_t' included
157  size *= i + 1;
158 
159  // Allocate the required memory
160  if(0 == m_counters.length)
161  {
162  counters = (counter_t*) heap_malloc(m_heap_id, size);
163  }
164  else
165  {
166  counters = (counter_t*) heap_realloc(m_counters.counters, size );
167  }
168 
169  // Check if allocation was successful
170  if(NULL != counters)
171  {
172  // Update flag counter administration and initialize new item
173  m_counters.counters = counters;
174  m_counters.length++;
175  m_counters.counters[i] = 0;
176 
177  // Pass new flag back to caller with an offset so that no flag ID of 0
178  // can exist.
179  *flag = i + 1;
180  retval = true;
181  }
182 
183  return retval;
184 }
185 
186 
187 bool
188 signal_connect( signal_t signal, flag_t flag )
189 {
190  bool retval = false;
191  flag_t *flags = NULL;
192  size_t size = sizeof(flag_t);
193  counter_t i = 0;
194 
195  // Check for existing signal
196  if(signal_valid(signal) && signal_flag_valid(flag))
197  {
198  // Calculate total memory to allocate the new 'counter_t' included
199  i = m_sigreg.registry[signal-1].length;
200  size *= i + 1;
201 
202  // Check if given connection is present for given signal and flag
203  retval = signal_flag_connected(signal, flag);
204 
205  // No connection yet? Create one
206  if(false == retval)
207  {
208  // Allocate the required memory
209  if(0 == m_sigreg.registry[signal-1].length)
210  {
211  flags = (flag_t*) heap_malloc(m_heap_id, size);
212  }
213  else
214  {
215  flags = (flag_t*) heap_realloc(
216  m_sigreg.registry[signal-1].flags, size);
217  }
218 
219  // Check if allocation was successful
220  if(NULL != flags)
221  {
222  // Update signal-registry
223  m_sigreg.registry[signal-1].flags = flags;
224  m_sigreg.registry[signal-1].flags[i] = flag;
225  m_sigreg.registry[signal-1].length++;
226  retval = true;
227  }
228  }
229  }
230 
231  return retval;
232 }
233 
234 
235 void
236 signal_reset_connections(signal_t signal)
237 {
238  // Check for existing signal
239  if(signal_valid(signal))
240  {
241  // Free flags connected to this signal
242  heap_free(m_sigreg.registry[signal-1].flags);
243  m_sigreg.registry[signal-1].flags = NULL;
244  m_sigreg.registry[signal-1].length = 0;
245  }
246 }
247 
248 
249 void
250 signal_emit(signal_t signal)
251 {
252  signal_t i;
253  flag_t flag;
254 
255  // Check for existing signal
256  if(signal_valid(signal))
257  {
258  for( i=0 ; i<m_sigreg.registry[signal-1].length ; i++ )
259  {
260  // Get the registered flag(s) for this signal
261  flag = m_sigreg.registry[signal-1].flags[i];
262  // Set the flag
263  signal_flag_set(flag);
264  }
265  }
266 }
267 
268 
269 void
270 signal_emit_delayed(signal_t signal, uint_base_t delay)
271 {
272  alarm_set(delay, signal);
273 }
274 
275 
276 bool
277 signal_flag_isset(flag_t flag)
278 {
279  bool retval = false;
280 
281  if(signal_flag_valid(flag))
282  {
283  retval = (m_counters.counters[flag-1] > 0);
284  }
285 
286  return retval;
287 }
288 
289 
290 void
291 signal_flag_clear(flag_t flag)
292 {
293  if(signal_flag_valid(flag))
294  {
295  m_counters.counters[flag-1]--;
296  }
297 }
298 
299 
300 void
301 signal_flag_reset(flag_t flag)
302 {
303  if(signal_flag_valid(flag))
304  {
305  m_counters.counters[flag-1] = 0;
306  }
307 }
308 
309 
310 /* PRIVATE FUNCTIONS **********************************************************/
311 
312 void
313 signal_flag_set(flag_t flag)
314 {
315  if(signal_flag_valid(flag) )
316  {
317  m_counters.counters[flag-1]++;
318  }
319 }
320 
321 
322 bool
323 signal_flag_valid(flag_t flag)
324 {
325  return (flag > 0) && (flag <= m_counters.length);
326 }
327 
328 
329 bool
330 signal_valid(signal_t signal)
331 {
332  return (signal > 0) && (signal <= m_sigreg.length);
333 }
334 
335 
336 bool
337 signal_flag_connected(signal_t signal, flag_t flag)
338 {
339  bool retval = false;
340  counter_t i = 0;
341 
342  if(signal_valid(signal) && signal_flag_valid(flag))
343  {
344  for( i=0 ; i<m_sigreg.registry[signal-1].length ; i++ )
345  {
346  if(m_sigreg.registry[signal-1].flags[i] == flag)
347  {
348  retval = true;
349  break;
350  }
351  }
352  }
353 
354  return retval;
355 }