Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

phConditionCounter.cpp

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------
00002     Phission : 
00003         Realtime Vision Processing System
00004     
00005     Copyright (C) 2003-2006 Philip D.S. Thoren (pthoren@cs.uml.edu)
00006     University of Massachusetts at Lowell,
00007     Laboratory for Artificial Intelligence and Robotics
00008     
00009     This file is part of Phission.
00010 
00011     Phission is free software; you can redistribute it and/or modify
00012     it under the terms of the GNU Lesser General Public License as published by
00013     the Free Software Foundation; either version 2 of the License, or
00014     (at your option) any later version.
00015 
00016     Phission is distributed in the hope that it will be useful,
00017     but WITHOUT ANY WARRANTY; without even the implied warranty of
00018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019     GNU Lesser General Public License for more details.
00020 
00021     You should have received a copy of the GNU Lesser General Public License
00022     along with Phission; if not, write to the Free Software
00023     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00024 
00025  ---------------------------------------------------------------------------*/
00026 #ifdef HAVE_CONFIG_H
00027     #include <phissionconfig.h>
00028 #endif
00029 
00030 #include <phStandard.h>
00031 
00032 #include <phObject.h>
00033 #include <phMutex.h>
00034 #include <phCondition.h>
00035 
00036 #include <phConditionCounter.h>
00037 
00038 #include <phError.h>
00039 #include <phMemory.h>
00040 #include <phPrint.h>
00041 
00042 /* ------------------------------------------------------------------------- */
00043 phConditionCounter::phConditionCounter( intmax_t value ) : phCondition()
00044 {
00045     this->m_wake    = 0;
00046     this->m_waiting = 0;
00047     this->m_value   = value;
00048     this->setName("phConditionCounter");
00049 }
00050 /* ------------------------------------------------------------------------- */
00051 phConditionCounter::~phConditionCounter( )
00052 {
00053     this->m_value   = 0;
00054     this->m_waiting = 0;
00055     this->m_wake    = 0;
00056 }
00057 /* ------------------------------------------------------------------------- */
00058 int phConditionCounter::increment( intmax_t value )
00059 {
00060     phFUNCTION("phConditionCounter::increment")
00061     int locked = 0;
00062 
00063     phTHIS_LOCK(locked);
00064 
00065     this->m_value += value;
00066 
00067     rc = this->broadcast();
00068     phCHECK_RC(rc,NULL,"this->broadcast");
00069     
00070     phTHIS_UNLOCK(locked);
00071     return phSUCCESS;
00072 
00073 error:
00074     phTHIS_ERROR_UNLOCK(locked);
00075     return phFAIL;
00076 }
00077 
00078 /* ------------------------------------------------------------------------- */
00079 int phConditionCounter::decrement( intmax_t value )
00080 {
00081     phFUNCTION("phConditionCounter::decrement")
00082     int locked = 0;
00083    
00084     phTHIS_LOCK(locked);
00085         
00086     this->m_value -= value;
00087 
00088     rc = this->broadcast();
00089     phCHECK_RC(rc,NULL,"this->broadcast");
00090     
00091     phTHIS_UNLOCK(locked);
00092     return phSUCCESS;
00093     
00094 error:
00095     phTHIS_ERROR_UNLOCK(locked);
00096     return phFAIL;
00097 }
00098 
00099 /* ------------------------------------------------------------------------- */
00100 /* This wakeup can lock because no one will lock it externally and no
00101    one will block with the lock */
00102 int phConditionCounter::wakeup( )
00103 {
00104     phFUNCTION("phConditionCounter::wakeup")
00105     int locked = 0;
00106    
00107     phTHIS_LOCK(locked);
00108    
00109     this->m_wake = 1;
00110     
00111     rc = this->broadcast();
00112     phCHECK_RC(rc,NULL,"this->broadcast()");
00113     
00114     phTHIS_UNLOCK(locked);
00115     return phSUCCESS;
00116     
00117 error:
00118     phTHIS_ERROR_UNLOCK(locked);
00119     return phFAIL;
00120 }
00121 
00122 
00123 /* ------------------------------------------------------------------------- */
00124 int phConditionCounter::setValue( intmax_t value )
00125 {
00126     phFUNCTION("phConditionCounter::setValue")
00127     int locked = 0;
00128     
00129     phTHIS_LOCK(locked);
00130     
00131     this->m_value = value;
00132     
00133     rc = this->broadcast();
00134     phCHECK_RC(rc,NULL,"this->broadcast");
00135     
00136     phTHIS_UNLOCK(locked);
00137     return phSUCCESS;
00138 
00139 error:
00140     phTHIS_ERROR_UNLOCK(locked);
00141     return phFAIL;
00142 }
00143 
00144 /* ------------------------------------------------------------------------- */
00145 intmax_t phConditionCounter::getValue()
00146 {
00147     phFUNCTION("phConditionCounter::getValue")
00148     int         locked = 0;
00149     intmax_t   retrc = 0;
00150     
00151     phTHIS_LOCK(locked);
00152     
00153     retrc = this->m_value;
00154     
00155     phTHIS_UNLOCK(locked);
00156     return retrc;
00157     
00158 error:
00159     phTHIS_ERROR_UNLOCK(locked);
00160     return 0;
00161 }
00162 
00163 /* ------------------------------------------------------------------------- */
00164 int phConditionCounter::waitForValue(   intmax_t    value, 
00165                                         int         check_op,
00166                                         intmax_t   *return_value )
00167 {
00168     phFUNCTION("phConditionCounter::waitForValue")
00169     int         locked = 0;
00170     intmax_t    retrc  = 0;
00171     int         check  = 0;
00172     int         wake   = 0;
00173     
00174     phTHIS_LOCK(locked);
00175    
00176     this->m_waiting++;
00177 
00178     do
00179     {
00180         wake = this->m_wake;
00181         
00182         if (!wake)
00183         {
00184             if (check_op & phCHECK_NOT_EQUAL)
00185             {
00186                 check = (this->m_value != value) ? 1 : check;
00187             }
00188             if (check_op & phCHECK_EQUAL)
00189             {
00190                 check = (this->m_value == value) ? 1 : check;
00191             }
00192             if (check_op & phCHECK_GREATER_THAN)
00193             {
00194                 check = (this->m_value > value) ? 1 : check;
00195             }
00196             if (check_op & phCHECK_LESS_THAN)
00197             {
00198                 check = (this->m_value < value) ? 1 : check;
00199             }
00200             
00201             if (!check)
00202             {
00203                 rc = this->signalWait();
00204                 if (rc < 0) this->m_waiting--;
00205                 phCHECK_RC(rc,NULL,"this->signalWait");
00206             }
00207         }
00208         wake = this->m_wake;
00209     }
00210     while (!(check || wake));
00211     
00212     if (wake)
00213     {
00214         retrc = phConditionCounter_WAKEUP;
00215     }
00216     else
00217     {
00218         if (return_value != NULL) *return_value = this->m_value;
00219         retrc = phSUCCESS;
00220     }
00221 
00222     if (((--this->m_waiting) == 0) && (wake))
00223     {
00224         this->m_wake = 0;
00225     }
00226     
00227     phTHIS_UNLOCK(locked);
00228     return retrc;
00229 
00230 error:
00231     phTHIS_ERROR_UNLOCK(locked);
00232     return phFAIL;
00233 }
00234 




Copyright (C) 2002 - 2007 Philip D.S. Thoren ( pthoren@users.sourceforge.net )
University Of Massachusetts at Lowell
Robotics Lab
SourceForge.net Logo

Generated on Sat Jun 16 02:44:02 2007 for phission by  doxygen 1.4.4