Multi-ApplicationOnlineProfiling  2.1
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
Knowledge_System.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 "Knowledge_System.h"
20 #include "Data_Entry.h"
21 #include "CRC64.h"
22 
23 
24 
25 
26 
27 void Knowledge_system_init( struct Knowledge_system *ks, uint64_t type, uint64_t *sensivity_keys, uint32_t sensivity_count,
28  void (*process)( struct MALP_blackboard *bb, struct Data_entry **de, uint32_t entry_count, void *arg ), void *arg )
29 {
30 
31  ks->type = type;
32  ks->lock = 0;
33 
35 
36  if( sensivity_count == 0 )
37  {
38  printf("Cannot create a KS with sensitity 0 ! \n");
39  abort();
40  }
41 
42  ks->sensivity_keys = malloc( ks->sensivity_count * sizeof( uint64_t ) );
43 
44  if( !ks->sensivity_keys )
45  {
46  perror( "malloc" );
47  abort();
48  }
49 
50  memcpy( ks->sensivity_keys, sensivity_keys, ks->sensivity_count * sizeof( uint64_t ) );
51 
52  ks->sensivity_array = malloc( ks->sensivity_count * sizeof( uint64_t ) );
53 
54  if( !ks->sensivity_array )
55  {
56  perror( "malloc" );
57  abort();
58  }
59 
60  ks->data_entries = malloc( ks->sensivity_count * sizeof( struct Buffered_FIFO ) );
61 
62  if( !ks->data_entries )
63  {
64  perror( "malloc" );
65  abort();
66  }
67 
68  int i = 0;
69 
70  for( i = 0 ; i < ks->sensivity_count ; i++ )
71  {
72  Buffered_FIFO_init( &ks->data_entries[i], 10, sizeof(struct Data_entry *) );
73  ks->sensivity_array[i] = 0;
74  }
75 
76  ks->process = process;
77  ks->arg = arg;
78  ks->freed = 0;
79 }
80 
81 
83 {
84  ks->type = 0;
85  ks->lock = 1;
86 
87  int i = 0;
88  for( i = 0 ; i < ks->sensivity_count ; i++ )
89  Buffered_FIFO_release( &ks->data_entries[i], NULL );
90 
91  free( ks->data_entries );
92  ks->data_entries = NULL;
93 
94  ks->sensivity_count = 0;
95 
96  free( ks->sensivity_keys );
97  ks->sensivity_keys = NULL;
98 
99  free( ks->sensivity_array );
100  ks->sensivity_array = NULL;
101 
102  ks->process = NULL;
103  ks->arg = NULL;
104  ks->freed = 1;
105 
106 }
107 
108 void Knowledge_system_set_process( struct Knowledge_system *ks, void (*process)( struct MALP_blackboard *bb, struct Data_entry **de, uint32_t entry_count, void *arg ), void *arg )
109 {
110 
111  MALP_Spinlock_lock( &ks->lock );
112  {
113  ks->process = process;
114  ks->arg = arg;
115  }
116  MALP_Spinlock_unlock( &ks->lock );
117 }
118 
119 
121 {
122 
123  MALP_Spinlock_lock( &ks->lock );
124  {
125  ks->is_serial = is_serial;
126  }
127  MALP_Spinlock_unlock( &ks->lock );
128 }
129 
130 
131 
133 {
134  /* Check if all the requirements are satisfied to submit a job */
135  int i = 0;
136  for( i = 0 ; i < ks->sensivity_count; i++ )
137  {
138  if( ks->sensivity_array[i] == 0 )
139  {
140  return 1;
141  }
142  }
143 
144  return 0;
145 }
146 
148 {
149  struct Knowledge_system_job ret;
150  /* Create an empty job */
151  memset( &ret, 0, sizeof( struct Knowledge_system_job ) );
152 
153  MALP_Spinlock_lock( &ks->lock );
154  {
155  int local_id = -1;
156  int i = 0;
157  /* Find the right id for current key */
158  for( i = 0 ; i < ks->sensivity_count ; i++ )
159  {
160  if( ( de->key == ks->sensivity_keys[i] )
161  && ( ks->sensivity_array[i] == 0 ) ) /* We allow multiple sensivities of the same type */
162  {
163  local_id = i;
164  break;
165  }
166  }
167 
168  /* If no local ID search sensivities again without multiple sensivites of the same type */
169  if( local_id < 0 )
170  {
171  for( i = 0 ; i < ks->sensivity_count ; i++ )
172  {
173  if( de->key == ks->sensivity_keys[i] )
174  {
175  local_id = i;
176  break;
177  }
178  }
179  }
180 
181  /* This data entry is acceptable */
182  if( 0 <= local_id )
183  {
184 
185  /* Store the Data Entry reference */
186  Buffered_FIFO_push( &ks->data_entries[local_id], (void *)&de );
187  /* Increment sensivity array */
188  ks->sensivity_array[local_id]++;
189 
190  /* All sensivities ready to process and we have a handler */
191 
193  {
194  ret = Knowledge_system_job_new( ks );
195  }
196  }
197 
198  }
199  MALP_Spinlock_unlock( &ks->lock );
200  return ret;
201 }
202 
203 
205 {
206  struct Knowledge_system_job ret;
207 
208  ret.ks_type = ks->type;
209  ret.process = ks->process;
210  ret.arg = ks->arg;
211  ret.entries_count = ks->sensivity_count;
212 
213  /* See if this job is serial */
214  ret.is_serial = ks->is_serial;
215 
216  if( ks->sensivity_count )
217  {
218  ret.entries = malloc( ks->sensivity_count * sizeof( struct Data_entry * ) );
219  if( !ret.entries )
220  {
221  perror( "malloc" );
222  abort();
223  }
224 
225  /* Fill the entry list */
226  int i = 0;
227  for( i = 0 ; i < ks->sensivity_count ; i++ )
228  {
229  struct Data_entry *tmp = NULL;
230  if( !Buffered_FIFO_pop( &ks->data_entries[i], (void *)&tmp ) )
231  {
232  /* We failled to request an element => sensivity list was not FULL */
233  abort();
234  }
235  else
236  {
237  ks->sensivity_array[i]--;
238  }
239  ret.entries[i] = tmp;
240  }
241  }
242  else
243  {
244  ret.entries = NULL;
245  }
246 
247  return ret;
248 }
249 
250 
252 {
253  if( !ksj )
254  return;
255 
256  free( ksj->entries );
257  memset( ksj, 0, sizeof( struct Knowledge_system_job ) );
258 }
uint64_t * sensivity_array
struct Buffered_FIFO * data_entries
struct Knowledge_system_job Knowledge_system_job_new(struct Knowledge_system *ks)
Knowledge_system_job_new.
struct Data_entry ** entries
struct Knowledge_system_job Knowledge_system_submit_data_entry(struct Knowledge_system *ks, struct Data_entry *de)
Knowledge_system_submit_data_entry.
MALP_Spinlock lock
uint32_t sensivity_count
The Knowledge_system structure.
void Buffered_FIFO_release(struct Buffered_FIFO *fifo, void(*free_func)(void *))
releases a FIFO
This is a struct defining a FIFO It is composed of several Buffered_FIFO_chunk.
void * Buffered_FIFO_push(struct Buffered_FIFO *fifo, void *elem)
Pushes an element into a FIFO.
void * Buffered_FIFO_pop(struct Buffered_FIFO *fifo, void *dest)
Pops an element from a FIFO.
void Knowledge_system_set_serial(struct Knowledge_system *ks, int is_serial)
sets the parallelism mode for this KS
int MALP_Spinlock_unlock(MALP_Spinlock *mutex)
Unlocks the given MALP_Spinlock.
Definition: Spinlock.c:41
struct representing a job that does the actual data processing (created by Knowledge_system) ...
The MALP_blackboard structure.
void(* process)(struct MALP_blackboard *bb, struct Data_entry **de, uint32_t entry_count, void *arg)
void Knowledge_system_set_process(struct Knowledge_system *ks, void(*process)(struct MALP_blackboard *bb, struct Data_entry **de, uint32_t entry_count, void *arg), void *arg)
sets the processing function to a Knowledge_system
int MALP_Spinlock_lock(MALP_Spinlock *mutex)
Locks the given MALP_Spinlock.
Definition: Spinlock.c:29
int Knowledge_system_has_unsatisfied_sensivities(struct Knowledge_system *ks)
Knowledge_system_has_unsatisfied_sensivities.
void Knowledge_system_release(struct Knowledge_system *ks)
Knowledge_system release.
void(* process)(struct MALP_blackboard *bb, struct Data_entry **de, uint32_t entry_count, void *arg)
uint64_t ks_type
the type of Knowledge_system
void Buffered_FIFO_init(struct Buffered_FIFO *fifo, uint64_t chunk_size, size_t elem_size)
Initializes a Buffered_FIFO.
Struct defining a piece of data that can exist on the blackboard.
Definition: Data_Entry.h:37
uint64_t * sensivity_keys
void Knowledge_system_job_release(struct Knowledge_system_job *ksj)
Knowledge_system_job_release.
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.