Fast Research Interface Library  Manual and Documentation
src/FastResearchInterfaceLibrary/Console.cpp
Go to the documentation of this file.
00001 //  ---------------------- Doxygen info ----------------------
00051 //  ----------------------------------------------------------
00052 //   For a convenient reading of this file's source code,
00053 //   please use a tab width of four characters.
00054 //  ----------------------------------------------------------
00055 
00056 
00057 #include <Console.h>
00058 #include <stdio.h>
00059 #include <stdarg.h>
00060 #include <string.h>
00061 #include <pthread.h>
00062 #include <OSAbstraction.h>
00063 
00064 
00065 #ifdef WIN32// \ToDo Make this clean through the OSAbstraction
00066 #include <Windows.h>    
00067 #endif
00068 
00069 
00070 
00071 // ****************************************************************
00072 // Constructor 
00073 //
00074 Console::Console(       const unsigned int  &Priority
00075                     ,   const FILE          *FileHandler)
00076 {
00077     struct sched_param      ThreadSchedulingParams;
00078 
00079     pthread_attr_t          ThreadAttributes;
00080 
00081     TermintateThread        =   false;
00082     ThreadCreated           =   false;
00083     ConsoleThreadReadyToRun =   false;
00084 
00085     pthread_mutex_init      (&(this->Mutex)     , NULL);
00086     pthread_cond_init       (&(this->CondVar)   , NULL);
00087 
00088     ThreadSchedulingParams.sched_priority   =   Priority;
00089 
00090     pthread_attr_init           (&ThreadAttributes                              )   ;
00091     pthread_attr_setschedpolicy (&ThreadAttributes  ,   SCHED_FIFO              )   ;
00092     pthread_attr_setinheritsched(&ThreadAttributes  ,   PTHREAD_EXPLICIT_SCHED  )   ;
00093     pthread_attr_setschedparam  (&ThreadAttributes  ,   &ThreadSchedulingParams )   ;
00094 
00095     pthread_create(     &ConsoleThread
00096                     ,   &ThreadAttributes
00097                     ,   &ConsoleThreadMain
00098                     ,   this);
00099 
00100     pthread_mutex_lock(&(this->Mutex));
00101 
00102     while (!ThreadCreated)
00103     {
00104         pthread_cond_wait (&(this->CondVar), &(this->Mutex));
00105     }
00106 
00107     pthread_mutex_unlock(&(this->Mutex));
00108 
00109     memset(this->Buffer, 0x0,       2
00110                                *    CONSOLE_NUMBER_OF_BUFFER_ENTRIES
00111                                *    CONSOLE_BUFFER_ENTRY_SIZE
00112                                *    sizeof(char));
00113 
00114 
00115 
00116     this->BufferNumber      =   false;
00117 
00118     this->NumberOfMessages[0]   =   0;
00119     this->NumberOfMessages[1]   =   0;
00120 
00121 
00122     this->Handler               =   (FILE*)FileHandler;
00123 
00124     pthread_mutex_lock(&(this->Mutex));
00125     this->ConsoleThreadReadyToRun   =   true;
00126     pthread_mutex_unlock(&(this->Mutex));
00127 
00128     pthread_cond_signal(&(this->CondVar));
00129 }
00130 
00131 
00132 // ****************************************************************
00133 // Destructor
00134 //
00135 Console::~Console(void)
00136 {
00137     pthread_mutex_lock(&(this->Mutex));
00138     this->TermintateThread  =   true;
00139     pthread_mutex_unlock(&(this->Mutex));
00140     pthread_cond_signal(&(this->CondVar));
00141     pthread_join(this->ConsoleThread, NULL);
00142 }
00143 
00144 
00145 // ****************************************************************
00146 // printf()
00147 //
00148 int Console::printf(const char* Format,...)
00149 {
00150     int         Result;
00151 
00152     va_list     ListOfArguments;
00153 
00154     va_start(ListOfArguments, Format);
00155 
00156 
00157     pthread_mutex_lock(&(this->Mutex));
00158     if (this->NumberOfMessages[this->BufferNumber] >= CONSOLE_NUMBER_OF_BUFFER_ENTRIES)
00159     {
00160         sprintf(this->Buffer[this->BufferNumber][this->NumberOfMessages[this->BufferNumber] - 1], "Console::printf(): Buffer is full, skipping output!\n");
00161         Result = strlen(this->Buffer[this->BufferNumber][this->NumberOfMessages[this->BufferNumber] - 1]);
00162         pthread_mutex_unlock(&(this->Mutex));
00163         return(Result);
00164     }
00165 
00166     (this->NumberOfMessages[this->BufferNumber])++;
00167     Result = vsnprintf(this->Buffer[this->BufferNumber][NumberOfMessages[this->BufferNumber] - 1], CONSOLE_BUFFER_ENTRY_SIZE - 1, Format, ListOfArguments);
00168     pthread_mutex_unlock(&(this->Mutex));
00169     pthread_cond_signal(&(this->CondVar));
00170 
00171     va_end(ListOfArguments);
00172     return(Result);
00173 }
00174 
00175 
00176 
00177     
00178     
00179 // ****************************************************************
00180 // ConsoleThreadMain()
00181 //
00182 
00183 void* Console::ConsoleThreadMain(void* ObjectPointer)
00184 {
00185     unsigned int        i       =   0;
00186 
00187     Console* ThisObjectPtr = (Console*)ObjectPointer;
00188     
00189 #ifdef WIN32
00190     // \ToDo Make this clean through the OSAbstraction
00191     SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST);
00192 #endif
00193     
00194     pthread_mutex_lock(&(ThisObjectPtr->Mutex));
00195     ThisObjectPtr->ThreadCreated    =   true;
00196     pthread_mutex_unlock(&(ThisObjectPtr->Mutex));
00197 
00198     pthread_cond_signal(&(ThisObjectPtr->CondVar));
00199 
00200     pthread_mutex_lock(&(ThisObjectPtr->Mutex));
00201 
00202     while (!ThisObjectPtr->ConsoleThreadReadyToRun)
00203     {
00204         pthread_cond_wait (&(ThisObjectPtr->CondVar), &(ThisObjectPtr->Mutex));
00205     }
00206 
00207     pthread_mutex_unlock(&(ThisObjectPtr->Mutex));
00208 
00209     for(;;)
00210     {
00211         pthread_mutex_lock(&(ThisObjectPtr->Mutex));
00212         if (ThisObjectPtr->NumberOfMessages[!(ThisObjectPtr->BufferNumber)] == 0)
00213         {
00214             if (ThisObjectPtr->TermintateThread)
00215             {
00216                 pthread_mutex_unlock(&(ThisObjectPtr->Mutex));
00217                 break;
00218             }
00219             pthread_cond_wait (&(ThisObjectPtr->CondVar), &(ThisObjectPtr->Mutex));
00220 
00221             // keep the maximum amount of CPU time for this thread at a minimum while the mutex is locked
00222             ThisObjectPtr->BufferNumber = !ThisObjectPtr->BufferNumber;
00223 
00224             pthread_mutex_unlock(&(ThisObjectPtr->Mutex));
00225         }
00226         else
00227         {
00228             pthread_mutex_unlock(&(ThisObjectPtr->Mutex));
00229         }
00230 
00231         for(i = 0; i < ThisObjectPtr->NumberOfMessages[!(ThisObjectPtr->BufferNumber)]; i++)
00232         {
00233             fprintf(ThisObjectPtr->Handler, "%s", ThisObjectPtr->Buffer[!(ThisObjectPtr->BufferNumber)][i]);
00234         }
00235 
00236         ThisObjectPtr->flush();
00237         ThisObjectPtr->NumberOfMessages[!(ThisObjectPtr->BufferNumber)] = 0;
00238     }
00239 
00240     for(i = 0; i < ThisObjectPtr->NumberOfMessages[ThisObjectPtr->BufferNumber]; i++)
00241     {
00242         fprintf(ThisObjectPtr->Handler, "%s", ThisObjectPtr->Buffer[ThisObjectPtr->BufferNumber][i]);
00243     }
00244 
00245     ThisObjectPtr->flush();
00246 
00247     pthread_exit(NULL);
00248     
00249     return (NULL);
00250 }
00251 
00252 
00253 
00254 // ****************************************************************
00255 // flush()
00256 //
00257 void Console::flush(void) const
00258 {
00259     fflush(this->Handler);
00260     return;
00261 }
00262 
00263 
00264 // ****************************************************************
00265 // GetFileHandler()
00266 //
00267 FILE* Console::GetFileHandler(void) const
00268 {
00269     return(this->Handler);
00270 }
This document was generated with Doxygen on Thu Apr 12 2012 11:18:54. User documentation of the Fast Research Interface Library for the KUKA Lightweight Robot IV by the Stanford Robotics Research Group. Copyright 2010–2012.