/* * Video On Demand Samples * * Copyright (C) 2015 Microchip Technology Germany II GmbH & Co. KG * * 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. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * You may also obtain this software under a propriety license from Microchip. * Please contact Microchip for further information. * */ #include #include #include #include #include #include #include #include #include #include "Console.h" ///Our shared memory key static int shmkey = 072162537; //The minimum priority static ConsolePrio_t minPrio = PRIO_LOW; /*! \cond PRIVATE */ typedef struct { ///The first process will setup the critical section and set this variable to true. bool initialized; ///If set to true, multiple processeses are synced via shared memory. bool processSynced; ///If set to true, there is an segmented print ongoing (Start, Continue, Exit). bool criticalSection; //If is in a critical segmented print, this variable will hold the prio for Start, Continue, Exit. ConsolePrio_t criticalSectionPrio; ///Handle of the shared mutex. pthread_mutex_t mutex; } sharedData_t; /*! \endcond */ /*----------------------------------------------------------*/ /*! \brief Pointer to the shared memory instance. */ /*----------------------------------------------------------*/ static sharedData_t *data = NULL; void ConsoleInit( bool synchronizeProcesses ) { pthread_mutexattr_t attr; if( synchronizeProcesses ) { int shmid = shmget( shmkey, sizeof( sharedData_t ), IPC_CREAT | 0666 ); if( ( sharedData_t * )-1 == ( data = ( sharedData_t* )shmat( shmid, NULL, 0 ) ) ) { data = NULL; fprintf( stderr, RED"ConsoleInit failed, because shared memory could not be accessed."RESETCOLOR"\n" ); return; } } else { data = ( sharedData_t * )calloc( 1, sizeof( sharedData_t ) ); } if( ( NULL != data ) && !data->initialized ) { data->processSynced = synchronizeProcesses; data->initialized = true; data->criticalSection = false; pthread_mutexattr_init( &attr ); if( synchronizeProcesses ) pthread_mutexattr_setpshared( &attr, PTHREAD_PROCESS_SHARED ); else pthread_mutexattr_setpshared( &attr, PTHREAD_PROCESS_PRIVATE ); pthread_mutex_init( &data->mutex, &attr ); } } void ConsoleDeinit( void ) { if( NULL != data && !data->processSynced ) { free( data ); data = NULL; } } void ConsoleSetPrio( ConsolePrio_t prio ) { minPrio = prio; } void ConsolePrintf( ConsolePrio_t prio, const char *statement, ... ) { int err; if( prio < minPrio || NULL == statement ) return; if( NULL == data ) { fprintf( stderr, RED"ConsolePrintf data was null"RESETCOLOR"\n" ); return; } if( 0 != ( err = pthread_mutex_lock( &data->mutex ) ) ) { fprintf( stderr, RED"ConsolePrintf, pthread_mutex_lock error: %d"RESETCOLOR"\n", err ); return; } va_list args; va_start( args, statement ); vfprintf( stderr, statement, args ); va_end( args ); if( 0 != ( err = pthread_mutex_unlock( &data->mutex ) ) ) { fprintf( stderr, RED"ConsolePrintf, pthread_mutex_unlock error: %d"RESETCOLOR"\n", err ); return; } } void ConsolePrintfStart( ConsolePrio_t prio, const char *statement, ... ) { int err; if( NULL == data ) { fprintf( stderr, RED"ConsolePrintfStart data was null"RESETCOLOR"\n" ); return; } if( 0 != ( err = pthread_mutex_lock( &data->mutex ) ) ) { fprintf( stderr, RED"ConsolePrintfStart, pthread_mutex_lock error: %d"RESETCOLOR"\n", err ); return; } data->criticalSection = true; data->criticalSectionPrio = prio; if( data->criticalSectionPrio >= minPrio && NULL != statement ) { va_list args; va_start( args, statement ); vfprintf( stderr, statement, args ); va_end( args ); } } void ConsolePrintfContinue( const char *statement, ... ) { if( NULL == data ) { fprintf( stderr, RED"ConsolePrintfContinue data was null"RESETCOLOR"\n" ); return; } if( !data->criticalSection ) { fprintf( stderr, RED"ConsolePrintfContinue not in critical section"RESETCOLOR"\n" ); return; } if( data->criticalSectionPrio >= minPrio && NULL != statement ) { va_list args; va_start( args, statement ); vfprintf( stderr, statement, args ); va_end( args ); } } void ConsolePrintfExit( const char *statement, ... ) { int err; if( NULL == data ) { fprintf( stderr, RED"ConsolePrintfExit data was null"RESETCOLOR"\n" ); return; } if( !data->criticalSection ) { fprintf( stderr, RED"ConsolePrintfExit not in critical section"RESETCOLOR"\n" ); return; } if( data->criticalSectionPrio >= minPrio && NULL != statement ) { va_list args; va_start( args, statement ); vfprintf( stderr, statement, args ); va_end( args ); } data->criticalSection = false; if( 0 != ( err = pthread_mutex_unlock( &data->mutex ) ) ) { fprintf( stderr, RED"ConsolePrintfExit, pthread_mutex_unlock error: %d"RESETCOLOR"\n", err ); } }