📄 chain.c
字号:
/*************************************************************************** chain.c - Defines chains of SPCs ------------------- begin : 2002 authors : Linus Gasser emails : linus.gasser@epfl.ch ***************************************************************************//*************************************************************************** Changes ------- date - name - description 03/01/02 - ineiti - begin 03/01/09 - ineiti - make some check for invalid chains 03/04/04 - ineiti - use of DEF_END TODO ---- - make a table with all chains, so that no wrong pointers may be freed. This implies not returning the structure, but an id to the chain. Like the SPC-database and CDB **************************************************************************//*************************************************************************** * * * 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. * * * ***************************************************************************/#include <stdarg.h>#include <strings.h>#include "chain.h"#include "system.h"#include "debugging.h"#include "memory.h"#define DBG_LVL 0/** * This module helps to define chains of modules. This way you don't * have to allocate all the variables and stuff. It's just more nice. *//** * @short creates a new chain */struct chain_t *swr_chain_create( int first_type, ... ) { struct chain_t *ret; int index, intsize, tmp_int, tmp_cst; char *name, *name_old; swr_sdb_id *sdb, tmp_sdb, *tmp_psdb; va_list argp; int length; // First let's calculate the length of the chain if ( first_type < DEF_OFFSET ) { // This is easy, the old style... length = first_type; PR_DBG( 4, "Old style, len = %i\n", length ); } else { // Hmm, now we have to go through the whole chain and make sure // that we get all elements. length = 0; va_start( argp, first_type ); for ( tmp_cst = first_type; tmp_cst != DEF_OFFSET + DEF_END; tmp_cst = va_arg( argp, int ) ) { length++; PR_DBG( 4, "tmp_cst: %x\n", tmp_cst ); if ( tmp_cst & DEF_OLD ) { tmp_sdb = va_arg( argp, swr_sdb_id ); } else { name = va_arg( argp, char * ); if ( tmp_cst & DEF_VAR ) { tmp_psdb = va_arg( argp, swr_sdb_id * ); } } if ( tmp_cst & DEF_IN ) { tmp_int = va_arg( argp, int ); } if ( tmp_cst & DEF_OUT ) { tmp_int = va_arg( argp, int ); } } va_end( argp ); PR_DBG( 4, "New style, len = %i\n", length ); } if ( length < 2 ) { PR_DBG( 0, "Can't set up a chain with less than 2 elements!\n" ); return NULL; } PR_DBG( 3, "Set up a chain with %i spcs\n", length ); // set up the chain ret = swr_malloc( sizeof( struct chain_t ) ); ret->sdb = swr_malloc( sizeof( swr_sdb_id ) * length ); intsize = sizeof( int ) * length; ret->port_in = swr_malloc( intsize ); memset( ret->port_in, 0, intsize ); ret->port_out = swr_malloc( intsize ); memset( ret->port_out, 0, intsize ); ret->type = swr_malloc( sizeof( int ) * length ); ret->conn = swr_malloc( sizeof( swr_conn ) * ( length - 1 ) ); ret->length = length; name = name_old = NULL; va_start( argp, first_type ); for ( index=0; index < length; index++ ) { // Cheat for the first element, perhaps it's already in first_type if ( !index && ( first_type >= DEF_OFFSET ) ) { ret->type[ index ] = first_type; } else { ret->type[ index ] = va_arg( argp, int ); } if ( ret->type[ index ] & DEF_OLD ) { // Get an already existing spc ret->sdb[ index ] = va_arg( argp, swr_sdb_id ); PR_DBG( 2, "[%i]: Using SPC %i\n", index, ret->sdb[ index ] ); } else { // Create the spc name_old = name; name = va_arg( argp, char * ); ret->sdb[ index ] = swr_sdb_instantiate_name( name ); PR_DBG( 1, "[%i]: Create a SPC called %s -> id:%i\n", index, name, ret->sdb[ index ] ); if ( ret->type[ index ] & DEF_VAR ) { // The spc shall be stored PR_DBG( 4, "And storing the SPC\n" ); sdb = va_arg( argp, swr_sdb_id * ); *sdb = ret->sdb[ index ]; } } if ( ret->type[ index ] & DEF_IN ) { // Input-port is given ret->port_in[ index ] = va_arg( argp, int ); PR_DBG( 3, "Input-port %i\n", ret->port_in[ index ] ); } if ( ret->type[ index ] & DEF_OUT ) { // Output-port is given ret->port_out[ index ] = va_arg( argp, int ); PR_DBG( 3, "Output-port %i\n", ret->port_out[ index ] ); } if ( index ) { // And connect it with the last one ret->conn[ index - 1 ] = swr_conn_add( ret->sdb[ index - 1 ], ret->port_out[ index - 1 ], ret->sdb[ index ], ret->port_in[ index ] ); if ( ret->conn[ index - 1 ] < 0 ) { PR_DBG( 0, "Couldn't make connection between %s[%i] and %s[%i]\n", name_old, index - 1, name, index ); } PR_DBG( 3, "Made connection %i\n", ret->conn[ index - 1 ] ); } } va_end( argp ); return ret;}/** * @short destroys chain and frees memory */int swr_chain_destroy( struct chain_t *chain ) { int index; if ( !chain ) { PR_DBG( 2, "Chain is NULL-pointer, aborting\n" ); return -1; } for ( index=0; index < chain->length - 1; index++ ) { // There are only chain->length - 1 connections char name1[SWR_CDB_MAX_NAME_LENGTH], name2[SWR_CDB_MAX_NAME_LENGTH]; swr_cdb_get_name( swr_sdb_get_struct( chain->sdb[ index ] )-> cdb_desc->id, name1 ); swr_cdb_get_name( swr_sdb_get_struct( chain->sdb[ index + 1 ] )-> cdb_desc->id, name2 ); PR_DBG( 4, "Freeing connection %s to %s\n", name1, name2 ); if ( swr_conn_delete( chain->conn[ index ] ) < 0 ) { PR_DBG( 0, "Hmm, there is an invalid connection in the chain," "between %s and %s, index %i, aborting\n", name1, name2, index ); return -1; } } for ( index=0; index < chain->length; index++ ) { // But chain->length SDBs if ( !( chain->type[ index ] & DEF_OLD ) ) { char name[SWR_CDB_MAX_NAME_LENGTH]; swr_cdb_get_name( swr_sdb_get_struct( chain->sdb[ index ] )-> cdb_desc->id, name ); PR_DBG( 4, "Freeing id %i (%s)\n", chain->sdb[ index ], name ); if ( swr_sdb_destroy( chain->sdb[ index ] ) < 0 ) { PR_DBG( 0, "Hmm, there is an invalid SPC in the chain: %s," " index %i, aborting\n", name, index ); return -1; } } } swr_free( chain->conn ); swr_free( chain->type ); swr_free( chain->port_out ); swr_free( chain->port_in ); swr_free( chain->sdb ); swr_free( chain ); return 0;}/** * The following symbols are exported: */EXPORT_SYMBOL(swr_chain_create);EXPORT_SYMBOL(swr_chain_destroy);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -