summaryrefslogtreecommitdiffstats
path: root/Src/Console.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Console.c')
-rw-r--r--Src/Console.c209
1 files changed, 209 insertions, 0 deletions
diff --git a/Src/Console.c b/Src/Console.c
new file mode 100644
index 0000000..4ae52a3
--- /dev/null
+++ b/Src/Console.c
@@ -0,0 +1,209 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ * You may also obtain this software under a propriety license from Microchip.
+ * Please contact Microchip for further information.
+ *
+ */
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#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 );
+ }
+}