Multi-ApplicationOnlineProfiling  2.1
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
MALP_Blackboard.c
Go to the documentation of this file.
1 /* ############################ MALP License ############################## */
2 /* # Fri Jan 18 14:00:00 CET 2013 # */
3 /* # Copyright or (C) or Copr. Commissariat a l'Energie Atomique # */
4 /* # # */
5 /* # This software is governed by the CeCILL-C license under French law # */
6 /* # and abiding by the rules of distribution of free software. You can # */
7 /* # use, modify and/ or redistribute the software under the terms of # */
8 /* # the CeCILL-C license as circulated by CEA, CNRS and INRIA at the # */
9 /* # following URL http://www.cecill.info. # */
10 /* # # */
11 /* # The fact that you are presently reading this means that you have # */
12 /* # had knowledge of the CeCILL-C license and that you accept its # */
13 /* # terms. # */
14 /* # # */
15 /* # Authors: # */
16 /* # - BESNARD Jean-Baptiste jean-baptiste.besnard@cea.fr # */
17 /* # # */
18 /* ######################################################################## */
19 #include "MALP_Blackboard.h"
20 
21 #include <string.h>
22 
23 void MALP_blackboard_init( struct MALP_blackboard *bb, uint32_t workers_count, void *context )
24 {
26  bb->context = context;
27  Hash_Table_init( &bb->ks_table, sizeof( struct Ks_cell ), 4241, KS_COLL_AVOID );
28  Hash_Table_init( &bb->key_table, sizeof( struct Key_cell ), 4241, KEY_COLL_AVOID );
29  Hash_Table_init( &bb->de_name_table, sizeof( struct Name_cell ), 4241, NAME_COLL_AVOID );
30 
32 
33  bb->cpu_count = sysconf( _SC_NPROCESSORS_ONLN );
34 
35  Pbb_workers_init( &bb->workers, bb, workers_count?workers_count:bb->cpu_count );
36 
37  bb->pending_datas = 0;
38  bb->lock = 0;
39  bb->default_handler = NULL;
40 }
41 
42 
43 void free_ks(void *pks)
44 {
45  struct Knowledge_system *ks = (struct Knowledge_system *)pks;
47 }
48 
49 void free_key_ent(void *pke)
50 {
51  struct Key_entry *ke = (struct Key_entry *)pke;
52  Key_entry_release( ke );
53 }
54 
55 void free_name(void *pn)
56 {
57  free( pn );
58 }
59 
60 
62 {
67 
68  bb->lock = 1;
69  bb->default_handler = NULL;
70 }
71 
73 {
74  Pbb_workers_wait( &bb->workers );
75 }
76 
77 
78 int knowledge_system_test_func(void *pks, uint64_t key, void *arg)
79 {
80  struct Knowledge_system *ks = (struct Knowledge_system *)pks;
81 
82  if( ks->type == key )
83  return 1;
84 
85  return 0;
86 }
87 
88 int empty_knowledge_system_test_func(void *pks, uint64_t key, void *arg)
89 {
90  /* Do we have freed KS in this bucket */
91  struct Knowledge_system *ks = (struct Knowledge_system *)pks;
92 
93  if( ks->freed == 1 )
94  return 1;
95 
96  return 0;
97 }
98 
99 int key_entry_test_func(void *pke, uint64_t key, void *arg)
100 {
101  struct Key_entry *ke = (struct Key_entry *)pke;
102 
103  if( ke->key == key )
104  return 1;
105 
106  return 0;
107 }
108 
109 int empty_key_entry_test_func(void *pke, uint64_t key, void *arg)
110 {
111  /* Do we have freed KE in this bucket */
112  struct Key_entry *ke = (struct Key_entry *)pke;
113 
114  if( ke->freed == 1 )
115  return 1;
116 
117  return 0;
118 }
119 
120 struct Key_entry* MALP_Blackboard_get_ke( struct MALP_blackboard *bb, uint64_t key )
121 {
122  struct Key_entry* ret = Hash_Table_get( &bb->key_table, key, NULL, key_entry_test_func );
123  return ret;
124 }
125 
127 {
128  struct Key_entry *ret = Hash_Table_get( &bb->key_table, key, NULL, key_entry_test_func );
129 
130  if( ret )
131  {
132  return ret;
133  }
134  else
135  {
136  struct Key_entry ke;
137  Key_entry_init( &ke, key );
138 
139  ret = Hash_Table_get( &bb->key_table, key, NULL, empty_key_entry_test_func );
140  if( ret == NULL )
141  {
142  ret = Hash_Table_push( &bb->key_table, (void *)&ke , key );
143  }
144  else
145  {
146  memcpy( ret, &ke, sizeof( struct Key_entry ) );
147  }
148  }
149 
150  return ret;
151 }
152 
153 
154 
155 
157 {
159 
160  if( ret )
161  {
162  memcpy( ret, ks, sizeof( struct Knowledge_system ) );
163  }
164  else
165  {
166  ret = Hash_Table_push( &bb->ks_table, (void *)ks , ks->type );
167  }
168 
169  return ret;
170 }
171 
173 {
174  struct Knowledge_system *existing_ks = Hash_Table_get( &bb->ks_table, type, NULL, knowledge_system_test_func );
175 
176  if( existing_ks )
177  return 1;
178 
179  return 0;
180 }
181 
182 struct Knowledge_system * MALP_Blackboard_new_ks( struct MALP_blackboard *bb, uint64_t type, uint64_t *sensivities,
183  uint32_t sensivities_count, void (*process)( struct MALP_blackboard *bb, struct Data_entry **de, uint32_t entry_count, void *arg ), void *arg )
184 {
185  struct Knowledge_system *existing_ks = NULL;
186 
187  MALP_Spinlock_lock( &bb->lock );
188  {
189  /* Check if it is not already registered */
190  existing_ks = Hash_Table_get( &bb->ks_table, type, NULL, knowledge_system_test_func );
191 
192  if( existing_ks != NULL )
193  {
194  return existing_ks;
195  }
196 
197  /* If not create a new Ks */
198  struct Knowledge_system ks;
199  Knowledge_system_init( &ks, type, sensivities, sensivities_count, process, arg );
200 
201  /* Push it to Ks list */
202  existing_ks = MALP_Blackboard_push_ks( bb, &ks );
203 
204  /* Register in key entries */
205  int i = 0;
206  for( i = 0 ; i < sensivities_count ; i++ )
207  {
208  struct Key_entry *ke = MALP_Blackboard_push_unique_ke( bb, sensivities[i] );
209  Key_entry_push_ks( ke, existing_ks );
210  }
211  }
212  MALP_Spinlock_unlock( &bb->lock );
213 
214  return existing_ks;
215 }
216 
217 
218 void __MALP_Blackboard_delete_ks(void *pke, void *pks)
219 {
220  struct Key_entry *ke = (struct Key_entry *)pke;
221  struct Knowledge_system *ks = (struct Knowledge_system *)pks;
222 
223  Key_entry_pop_ks( ke, ks );
224 }
225 
226 void MALP_Blackboard_delete_ks( struct MALP_blackboard *bb, uint64_t type )
227 {
228  MALP_Spinlock_lock( &bb->lock );
229  {
230  /* Check if KS exists */
231  struct Knowledge_system *existing_ks = Hash_Table_get( &bb->ks_table, type, NULL, knowledge_system_test_func );
232 
233  if( existing_ks == NULL )
234  {
235  /* No such KS */
236  return;
237  }
238 
239  /* If it does unregister Ks in Key entries */
241 
242 
243  /* Free it */
244  Knowledge_system_release( existing_ks );
245 
246  }
247  MALP_Spinlock_unlock( &bb->lock );
248 }
249 
250 
252 {
253  /* Increment the refcount of the number of KS in this key */
255 }
256 
261 {
262  struct Data_entry *de;
263  struct MALP_blackboard *bb;
264 };
265 
266 int ke_submit_handler( struct Knowledge_system *ks, void *pbbsb)
267 {
268  struct MALP_BB_submit *bb_sb = (struct MALP_BB_submit *)pbbsb;
270 
271  Pbb_workers_submit( &bb_sb->bb->workers, &job );
272 
273  return 0;
274 }
275 
276 void MALP_Blackboard_submit_to_ke_ks( struct MALP_blackboard *bb, struct Key_entry *ke, struct Data_entry *de )
277 {
278  struct MALP_BB_submit bb_sb = { de , bb };
279  Key_entry_walk( ke, ke_submit_handler, (void *)&bb_sb );
280 }
281 
282 
284 {
285  if( !de )
286  return 1;
287 
288  if( Data_entry_get_ref_count( de ) )
289  {
290  printf("Cannot resubmit a data entry without a null refcount\n");
291  abort();
292  }
293 
294 
295  struct Key_entry *ke = MALP_Blackboard_get_ke( bb, de->key );
296 
297  //printf("KEY : %llX Got KE : %p\n", de->key , ke );
298 
299  /* Update refcount */
300  if( ke )
301  {
303  de->been_resubmitted = 1;
304  /* Submit to KS now that all refcount were summed */
305  MALP_Blackboard_submit_to_ke_ks( bb, ke, de );
306  }
307 
308  return ( ke == NULL )?0:1;
309 }
310 
312 {
313  if( !de )
314  return 1;
315 
316  struct Key_entry *ke = MALP_Blackboard_get_ke( bb, de->key );
317 
318 
319  /* Update refcount */
320  if( ke )
321  {
322  de->been_resubmitted = 0;
324 
325  /* We have a new pending data */
327 
328  //printf("Submitting DE @ %llX\n", de->key );
329 
330  /* Submit to KS now that all refcount were summed */
331  MALP_Blackboard_submit_to_ke_ks( bb, ke, de );
332  }
333 
334  return ( ke == NULL )?0:1;
335 }
336 
337 
338 
339 int MALP_Blackboard_submit_data( struct MALP_blackboard *bb, uint64_t key, void *payload, size_t payload_size )
340 {
341  struct Data_entry *de = NULL;
342 
343  struct Key_entry *ke = MALP_Blackboard_get_ke( bb, key );
344 
345  /* Update refcount */
346  if( ke )
347  {
348  de = Data_entry_init( key, payload, payload_size );
349 
351 
352  //printf("Submitting DATA @ %llX\n", key );
353 
354  /* We have a new pending data */
356 
357  /* Submit to KS now that all refcount were summed */
358  MALP_Blackboard_submit_to_ke_ks( bb, ke, de );
359  }
360 
361 
362  return (de == NULL)?0:1;
363 }
364 
int knowledge_system_test_func(void *pks, uint64_t key, void *arg)
knowledge_system_test_func
void MALP_blackboard_init(struct MALP_blackboard *bb, uint32_t workers_count, void *context)
MALP_blackboard initialisation.
void free_name(void *pn)
int MALP_Blackboard_submit_data_entry(struct MALP_blackboard *bb, struct Data_entry *de)
MALP_Blackboard_submit_data_entry.
#define KS_COLL_AVOID
Number of KS cells (Number of elements)
static void Hash_Table_use_lock(struct Hash_Table *ht)
Indicates that the hashtable must use a lock for operations (get/push)
Definition: Hash_Table.h:66
struct Knowledge_system_job Knowledge_system_submit_data_entry(struct Knowledge_system *ks, struct Data_entry *de)
Knowledge_system_submit_data_entry.
void MALP_Blackboard_delete_ks(struct MALP_blackboard *bb, uint64_t type)
MALP_Blackboard_delete_ks.
void __MALP_Blackboard_delete_ks(void *pke, void *pks)
The Knowledge_system structure.
void MALP_Blackboard_submit_to_ke_ks(struct MALP_blackboard *bb, struct Key_entry *ke, struct Data_entry *de)
void Key_entry_push_ks(struct Key_entry *ke, struct Knowledge_system *ks)
associates a Knowledge_system to a key entry
Definition: Key_Entry.c:93
struct Hash_Table ks_table
The Knowledge system cell structure Structure containing an internal hash table and table of knowledg...
struct Hash_Table de_name_table
Temporary datastructure.
struct Key_entry * MALP_Blackboard_push_unique_ke(struct MALP_blackboard *bb, uint64_t key)
void free_key_ent(void *pke)
void Key_entry_pop_ks(struct Key_entry *ke, struct Knowledge_system *ks)
Removes an association between a Knowledge_system and its key.
Definition: Key_Entry.c:123
void * Hash_Table_push(struct Hash_Table *ht, void *payload, uint64_t key)
adds an element to a hashtable
Definition: Hash_Table.c:198
short been_resubmitted
1 if it has been re-submitted
Definition: Data_Entry.h:43
int MALP_Blackboard_ks_present(struct MALP_blackboard *bb, uint64_t type)
test if a knowledge system is available in a MALP_Blackboard Test if a knowledge system of a specific...
uint64_t key
the key identifier
Definition: Key_Entry.h:39
int MALP_Spinlock_unlock(MALP_Spinlock *mutex)
Unlocks the given MALP_Spinlock.
Definition: Spinlock.c:41
void MALP_blackboard_release(struct MALP_blackboard *bb)
MALP_blackboard release.
struct representing a job that does the actual data processing (created by Knowledge_system) ...
void Key_entry_init(struct Key_entry *ke, uint64_t key)
Init a key entry with given key.
Definition: Key_Entry.c:26
void(* default_handler)(struct MALP_blackboard *, uint64_t KS_id, struct Data_entry **, uint32_t, void *arg)
void Key_entry_walk(struct Key_entry *ke, int(*handler)(struct Knowledge_system *, void *), void *arg)
Call a handler on every Ks of a key entry.
Definition: Key_Entry.c:213
The MALP_blackboard structure.
void free_ks(void *pks)
struct Hash_Table key_table
struct Knowledge_system * MALP_Blackboard_new_ks(struct MALP_blackboard *bb, uint64_t type, uint64_t *sensivities, uint32_t sensivities_count, void(*process)(struct MALP_blackboard *bb, struct Data_entry **de, uint32_t entry_count, void *arg), void *arg)
Create a new Knowledge system while associating a key (used as an id and a type) and a handler (proce...
void(* process)(struct MALP_blackboard *bb, struct Data_entry **de, uint32_t entry_count, void *arg)
uint64_t key
the key, identifying the type of data
Definition: Data_Entry.h:39
void MALP_blackboard_wait(struct MALP_blackboard *bb)
MALP_blackboard_wait Function to call the wait function for the Pbb workers of a MALP blackboard...
void Hash_Table_init(struct Hash_Table *ht, size_t sizeof_payload, uint64_t table_size, uint8_t coll_avoid)
Hash_Table initialization.
Definition: Hash_Table.c:40
int MALP_Blackboard_submit_data(struct MALP_blackboard *bb, uint64_t key, void *payload, size_t payload_size)
MALP_Blackboard_submit_data.
void Hash_Table_walkthrought_2p(struct Hash_Table *ht, void *second_arg, void(*action)(void *, void *))
Executes a function on every stored elements.
Definition: Hash_Table.c:385
MALP_Spinlock lock
void * Hash_Table_get(struct Hash_Table *ht, uint64_t key, void *extra_arg, int(*test_func)(void *, uint64_t, void *))
retrieves an element from the hashtable
Definition: Hash_Table.c:128
int MALP_Blackboard_resubmit_data_entry(struct MALP_blackboard *bb, struct Data_entry *de)
MALP_Blackboard_resubmit_data_entry.
static void MALP_Blackboard_add_pending(struct MALP_blackboard *bb)
Increments the number of pending data block counter.
static uint64_t Data_entry_get_ref_count(struct Data_entry *de)
Getter on the ref_count of a Data_entry.
Definition: Data_Entry.h:94
The Name_cell structure Structure containing an internal hash table and table of cell names...
void MALP_Blackboard_compute_de_refcount(struct Key_entry *ke, struct Data_entry *de)
void Hash_Table_release(struct Hash_Table *ht, void(*free_f)(void *))
Hash_Table release.
Definition: Hash_Table.c:67
int MALP_Spinlock_lock(MALP_Spinlock *mutex)
Locks the given MALP_Spinlock.
Definition: Spinlock.c:29
struct Data_entry * Data_entry_init(uint64_t key, void *payload, size_t size)
Creates a new Data_entry.
Definition: Data_Entry.c:25
int ke_submit_handler(struct Knowledge_system *ks, void *pbbsb)
int empty_key_entry_test_func(void *pke, uint64_t key, void *arg)
empty_key_entry_test_func
void Pbb_workers_wait(struct Pbb_workers *wk)
Waits until all workers are done.
Definition: Pbb_Workers.c:241
void Knowledge_system_release(struct Knowledge_system *ks)
Knowledge_system release.
int key_entry_test_func(void *pke, uint64_t key, void *arg)
key_entry_test_func
int empty_knowledge_system_test_func(void *pks, uint64_t key, void *arg)
empty_knowledge_system_test_func
struct Key_entry * MALP_Blackboard_get_ke(struct MALP_blackboard *bb, uint64_t key)
struct Knowledge_system * MALP_Blackboard_push_ks(struct MALP_blackboard *bb, struct Knowledge_system *ks)
Struct defining a piece of data that can exist on the blackboard.
Definition: Data_Entry.h:37
The Key_cell structure Structure containing an internal hash table and table of key entries ( Key ent...
void Pbb_workers_submit(struct Pbb_workers *wk, struct Knowledge_system_job *ksj)
sumbits a job on workers
Definition: Pbb_Workers.c:226
The Key_entry struct.
Definition: Key_Entry.h:35
#define KEY_COLL_AVOID
Number of column keys (Number of elements)
void Key_entry_release(struct Key_entry *ke)
Clears a key entry.
Definition: Key_Entry.c:35
uint8_t freed
set to one when the entry is released, 0 otherwise
Definition: Key_Entry.h:40
static void Data_entry_inc_ref_count(struct Data_entry *de, uint64_t val)
Increments the ref_count of a Data_entry by a given value.
Definition: Data_Entry.h:112
struct Pbb_workers workers
#define NAME_COLL_AVOID
Number of column names (Number of elements)
void Pbb_workers_init(struct Pbb_workers *wk, struct MALP_blackboard *bb, uint32_t wk_count)
Initializes workers.
Definition: Pbb_Workers.c:169
void Knowledge_system_init(struct Knowledge_system *ks, uint64_t type, uint64_t *sensivity_keys, uint32_t sensivity_count, void(*process)(struct MALP_blackboard *bb, struct Data_entry **de, uint32_t entry_count, void *arg), void *arg)
Initializes a Knowledge_system.
void Pbb_workers_release(struct Pbb_workers *wk)
releases workers
Definition: Pbb_Workers.c:203
struct Data_entry * de
the data entry
volatile uint64_t pending_datas
int Key_entry_get_count(struct Key_entry *ke)
Get the number of Ks in this entry.
Definition: Key_Entry.c:153
struct MALP_blackboard * bb
the blackboard
void MALP_Trace_crc64_init()
This initializes the CRC64 internals.
Definition: CRC64.c:26