/*
* 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 3 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 );
}
}