DataObjectInterfaces.hpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef CORELIB_DATAOBJECTINTERFACES_HPP
00039 #define CORELIB_DATAOBJECTINTERFACES_HPP
00040
00041
00042 #include "os/MutexLock.hpp"
00043 #include "os/oro_atomic.h"
00044 #include <string>
00045
00046 #include "DataSource.hpp"
00047
00048 namespace RTT
00049 {
00050
00063 template <class T>
00064 class DataObjectInterface
00065 : public AssignableDataSource<T>
00066 {
00067 public:
00072 typedef typename boost::intrusive_ptr<DataObjectInterface<T> > shared_ptr;
00073
00077 DataObjectInterface() {
00078 this->ref();
00079 }
00080
00084 virtual ~DataObjectInterface() {}
00085
00089 typedef T DataType;
00090
00096 virtual void Get( DataType& pull ) const = 0;
00097
00103 virtual DataType Get() const = 0;
00104
00110 virtual void Set( const DataType& push ) = 0;
00111
00117 virtual const std::string& getName() const = 0;
00118
00124 typename DataSource<T>::result_t value() const {
00125 return this->Get();
00126 }
00127
00128 virtual typename DataSource<DataType>::result_t get() const {
00129 return this->Get();
00130 }
00131
00132 virtual void set( typename AssignableDataSource<DataType>::param_t t ) {
00133 this->Set( t );
00134 }
00135
00136 virtual typename AssignableDataSource<DataType>::reference_t set() {
00137
00138 typename DataSource<DataType>::value_t* tmp = 0;
00139 return typename AssignableDataSource<DataType>::reference_t(*tmp);
00140 }
00141
00142 virtual typename AssignableDataSource<DataType>::const_reference_t rvalue() const {
00143
00144 typename DataSource<DataType>::value_t* tmp = 0;
00145 return typename AssignableDataSource<DataType>::const_reference_t(*tmp);
00146 }
00147
00148 };
00149
00150
00160 template<class T>
00161 class DataObjectLocked
00162 : public DataObjectInterface<T>
00163 {
00164 mutable OS::Mutex lock;
00165
00169 T data;
00170
00171 std::string name;
00172 public:
00178 DataObjectLocked(const std::string& _name, const T& initial_value = T() )
00179 : data(initial_value), name(_name) {}
00180
00186 const std::string& getName() const { return name;}
00187
00188 void setName( const std::string& _name )
00189 {
00190 name = _name;
00191 }
00192
00196 typedef T DataType;
00197
00203 void Get( DataType& pull ) const { OS::MutexLock locker(lock); pull = data; }
00204
00211 DataType Get() const { DataType cache; Get(cache); return cache; }
00212
00218 void Set( const DataType& push ) { OS::MutexLock locker(lock); data = push; }
00219
00220 DataObjectLocked<DataType>* clone() const {
00221 return new DataObjectLocked<DataType>(name);
00222 }
00223
00224 DataObjectLocked<DataType>* copy( std::map<const DataSourceBase*, DataSourceBase*>& ) const {
00225 return const_cast<DataObjectLocked<DataType>*>(this);
00226 }
00227 };
00228
00256 template<class T>
00257 class DataObjectPrioritySet
00258 : public DataObjectInterface<T>
00259 {
00260 mutable OS::Mutex lock;
00261 mutable bool dirty_flag;
00262
00266 T data;
00267 T mcopy;
00268
00269 std::string name;
00270 public:
00276 DataObjectPrioritySet(const std::string& _name, const T& initial_value = T() )
00277 : data(initial_value), mcopy(), name(_name) {}
00278
00284 const std::string& getName() const { return name;}
00285
00286 void setName( const std::string& _name )
00287 {
00288 name = _name;
00289 }
00290
00294 typedef T DataType;
00295
00301 void Get( DataType& pull ) const
00302 { if (dirty_flag) pull = mcopy; else {OS::MutexLock locker(lock); pull = data;} }
00303
00309 DataType Get() const { DataType cache; Get(cache); return cache; }
00310
00316 void Set( const DataType& push )
00317 {
00318 OS::MutexTryLock locker(lock);
00319 if (locker.isSuccessful())
00320 {data = push; dirty_flag = false;}
00321 else
00322 {mcopy = push; dirty_flag = true;}
00323 }
00324
00325 DataObjectPrioritySet<DataType>* clone() const {
00326 return new DataObjectPrioritySet<DataType>(name);
00327 }
00328
00329 DataObjectPrioritySet<DataType>* copy( std::map<const DataSourceBase*, DataSourceBase*>& ) const {
00330 return const_cast<DataObjectPrioritySet<DataType>*>(this);
00331 }
00332 };
00333
00364 template<class T>
00365 class DataObjectPriorityGet
00366 : public DataObjectInterface<T>
00367 {
00368 mutable OS::Mutex lock;
00369
00373 T data;
00374 T mcopy;
00375
00376 std::string name;
00377 public:
00383 DataObjectPriorityGet(const std::string& _name, const T& initial_value = T() )
00384 : data(initial_value), mcopy(), name(_name) {}
00385
00391 const std::string& getName() const { return name;}
00392
00393 void setName( const std::string& _name )
00394 {
00395 name = _name;
00396 }
00397
00401 typedef T DataType;
00402
00408 void Get( DataType& pull ) const
00409 {
00410
00411
00412
00413
00414 OS::MutexTryLock locker(lock);
00415 if ( locker.isSuccessful() )
00416 {pull = data;}
00417 else
00418 {pull = mcopy;}
00419 }
00420
00426 DataType Get() const { DataType cache; Get(cache); return cache; }
00427
00433 void Set( const DataType& push )
00434 {
00435 {
00436 OS::MutexLock locker(lock);
00437 data = push;
00438 }
00439 mcopy = data;
00440 }
00441
00442 DataObjectPriorityGet<DataType>* clone() const {
00443 return new DataObjectPriorityGet<DataType>(name);
00444 }
00445
00446 DataObjectPriorityGet<DataType>* copy( std::map<const DataSourceBase*, DataSourceBase*>& ) const {
00447 return const_cast<DataObjectPriorityGet<DataType>*>(this);
00448 }
00449 };
00450
00479 template<class T>
00480 class DataObjectLockFree
00481 : public DataObjectInterface<T>
00482 {
00483 public:
00487 typedef T DataType;
00488
00497 static const unsigned int MAX_THREADS=8;
00498 private:
00502 static const unsigned int BUF_LEN=MAX_THREADS+2;
00503
00511 struct DataBuf {
00512 DataBuf()
00513 : data(), counter(), next()
00514 {
00515 oro_atomic_set(&counter, 0);
00516 }
00517 DataType data; mutable oro_atomic_t counter; DataBuf* next;
00518 };
00519
00520 typedef DataBuf* volatile VolPtrType;
00521 typedef DataBuf ValueType;
00522 typedef DataBuf* PtrType;
00523
00524 VolPtrType read_ptr;
00525 VolPtrType write_ptr;
00526
00530 DataBuf data[BUF_LEN];
00531
00532 std::string name;
00533
00534 public:
00535
00542 DataObjectLockFree(const std::string& _name, const T& initial_value = T() )
00543 : read_ptr(&data[ 0 ]),
00544 write_ptr(&data[ 1 ]),
00545 name(_name)
00546 {
00547
00548 for (unsigned int i = 0; i < BUF_LEN-1; ++i) {
00549 data[i].data = initial_value;
00550 data[i].next = &data[i+1];
00551 }
00552 data[BUF_LEN-1].next = &data[0];
00553 }
00554
00560 const std::string& getName() const { return name;}
00561
00562 void setName( const std::string& _name )
00563 {
00564 name = _name;
00565 }
00566
00574 DataType Get() const {DataType cache; Get(cache); return cache; }
00575
00583 void Get( DataType& pull ) const
00584 {
00585 PtrType reading;
00586
00587
00588
00589 do {
00590 reading = read_ptr;
00591 oro_atomic_inc(&reading->counter);
00592 if ( reading != read_ptr )
00593 oro_atomic_dec(&reading->counter);
00594 else
00595 break;
00596 } while ( true );
00597
00598
00599 pull = reading->data;
00600 oro_atomic_dec(&reading->counter);
00601 }
00602
00608 void Set( const DataType& push )
00609 {
00618
00619 write_ptr->data = push;
00620 PtrType wrote_ptr = write_ptr;
00621
00622
00623 while ( oro_atomic_read( &write_ptr->next->counter ) != 0 || write_ptr->next == read_ptr )
00624 {
00625 write_ptr = write_ptr->next;
00626 if (write_ptr == wrote_ptr)
00627 return;
00628 }
00629
00630
00631 read_ptr = wrote_ptr;
00632 write_ptr = write_ptr->next;
00633 }
00634
00635 DataObjectLockFree<DataType>* clone() const {
00636 return new DataObjectLockFree<DataType>(name);
00637 }
00638
00639 DataObjectLockFree<DataType>* copy( std::map<const DataSourceBase*, DataSourceBase*>& ) const {
00640 return const_cast<DataObjectLockFree<DataType>*>(this);
00641 }
00642
00643 };
00644
00652 template<class T>
00653 class DataObject
00654 : public DataObjectInterface<T>
00655 {
00659 T data;
00660
00661 std::string name;
00662 public:
00668 DataObject(const std::string& _name, const T& initial_value = T() )
00669 : data(initial_value), name(_name) {}
00670
00676 const std::string& getName() const { return name;}
00677
00678 void setName( const std::string& _name )
00679 {
00680 name = _name;
00681 }
00682
00686 typedef T DataType;
00687
00693 void Get( DataType& pull ) const { pull = data; }
00694
00700 DataType Get() const { return data; }
00701
00707 void Set( const DataType& push ) { data = push; }
00708
00709 DataObject<DataType>* clone() const {
00710 return new DataObject<DataType>(name);
00711 }
00712
00713 DataObject<DataType>* copy( std::map<const DataSourceBase*, DataSourceBase*>& ) const {
00714 return const_cast<DataObject<DataType>*>(this);
00715 }
00716
00717 };
00718 }
00719
00720 #endif
00721