/[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 1424 by schoenebeck, Sun Oct 14 22:00:17 2007 UTC
# Line 1  Line 1 
1  /***************************************************************************  /***************************************************************************
2   *                                                                         *   *                                                                         *
3   *   Copyright (C) 2006 Andreas Persson                                    *   *   Copyright (C) 2006, 2007 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(&lock, 0);
83                      }                      }
84    
85                      Reader(SynchronizedConfig& config);                      Reader(SynchronizedConfig& config);
# Line 124  namespace LinuxSampler { Line 125  namespace LinuxSampler {
125              int updateIndex;              int updateIndex;
126              T config[2];              T config[2];
127              std::set<Reader*> readers;              std::set<Reader*> readers;
128    
129                static int atomicRead(atomic_t* pSharedVariable) {
130                    return pSharedVariable->word;
131                }
132    
133                static void atomicSet(atomic_t* pSharedVariable, int value) {
134                    pSharedVariable->word = value;
135                }
136      };      };
137    
138      template<class T> SynchronizedConfig<T>::SynchronizedConfig() {      template<class T> SynchronizedConfig<T>::SynchronizedConfig() {
139          atomic_set(&indexAtomic, 0);          atomicSet(&indexAtomic, 0);
140          updateIndex = 1;          updateIndex = 1;
141      }      }
142    
# Line 136  namespace LinuxSampler { Line 145  namespace LinuxSampler {
145      }      }
146    
147      template<class T> T& SynchronizedConfig<T>::SwitchConfig() {      template<class T> T& SynchronizedConfig<T>::SwitchConfig() {
148          atomic_set(&indexAtomic, updateIndex);          atomicSet(&indexAtomic, updateIndex);
149    
150          // first put all locking readers in a linked list          // first put all locking readers in a linked list
151          Reader* lockingReaders = 0;          Reader* lockingReaders = 0;
152          for (typename std::set<Reader*>::iterator iter = readers.begin() ;          for (typename std::set<Reader*>::iterator iter = readers.begin() ;
153               iter != readers.end() ;               iter != readers.end() ;
154               iter++) {               iter++) {
155              if (atomic_read(&(*iter)->lock)) {              if (atomicRead(&(*iter)->lock)) {
156                  (*iter)->next = lockingReaders;                  (*iter)->next = lockingReaders;
157                  lockingReaders = *iter;                  lockingReaders = *iter;
158              }              }
# Line 154  namespace LinuxSampler { Line 163  namespace LinuxSampler {
163              usleep(50000);              usleep(50000);
164              Reader** prev = &lockingReaders;              Reader** prev = &lockingReaders;
165              for (Reader* p = lockingReaders ; p ; p = p->next) {              for (Reader* p = lockingReaders ; p ; p = p->next) {
166                  if (atomic_read(&p->lock)) prev = &p->next;                  if (atomicRead(&p->lock)) prev = &p->next;
167                  else *prev = p->next; // unlink                  else *prev = p->next; // unlink
168              }              }
169          }          }
# Line 168  namespace LinuxSampler { Line 177  namespace LinuxSampler {
177    
178      template <class T>      template <class T>
179      SynchronizedConfig<T>::Reader::Reader(SynchronizedConfig& config) : parent(config) {      SynchronizedConfig<T>::Reader::Reader(SynchronizedConfig& config) : parent(config) {
180          atomic_set(&lock, 0);          atomicSet(&lock, 0);
181          parent.readers.insert(this);          parent.readers.insert(this);
182      }      }
183    

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

  ViewVC Help
Powered by ViewVC