/[svn]/linuxsampler/trunk/src/common/SynchronizedConfig.h
ViewVC logotype

Diff of /linuxsampler/trunk/src/common/SynchronizedConfig.h

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 846 by persson, Sun Mar 19 16:38:22 2006 UTC revision 1644 by persson, Sat Jan 19 16:55:03 2008 UTC
# Line 1  Line 1 
1  /***************************************************************************  /***************************************************************************
2   *                                                                         *   *                                                                         *
3   *   Copyright (C) 2006 Andreas Persson                                    *   *   Copyright (C) 2006-2008 Andreas Persson                               *
4   *                                                                         *   *                                                                         *
5   *   This program is free software; you can redistribute it and/or modify  *   *   This program is free software; you can redistribute it and/or modify  *
6   *   it under the terms of the GNU General Public License as published by  *   *   it under the terms of the GNU General Public License as published by  *
# Line 21  Line 21 
21  #ifndef __SYNCHRONIZEDCONFIG_H__  #ifndef __SYNCHRONIZEDCONFIG_H__
22  #define __SYNCHRONIZEDCONFIG_H__  #define __SYNCHRONIZEDCONFIG_H__
23    
 #include "atomic.h"  
24  #include <set>  #include <set>
25    
26  namespace LinuxSampler {  namespace LinuxSampler {
# Line 40  namespace LinuxSampler { Line 39  namespace LinuxSampler {
39       * safe to modify the other instance.       * safe to modify the other instance.
40       *       *
41       * The real time threads need one Reader object each to access the       * The real time threads need one Reader object each to access the
42       * confuration data. This object must be created outside the real       * configuration data. This object must be created outside the
43       * time thread. The Lock() function returns a reference to the       * real time thread. The Lock() function returns a reference to
44       * data to be read, and Unlock() must be called when finished       * the data to be read, and Unlock() must be called when finished
45       * reading the data. (Neither Lock nor Unlock will block the real       * reading the data. (Neither Lock nor Unlock will block the real
46       * time thread, or use any system calls.)       * time thread, or use any system calls.)
47       */       */
48      template<class T>      template<class T>
49      class SynchronizedConfig {      class SynchronizedConfig {
50            struct atomic_t { volatile int word; };
51    
52          public:          public:
53              SynchronizedConfig();              SynchronizedConfig();
54    
# Line 65  namespace LinuxSampler { Line 66  namespace LinuxSampler {
66                       *          thread                       *          thread
67                       */                       */
68                      const T& Lock() {                      const T& Lock() {
69                          atomic_set(&lock, 1);                          atomicSet(&lock, 1);
70                          return parent.config[atomic_read(&parent.indexAtomic)];                          return parent.config[atomicRead(&parent.indexAtomic)];
71                      }                      }
72    
73                      /**                      /**
# Line 78  namespace LinuxSampler { Line 79  namespace LinuxSampler {
79                       * time threads are locked anymore.                       * time threads are locked anymore.
80                       */                       */
81                      void Unlock() {                      void Unlock() {
82                          atomic_set(&lock, 0);                          atomicSet(&flag, 0);
83                            atomicSet(&lock, 0);
84                      }                      }
85    
86                      Reader(SynchronizedConfig& config);                      Reader(SynchronizedConfig& config);
# Line 87  namespace LinuxSampler { Line 89  namespace LinuxSampler {
89                      friend class SynchronizedConfig;                      friend class SynchronizedConfig;
90                      SynchronizedConfig& parent;                      SynchronizedConfig& parent;
91                      atomic_t lock;                      atomic_t lock;
92                        atomic_t flag;
93                      Reader *next; // only used locally in SwitchConfig                      Reader *next; // only used locally in SwitchConfig
94              };              };
95    
# Line 124  namespace LinuxSampler { Line 127  namespace LinuxSampler {
127              int updateIndex;              int updateIndex;
128              T config[2];              T config[2];
129              std::set<Reader*> readers;              std::set<Reader*> readers;
130    
131                static int atomicRead(atomic_t* pSharedVariable) {
132                    return pSharedVariable->word;
133                }
134    
135                static void atomicSet(atomic_t* pSharedVariable, int value) {
136                    pSharedVariable->word = value;
137                }
138      };      };
139    
140      template<class T> SynchronizedConfig<T>::SynchronizedConfig() {      template<class T> SynchronizedConfig<T>::SynchronizedConfig() {
141          atomic_set(&indexAtomic, 0);          atomicSet(&indexAtomic, 0);
142          updateIndex = 1;          updateIndex = 1;
143      }      }
144    
# Line 136  namespace LinuxSampler { Line 147  namespace LinuxSampler {
147      }      }
148    
149      template<class T> T& SynchronizedConfig<T>::SwitchConfig() {      template<class T> T& SynchronizedConfig<T>::SwitchConfig() {
150          atomic_set(&indexAtomic, updateIndex);          atomicSet(&indexAtomic, updateIndex);
151    
152          // first put all locking readers in a linked list          // first put all locking readers in a linked list
153          Reader* lockingReaders = 0;          Reader* lockingReaders = 0;
154          for (typename std::set<Reader*>::iterator iter = readers.begin() ;          for (typename std::set<Reader*>::iterator iter = readers.begin() ;
155               iter != readers.end() ;               iter != readers.end() ;
156               iter++) {               iter++) {
157              if (atomic_read(&(*iter)->lock)) {              atomicSet(&(*iter)->flag, 1);
158                if (atomicRead(&(*iter)->lock) && atomicRead(&(*iter)->flag)) {
159                  (*iter)->next = lockingReaders;                  (*iter)->next = lockingReaders;
160                  lockingReaders = *iter;                  lockingReaders = *iter;
161              }              }
# Line 154  namespace LinuxSampler { Line 166  namespace LinuxSampler {
166              usleep(50000);              usleep(50000);
167              Reader** prev = &lockingReaders;              Reader** prev = &lockingReaders;
168              for (Reader* p = lockingReaders ; p ; p = p->next) {              for (Reader* p = lockingReaders ; p ; p = p->next) {
169                  if (atomic_read(&p->lock)) prev = &p->next;                  if (atomicRead(&p->lock) && atomicRead(&p->flag)) prev = &p->next;
170                  else *prev = p->next; // unlink                  else *prev = p->next; // unlink
171              }              }
172          }          }
# Line 168  namespace LinuxSampler { Line 180  namespace LinuxSampler {
180    
181      template <class T>      template <class T>
182      SynchronizedConfig<T>::Reader::Reader(SynchronizedConfig& config) : parent(config) {      SynchronizedConfig<T>::Reader::Reader(SynchronizedConfig& config) : parent(config) {
183          atomic_set(&lock, 0);          atomicSet(&lock, 0);
184          parent.readers.insert(this);          parent.readers.insert(this);
185      }      }
186    

Legend:
Removed from v.846  
changed lines
  Added in v.1644

  ViewVC Help
Powered by ViewVC