TSP: The Transport Sample Protocol



Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

bb_tsp_provider.c

Go to the documentation of this file.
00001 
00037 #include "bb_core.h"
00038 #include "bb_simple.h"
00039 #define BB_TSP_PROVIDER_C
00040 #include "bb_tsp_provider.h"
00041 
00042 #include "tsp_provider_init.h"
00043 #include "tsp_datapool.h"
00044 
00045 /*
00046  * Declaration crado pour demarrage TSP en douceur
00047  */
00048 int TSP_provider_rqh_manager_get_nb_running();
00049 
00050 /* 
00051  * On inclu les en-têtes TSP
00052  * necessaire a l'implementation d'un GLU
00053  * car on doit réaliser ces fonctions dans
00054  * notre provider TSP.
00055  * Consulter le header 'glue_sserver.h' afin de comprendre
00056  * la réalisation des différentes fonctions.
00057  */
00058 #include <tsp_sys_headers.h>
00059 #include <glue_sserver.h>
00060 #include <tsp_ringbuf.h>
00061 
00062 #include <signal.h>
00063 
00064 /* RINGBUF_DECLARE_TYPE_DYNAMIC(glu_ringbuf,glu_item_t); */
00065 
00066 #define GLU_RING_BUFSIZE (1000 * 64 * 10)
00067 
00068 /*
00069  * Quelques variables static
00070  */
00071 /* le nom du provider */
00072 static char* X_server_name = "BB-TSP-V0_2";
00073 /* le ringbuffer entre le GLU et le reste du monde */
00074 /* static glu_ringbuf* glu_ring = 0; */
00075 /* la liste des symboles */
00076 static TSP_sample_symbol_info_t *X_sample_symbol_info_list_val = NULL;
00077 
00078 /* The BB and its shadow BB */
00079 static S_BB_T* the_bb = NULL;
00080 static char* the_bbname = NULL;
00081 static S_BB_T* shadow_bb = NULL;
00082 
00083 /* Le time stamp time du GLU */
00084 static time_stamp_t glu_time = 0;
00085 /* Tableau des adresses des valeurs dans le shadow BB indexé par
00086  * le provider_global_index
00087  */
00088 static void** value_by_pgi = NULL;
00089 static E_BB_TYPE_T * bbtype_by_pgi = NULL;
00090 /*
00091  * La frequence de base du provider devra être celle
00092  * du simulateur qui sera disponible dans le blackboard
00093  * a defaut on en fourni une fictive.
00094  */
00095 static double frequence_provider = 64.0;
00096 static double* bb_tsp_provider_frequency = &frequence_provider;
00097 
00098 int GLU_set_base_frequency(double d_frequence_provider) {
00099   *bb_tsp_provider_frequency = d_frequence_provider;
00100   return 0;
00101 }
00102 
00103 char* 
00104 GLU_get_server_name() {
00105   return X_server_name;
00106 }
00107 
00108 
00109 int 
00110 GLU_init(int fallback_argc, char* fallback_argv[]) {
00111 
00112   int retcode;
00113   int i;
00114   int j;
00115   int i_temp;
00116   int i_pg_index;
00117   int i_nb_item_scalaire;
00118 
00119   retcode = TRUE;
00120   /* Le TID du GLU_thread */
00121   glu_thread_id = 0;
00122   /* On n'a rien a faire des fallback pour l'instant */
00123   /* 
00124    * !!! On n'a besoin de s'attacher au BB seulement 
00125    * !!! si on est un process separe de celui qui le crée
00126    */
00127   if (bb_attach(&the_bb,the_bbname) != E_OK) {
00128     bb_logMsg(BB_LOG_SEVERE,
00129               "bb_tsp_provider::GLU_init","Cannot attach to BlackBoard <%s>!!",
00130               the_bbname);
00131     retcode = FALSE;
00132   } 
00133   
00134   /* 
00135    * Récupère un acces direct au blackboard 
00136    * afin de construire la liste des variables
00137    * plus simplement.
00138    */
00139   if (TRUE == retcode) {
00140     /* Allocation du shadow blackboard */
00141     shadow_bb = malloc(bb_get_mem_size(the_bb));
00142     if (NULL == shadow_bb) {
00143       retcode = FALSE;
00144     }
00145   }
00146   if (TRUE == retcode) {
00147     /* Shadow BBPE */
00148     if (E_NOK == bb_shadow_get(shadow_bb, the_bb)) {
00149       retcode = FALSE;
00150     }  
00151   }
00152   if (TRUE == retcode) {
00153     /* Initial update (ce qui est inutile mais ça ne gate rien */
00154     if (E_NOK ==  bb_shadow_update_data(shadow_bb,the_bb)) {
00155       retcode = FALSE;
00156     } 
00157   }
00158 
00159   /* Construction de la liste des symboles */
00160   /* On doit calculer le nombre d'item SCALAIRE 
00161    * car TSP ne gère pas [encore] les tableaux
00162    */
00163   i_nb_item_scalaire = 0;
00164   for (i=0;i<bb_get_nb_item(shadow_bb);++i) {
00165     /* we skip unhandled BB_TYPE */
00166     if (bb_data_desc(shadow_bb)[i].type < E_BB_CHAR) {
00167       i_nb_item_scalaire += bb_data_desc(shadow_bb)[i].dimension;
00168     }
00169   }
00170   /* On alloue une liste de symboles de la taille
00171    * correspondant au nombre de données (scalaire) enregistrées dans le BB
00172    */
00173   X_sample_symbol_info_list_val = calloc (i_nb_item_scalaire,
00174                                           sizeof (TSP_sample_symbol_info_t));
00175   assert(X_sample_symbol_info_list_val);
00176   /* On alloue 
00177    * le tableau de pointeurs vers les données
00178    */
00179   value_by_pgi = (void **) calloc(i_nb_item_scalaire,sizeof(void*));
00180   bbtype_by_pgi = (E_BB_TYPE_T *) calloc(i_nb_item_scalaire,sizeof(E_BB_TYPE_T));
00181 
00182   assert(value_by_pgi); 
00183   /* on initialise le provider global index a 0 */
00184   i_pg_index = 0;
00185   for (i=0; i<bb_get_nb_item(shadow_bb);++i) {
00186     /* TSP ne gère pas encore les tableaux
00187      * donc on génère des noms de symboles postfixés par
00188      * l'index du tableau [%d]
00189      */
00190     /* we skip unhandled BB_TYPE */ 
00191     if (bb_data_desc(shadow_bb)[i].type < E_BB_CHAR) {
00192       if (bb_data_desc(shadow_bb)[i].dimension > 1) {
00193         for (j=0;j<bb_data_desc(shadow_bb)[i].dimension; ++j) {
00194           i_temp = strlen(bb_data_desc(shadow_bb)[i].name)+9;
00195           X_sample_symbol_info_list_val[i_pg_index].name = malloc(i_temp);
00196           assert(X_sample_symbol_info_list_val[i_pg_index].name);
00197           snprintf(X_sample_symbol_info_list_val[i_pg_index].name, 
00198                    i_temp,
00199                    "%s[%0d]",
00200                    bb_data_desc(shadow_bb)[i].name,
00201                    j);
00202           X_sample_symbol_info_list_val[i_pg_index].provider_global_index = i_pg_index;
00203           X_sample_symbol_info_list_val[i_pg_index].period = 1;
00204           /* on pointe vers la valeur adéquate */
00205           value_by_pgi[i_pg_index]  = ((void*) ((char*)bb_data(shadow_bb) + bb_data_desc(shadow_bb)[i].data_offset)) + j*bb_data_desc(shadow_bb)[i].type_size;
00206           bbtype_by_pgi[i_pg_index] = bb_data_desc(shadow_bb)[i].type;
00207           ++i_pg_index;
00208         }
00209       } 
00210       /* creation simple pour les scalaires */
00211       else {
00212         X_sample_symbol_info_list_val[i_pg_index].name = strdup(bb_data_desc(shadow_bb)[i].name);
00213         X_sample_symbol_info_list_val[i_pg_index].provider_global_index = i_pg_index;
00214         X_sample_symbol_info_list_val[i_pg_index].period = 1;
00215         value_by_pgi[i_pg_index] = ((void*) ((char*)bb_data(shadow_bb) + bb_data_desc(shadow_bb)[i].data_offset));
00216         bbtype_by_pgi[i_pg_index] = bb_data_desc(shadow_bb)[i].type;
00217         ++i_pg_index;
00218       }
00219     } else  { /* skip unhandled BB type */ 
00220       STRACE_INFO(("Skipping unhandled symbol type <%d> name <%s>",bb_data_desc(shadow_bb)[i].type,bb_data_desc(shadow_bb)[i].name));
00221     }
00222   } /* loop over bb items */
00223   
00224   return retcode;
00225 } /* end of GLU_init */
00226 
00227 
00228 /*
00229  * C'est un provider actif car il dépend
00230  * d'une simulation potentiellement temps réelle et 
00231  * n'attendra donc pas que les éventuels consumer
00232  * consomment ce qu'ils ont demandés pour produire.
00233  * Si les consumers sont trop lents ils perdront des données
00234  * le provider ne s'arrêtera pas.
00235  */ 
00236 GLU_server_type_t GLU_get_server_type(void) {
00237   return GLU_SERVER_TYPE_ACTIVE;
00238 }
00239 
00240 
00241 int  GLU_get_symbol_number(void) {
00242   int i = 0;
00243   TSP_sample_symbol_info_t* p  = X_sample_symbol_info_list_val;
00244         
00245   for( p=X_sample_symbol_info_list_val; p->name!=0 ; ++p) {
00246     ++i;
00247   }
00248   return i;
00249 }  /* end of GLU_get_symbol_number */
00250 
00251 int  
00252 GLU_get_sample_symbol_info_list(GLU_handle_t h_glu, 
00253                                 TSP_sample_symbol_info_list_t* symbol_list) {
00254 
00255   symbol_list->TSP_sample_symbol_info_list_t_len = GLU_get_symbol_number();
00256   symbol_list->TSP_sample_symbol_info_list_t_val = X_sample_symbol_info_list_val;
00257             
00258   return TRUE;
00259 }
00260 
00261 double 
00262 GLU_get_base_frequency(void) {
00263   return *bb_tsp_provider_frequency;
00264 }
00265 
00266 static void* GLU_thread(void* arg) {
00267   
00268   int i;
00269   glu_item_t item;
00270   sigset_t s_mask;
00271   int nb_consumed_symbols;
00272   int* ptr_consumed_index;
00273   int pgi;
00274   
00275   bb_logMsg(BB_LOG_INFO,
00276               "bb_tsp_provider::GLU_thread",
00277               "Provider thread started with <%d> symbols",
00278               GLU_get_symbol_number());
00279   /*
00280    * On masque les signaux indesirables i.e. tous :))
00281    */
00282   sigfillset(&s_mask);
00283   pthread_sigmask(SIG_BLOCK,&s_mask,NULL);
00284   /* 
00285    * Initialise le temps propre du GLU 
00286    */
00287   glu_time      = 0;
00288 
00289   /* boucle infinie tant que le blackboard n'est pas detruit */
00290   while(1 != the_bb->destroyed) {
00291     /* On attend le déblocage du PE */
00292     if (E_NOK == bb_simple_synchro_wait(the_bb,BB_SIMPLE_MSGID_SYNCHRO_COPY)) {
00293       /* on sort car le BB a été détruit */
00294       break;
00295     }
00296     /* 
00297      * MAJ des donnees du shadow BB 
00298      */    
00299     bb_shadow_update_data(shadow_bb,the_bb);
00300     /* 
00301      * Refresh the [reverse list of consumed symbols]
00302      * Must be call at each step in case of new samples wanted 
00303      */
00304     TSP_datapool_get_reverse_list (&nb_consumed_symbols, &ptr_consumed_index); 
00305     /*  bb_simple_synchro_go(BB_SIMPLE_MSGID_SYNCHRO_COPY_ACK); */
00306 
00307     /* PUSH des valeurs directement dans le datapool */
00308     for(i = 0 ; i <  nb_consumed_symbols ; ++i) {
00309       /* retrieve the pgi of the consumed symbol */
00310       pgi = ptr_consumed_index[i];
00311       item.time                  = glu_time;
00312       item.provider_global_index = pgi;
00313       /* we return a double value even if 
00314        * the blackboard type is different
00315        * since TSP only knows double ... till now */
00316       item.value                 = bb_double_of(value_by_pgi[pgi],bbtype_by_pgi[pgi]);
00317       TSP_datapool_push_next_item(&item);      
00318     }
00319     TSP_datapool_push_commit(glu_time, GLU_GET_NEW_ITEM);
00320       
00321     ++glu_time;
00322 /*     if ( 0 == (glu_time%1000) ) { */
00323 /*       bb_logMsg(BB_LOG_FINER,"bb_tsp_provider::GLU_thread", */
00324 /*                "Time Stamp <%d>\n",glu_time); */
00325 /*     } */
00326 
00327   }
00328 
00329   return NULL;
00330   
00331 } /* end of GLU_thread */
00332 
00333 int GLU_start(void)
00334 {
00335   if (0==glu_thread_id) {
00336     return pthread_create(&glu_thread_id, NULL, GLU_thread, NULL); 
00337   } else {
00338     return 1;
00339   }
00340 }
00341 
00342 GLU_handle_t 
00343 GLU_get_instance(int custom_argc,
00344                  char* custom_argv[],
00345                  char** error_info) {
00346 
00347   if(error_info)
00348     *error_info = "";
00349 
00350   return GLU_GLOBAL_HANDLE;
00351 }  /* end of GLU_get_instance */
00352 
00353 
00354 /* void  */
00355 /* GLU_forget_data(GLU_handle_t h_glu) { */
00356 /*   RINGBUF_PTR_RESET_CONSUMER(glu_ring); */
00357 /* } */
00358 
00359 
00360 int32_t 
00361 bb_tsp_provider_initialise(int* argc, char** argv[],int TSPRunMode, const char* bbname) {
00362   
00363   int32_t retcode;
00364   
00365   retcode = E_OK;
00366   the_bbname = strdup(bbname);
00367   /* Init LibTSP provider */
00368   TSP_provider_init(argc, argv);  
00369   /* demarrage provider */
00370   TSP_provider_run(TSPRunMode);
00371   /* 
00372    * Si demarrage en mode non bloquant 
00373    * attendre demarrage thread provider
00374    * FIXME ce mode "d'attente" est pourlingue il faut une
00375    * API TSP pour gérer ces synchros de démarrage de thread.
00376    */
00377   if (TSP_ASYNC_REQUEST_NON_BLOCKING & TSPRunMode) {
00378     sleep(1);
00379     sched_yield();  
00380     while (TSP_provider_rqh_manager_get_nb_running()<1) {
00381       printf("Waiting TSP provider to start...\n");
00382       fflush(stdout);
00383       sleep(1);
00384       sched_yield();    
00385     } 
00386   }  
00387   return retcode;
00388 } /* end of bb_tsp_provider_initialise */
00389 
00390 int32_t 
00391 bb_tsp_provider_finalize() {
00392   int32_t retcode;
00393   
00394   TSP_provider_end();
00395   retcode = E_OK;
00396 
00397   return retcode;
00398 }
Framework Home Page.

Beware !! TSP wave is coming...