⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdb.c

📁 This a framework to test new ideas in transmission technology. Actual development is a LDPC-coder in
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************         sdb.c  -  RTLinux kernel module for the subsystem data base                            -------------------    begin                :  2002    authors              :  Linus Gasser    emails               :  linus.gasser@epfl.ch ***************************************************************************//***************************************************************************                                 Changes                                 ------- date - name - description 02-09-11 - ineiti - begin 02/10/31 - ineiti - take out messages 03/04/01 - ineiti - move swr_sdb_set* and swr_sdb_get* to values.c 03/04/04 - ineiti - added profiling 03/04/04 - ineiti - added indexes to config/struct 03/12/15 - ineiti - reconfiguration happens asynchronously now 04/03/31 - ineiti - swr_sdb_send_msg can return a non-zero value  **************************************************************************//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU General Public License as published by  * *   the Free Software Foundation; either version 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * ***************************************************************************/#define DBG_LVL 0#include "system.h"#include "debugging.h"#include "sdb.h"#include "subsystem.h"#include "memory.h"#include "parameters.h"#include "dbg.h"/** * The maximal number of concurrently available subsystems */#define MAX_SYS_POTWO 10#define MAX_SUBSYSTEMS ( 1 << MAX_SYS_POTWO )typedef struct {  swr_sdb_t context;  pthread_mutex_t mutex_config;  pthread_mutex_t mutex_stats;  void *config_data;  void *stats_data;}sdb_t;/** * All data for every subsystem is stored in here */sdb_t *sdb_table;pthread_mutex_t mutex_table;/** * The id of the next subsystem, if created */int curr_sdb_id;/** * Takes an id to a subsystem and returns the corresponding entry in the * table */#define ENTRY(i) sdb_table[ (i) & ( MAX_SUBSYSTEMS - 1 ) ]#define CHECK_ID(id)   if ( ( id < 0 ) || ( ENTRY(id).context.id != id ) ){ \    PR_DBG( 0, "ID not valid\n" ); return -1; }char swr_profile_name[][16] = { "Messages", "Data    ", "Total   " };struct swr_stats_track_t swr_stats_track[ MAX_TRACKS ][ 2 ];/** * @short Returns the spc-id of a subsystem * * Checks for a given subsystem the correct spm-id * * @param id the subsytem to search for *  * @return the spm-id or a negative error: * <ul> * <li>ERROR_NO_SUBSYS no such subsystem</li> * <li>ERROR_NO_SPM no corresponding spm-id found</li> * </ul> */swr_spc_id_t swr_sdb_spm( swr_sdb_id id ) {  if ( id < 0 )    return ERROR_NO_SUBSYS;  if ( ENTRY( id ).context.id != id )    return ERROR_NO_SUBSYS;  return ENTRY( id ).context.cdb_desc->id;}/** * @short Sends a 'message' to a subsystem * * Calls the message-handler of the given subsystem and gives * it the appropriate options * * @param id the subsystems id * @param m_id The message. swr_sdb_send_msg doesn't care about this * value, it just passes it along. * @param d The data to pass along. This can be anything * @param ret_id Where eventual replies shall be sent to. Putting * a -1 here is a valid option. *  * @return 0 or a negative error: * <ul> * <li>ERROR_NO_SUBSYS no such subsystem</li> * </ul> */int swr_sdb_send_msg( swr_sdb_id id, int m_id, void *d, swr_sdb_id ret_id ) {  PR_DBG( 4, "Sending msg %i from %i to %i\n", m_id, ret_id, id );  return subsys_handler( swr_sdb_get_struct( id ), m_id, d, ret_id );}/** * @short instantiate by name * * Perhaps the most important function. It takes a spm-id and * tries to generate a subsystem out of it. The spm-structure * is generated and initialised by the spm-init function. * Everything is set up and ready to be connected to other * spm-modules. * * After calling this function and if no error occured, the * return-value points to a waiting subsystem, ready to go. * * @param name a string pointing to the name of the sdb *  * @return subsys-id if all went well or a negative error: * <ul> * <li>ERROR_NO_SPM no such spm</li> * <li>ERROR_NO_MEMORY not enough memory</li> * <li>ERROR_OTHER undefined error</li> * </ul> */swr_sdb_id swr_sdb_instantiate_name( char *name ) {  return swr_sdb_instantiate_id( swr_cdb_get_id( name ) );}/** * @short Creates an instance of a subsystem * * Perhaps the most important function. It takes a spm-id and * tries to generate a subsystem out of it. The spm-structure * is generated and initialised by the spm-init function. * Everything is set up and ready to be connected to other * spm-modules. * * After calling this function and if no error occured, the * return-value points to a waiting subsystem, ready to go. * * @param id the spm-id *  * @return subsys-id if all went well or a negative error: * <ul> * <li>ERROR_NO_SPM no such spm</li> * <li>ERROR_NO_MEMORY not enough memory</li> * <li>ERROR_OTHER undefined error</li> * </ul> */swr_sdb_id swr_sdb_instantiate_id( swr_spc_id_t id ) {  int i, new_id;  const swr_spc_desc_t *cdb_struct;  sdb_t entry;  pthread_mutex_lock( &mutex_table );  if ( id < 0 )    goto swr_sdb_inst_err;  PR_DBG( 3, "Initialising dummy-entry\n" );  // First we do some checking whether the id exists, and if there  // is place left  if ( swr_cdb_get_reference( &cdb_struct, id ) < 0 )    goto swr_sdb_inst_err;  for ( new_id=curr_sdb_id; new_id < MAX_SUBSYSTEMS + curr_sdb_id;        new_id++ ) {    if ( ENTRY(new_id).context.id == -1 )      break;  }  if ( ENTRY(new_id).context.id != -1 )    goto swr_sdb_inst_err_ref;  // Then we begin putting in new values in our local entry  entry.context.id = new_id;  entry.context.cdb_desc = cdb_struct;  entry.context.status = 0;  entry.context.rec_count = 0;  // Get the output-ports, or initialise to NULL if there aren't any  if ( cdb_struct->outputs.nbr_ports ) {    if ( !( entry.context.port_out =              (swr_port_t*)swr_malloc( sizeof( swr_port_t ) *                                       cdb_struct->outputs.nbr_ports ) ) ) {      goto swr_sdb_inst_err_outports;    }  } else {    entry.context.port_out = NULL;  }  // Get the input-ports, or initialise to NULL if there aren't any  if ( cdb_struct->inputs.nbr_ports ) {    if ( !( entry.context.port_in =              (swr_port_t*)swr_malloc( sizeof( swr_port_t ) *                                       cdb_struct->inputs.nbr_ports ) ) ) {      goto swr_sdb_inst_err_inports;    }  } else {    entry.context.port_in = NULL;  }  // Setting up the configuration-memory, if any.  if ( ( i = swr_spc_get_config_memory_size( entry.context.cdb_desc ) ) ) {    if ( !(entry.config_data = swr_malloc( i ) ) )      goto swr_sdb_inst_err_malloc_config;  } else {    entry.config_data = NULL;  }  // Setting up the stats-memory, if any.  if ( ( i = swr_spc_get_stats_memory_size( entry.context.cdb_desc ) ) ) {    if ( !( entry.stats_data = swr_malloc( i ) ) )      goto swr_sdb_inst_err_malloc_stats;  } else {    entry.stats_data = NULL;  }  PR_DBG( 3, "Preparing module\n" );  // Create the mutex and cond-var for the subsystem and initialise the  // message-queue  pthread_mutex_init( &entry.context.mutex, NULL );  pthread_cond_init( &entry.context.cond, NULL );  // The mutexes have to be initialised:  // preparing a mutex protection for config and stats  pthread_mutex_init( &entry.mutex_config, NULL );  pthread_mutex_init( &entry.mutex_stats, NULL );  ENTRY(new_id) = entry;  if ( subsys_init( &ENTRY(new_id).context ) < 0 ) {    PR_DBG( 0, "Failed to initialise subsys. What now?\n" );  }  curr_sdb_id = new_id + 1;  PR_DBG( 4, "Finished\n" );  pthread_mutex_unlock( &mutex_table );  return new_id;  // ERROR-handlingswr_sdb_inst_err_malloc_stats:  PR_DBG_CL( 0, "Freeing stats and config, " );  swr_cdb_free_reference( &entry.context.cdb_desc );  swr_free( entry.context.port_in );swr_sdb_inst_err_malloc_config:swr_sdb_inst_err_inports:  PR_DBG_CL( 0, "Freeing the connections, " );  swr_free( entry.context.port_out );swr_sdb_inst_err_outports:swr_sdb_inst_err_ref:  PR_DBG_CL( 0, "Freeing reference " );  swr_cdb_free_reference( &cdb_struct );swr_sdb_inst_err:  PR_DBG( 0, "and exiting with error\n");  pthread_mutex_unlock( &mutex_table );  return -1;}/** * @short Destroys an instance of a subsystem */int swr_sdb_destroy( swr_sdb_id id ) {  sdb_t *entry;  if ( id < 0 )    goto swr_sdb_destroy_error;  entry = &ENTRY( id );  if ( entry->context.id < 0 ){    PR_DBG( 0, "Trying to free an already freed sdb: %i\n", id );    return -1;  }  subsys_handler( &entry->context, SUBS_MSG_EXIT, NULL, -1 );  pthread_mutex_lock( &mutex_table );  if ( entry->context.id != id )    goto swr_sdb_destroy_error;  swr_conn_sdb_remove( id );  pthread_mutex_destroy( &entry->mutex_config );  pthread_mutex_destroy( &entry->mutex_stats );  pthread_mutex_destroy( &entry->context.mutex );  pthread_cond_destroy( &entry->context.cond );  // Cleaning up our structures  entry->context.id = -1;  if ( entry->context.port_in ) {    swr_free( entry->context.port_in );  }  if ( entry->context.port_out ) {    swr_free( entry->context.port_out );  }  if ( entry->config_data ) {    swr_free( entry->config_data );  }  if ( entry->stats_data ) {    swr_free( entry->stats_data );  }  swr_cdb_free_reference( &entry->context.cdb_desc );  pthread_mutex_unlock( &mutex_table );  return 0;swr_sdb_destroy_error:  PR_DBG( 0, "uncool id %i\n", id );  pthread_mutex_unlock( &mutex_table );  return -1;}/** * @short returns the corresponding structure */swr_sdb_t *swr_sdb_get_struct( swr_sdb_id id ) {  if ( id < 0 )    return NULL;  if ( ENTRY( id ).context.id != id )    return NULL;  return &ENTRY( id ).context;}/** * @short activate inputs and call a module * * This function can be used to call a module out-of order. * It is mostly for debugging purposes. *  First the desired input-ports are activated (if they have * a valid data-part) and then a SUBS_SWR_MSG_DATA message is * sent to the module. * * @param id The id of the module * @param act A bit-mask for the input-ports to activate * * @return 0 on success, -1 on failure */int swr_sdb_call_module( swr_sdb_id id, int act ){  swr_sdb_t *s;  swr_port_t *port;  int i;  s = swr_sdb_get_struct( id );  if ( !s ){    PR_DBG( 0, "Module %i doesn't exist\n", id );    return -1;  }  for ( i=0; i<s->cdb_desc->inputs.nbr_ports; i++ ){    if ( ( 1 << i ) & act ){      port = s->port_in + i;      if ( port->data ){	PR_DBG( 4, "Setting port %i with data\n", i );	port->flags |= SWR_PORT_DATA;      }    }  }  swr_sdb_send_msg( id, SUBS_MSG_DATA, NULL, -1 );  return 0;}/** * @short Writes maximum size subsys-ids in ids and * returns the total number of ids. */int swr_sdb_list( swr_sdb_id *ids, int size ) {  int i, tot=0;  pthread_mutex_lock( &mutex_table );  for ( i=0; i<MAX_SUBSYSTEMS; i++ ) {    if ( ENTRY(i).context.id != -1 ) {      if ( tot < size ) {        ids[tot] = ENTRY(i).context.id;      }      tot++;    }  }  pthread_mutex_unlock( &mutex_table );  return tot;}/** * @short Returns the number of a certain parameter */int swr_sdb_get_config_parameter_nbr( swr_sdb_id id, char *name ) {  sdb_t *entry;  int ret = -1;  // if id < -1, then it might be a call to set_config with a negative  // id, which means not to reconfigure, so do allow it.  if ( id < 0 ){    if ( id < -1 ){      id = -id;    } else {      // Well, this is used as an invalid id soo often      return -1;    }  }  entry = &ENTRY(id);  pthread_mutex_lock( &entry->mutex_config );  if ( entry->context.id != id )    goto swr_sdb_get_config_param_error;  ret = swr_spc_get_config_parameter_nbr( entry->context.cdb_desc, name );swr_sdb_get_config_param_error:  pthread_mutex_unlock( &entry->mutex_config );  return ret;}/** * @short Writes a new value to the config-structure */int swr_sdb_set_config_parameter_value( swr_sdb_id id, int param, void *data ) {  sdb_t *entry;  int ret = -1;  int call_reconf = 1;  // If id < 0, then only set the value, without reconfiguration  // Nevertheless, keep the error on id -1, as this is used in many  // places to design an invalid module  if ( id < 0 ){    if ( id < -1 ){      id = -id;      call_reconf = 0;    } else {      return -1;    }  }  entry = &ENTRY(id);  pthread_mutex_lock( &entry->mutex_config );  if ( entry->context.id != id )    goto swr_sdb_set_config_error;  if ( swr_spc_set_config_parameter_value( entry->context.cdb_desc,       entry->config_data, param, data ) ) {    ret = 0;    PR_DBG( 4, "Setting status_reconf\n" );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -