Global objects semantic with templates

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Gianguz

    #1

    Global objects semantic with templates

    I'd like to discuss about the opportunity to have a global objects
    creator that introduces into a general framework
    (suited for multithreading) a controlled semantic to manage
    globals variables (objects and scalar-types).

    In the following example Global is able to create objects of any kind
    with and index value attached to. So a Global<0, string> is a unique
    string instance object allocated into the system that can be accessed
    from any point into the program simply 'creating' another instance of
    Global<int, T> with the same id and type.

    Like globals, destruction of these objects is delegated
    until the lifetime expiration of the program.

    Here is the example:

    #include <string>
    #include <iostream>

    using namespace std;

    template<int I,class T> class Global {

    public:

    static const int Index = I;

    typedef T Type;

    Global() { }

    Global(const T& t) { __set(t); }

    const Global& operator =(const T& t) { __set(t); }

    operator T&() { return __get(); }

    ~Global() { }

    private:

    static T& __get() {
    //access can be serialized here for multithreading
    static T Value;

    return Value;
    }

    static void __set(const T& t) {
    //access can be serialized here for multithreading
    static T& Value = __get();

    Value = t;

    return;
    }
    };


    int main() {

    typedef Global<0, string> Global0;
    typedef Global<1, string> Global1;

    Global0 a;
    Global1 b;

    a = "I'm A";

    b = "I'm B";

    cout << (string&)a << " " << (string&)b << endl;

    a = b;

    cout << (string&)a << " " << (string&)b << endl;

    typedef Global<1, string> Global2;

    Global2 c;

    c = "I'm C";

    cout << (string&)a << " " << (string&)b << endl;
    }

    Someone thinks that it can be useful? Or something like that is
    already used. In that case can you give me some reference about.

    Thanks,

    Gianguglielmo
  • Paavo Helde

    #2
    Re: Global objects semantic with templates

    gianguglielmo.c alvi@noze.it (Gianguz) wrote in
    news:afbb0050.0 412030144.2a173 5b5@posting.goo gle.com:
    [color=blue]
    > I'd like to discuss about the opportunity to have a global objects
    > creator that introduces into a general framework
    > (suited for multithreading) a controlled semantic to manage
    > globals variables (objects and scalar-types).
    >
    > In the following example Global is able to create objects of any kind
    > with and index value attached to. So a Global<0, string> is a unique
    > string instance object allocated into the system that can be accessed
    > from any point into the program simply 'creating' another instance of
    > Global<int, T> with the same id and type.
    >
    > Like globals, destruction of these objects is delegated
    > until the lifetime expiration of the program.
    >
    > Here is the example:
    >
    > #include <string>
    > #include <iostream>
    >
    > using namespace std;
    >
    > template<int I,class T> class Global {
    >
    > public:
    >
    > static const int Index = I;
    >
    > typedef T Type;
    >
    > Global() { }
    >
    > Global(const T& t) { __set(t); }
    >
    > const Global& operator =(const T& t) { __set(t); }
    >
    > operator T&() { return __get(); }
    >
    > ~Global() { }
    >
    > private:
    >
    > static T& __get() {
    > //access can be serialized here for multithreading
    > static T Value;
    >
    > return Value;
    > }
    >
    > static void __set(const T& t) {
    > //access can be serialized here for multithreading
    > static T& Value = __get();
    >
    > Value = t;
    >
    > return;
    > }
    > };
    >[/color]

    Just some remarks:

    1. Double underscore is reserved for compiler/stdlibrary implementations .
    You may not use such identifiers in your own code.

    2. *Any* globals in multithreading environment are quite suspect. In your
    case the possible locking as indicated by the comments is probably at the
    wrong place. There is often no use for locking separately the get() and
    set() functions, as the set() function may thus silently overwrite the
    results of set()-s called from other threads. One solution would be to
    return a proxy object from the get() function, which locks the global
    until set() function call on it, and/or scope exit. But this doesn't fit
    well with your nice implicit conversion operators...

    3. IIRC, statics in templates have been a troublesome area for some
    compilers in the past, so this approach might practically not be as
    portable as one might wish.

    HTH
    Paavo

    Comment

    • Gianguz

      #3
      Re: Global objects semantic with templates

      Paavo Helde <paavo@ebi.ee > wrote in message news:<Xns95B615 0D6ACB3paavo256 @194.126.101.12 4>...[color=blue]
      > gianguglielmo.c alvi@noze.it (Gianguz) wrote in
      > news:afbb0050.0 412030144.2a173 5b5@posting.goo gle.com:[/color]
      [color=blue]
      > Just some remarks:
      >
      > 1. Double underscore is reserved for compiler/stdlibrary implementations .
      > You may not use such identifiers in your own code.
      >[/color]

      Right!;) Somewhat that can be used freely could be a single
      underscore?
      [color=blue]
      > 2. *Any* globals in multithreading environment are quite suspect. In your
      > case the possible locking as indicated by the comments is probably at the
      > wrong place. There is often no use for locking separately the get() and
      > set() functions, as the set() function may thus silently overwrite the
      > results of set()-s called from other threads. One solution would be to
      > return a proxy object from the get() function, which locks the global
      > until set() function call on it, and/or scope exit. But this doesn't fit
      > well with your nice implicit conversion operators...
      >[/color]

      I dont' clearly understand that.
      If T1,T2,T3 call for instance 2 set and 1 get locking on the same
      semaphore,
      the get will simply take the last modified value.

      For instance:

      T1 T2 T3 RESULT
      set('a') set('b') get() 'b'
      set('b') set('a') get() 'a'
      set('a') get() set('b') 'a'
      set('b') get() set('a') 'b'
      get() set('a') set('b') 'default'
      get() set('b') set('a') 'default'

      And that is the 'Faked' ;) code:

      using namespace std;

      class FakeSemaphore {

      public:

      FakeSemaphore() { }

      void lock() { }

      void unlock() { }

      ~FakeSemaphore( ) { }
      };

      static FakeSemaphore _semaphore;

      template<class LOCK> class FakeGuard {

      private:

      FakeSemaphore* sem;

      FakeGuard();

      public:

      FakeGuard(FakeS emaphore* s) { sem = s; sem->lock(); }

      ~FakeGuard() { sem->unlock(); }
      };

      template<int I,class T> class Global {

      public:

      static const int Index = I;

      typedef T Type;

      Global() { }

      Global(const T& t) { _set(t); }

      const Global& operator =(const T& t) { _set(t); return *this; }

      operator T&() { return _get(); }

      ~Global() { }

      private:

      static T& _get() {
      FakeGuard<FakeS emaphore> guard(&_semapho re);
      static T Value;

      return Value;
      }

      static void _set(const T& t) {
      FakeGuard<FakeS emaphore> guard(&_semapho re);
      static T& Value = _get();

      Value = t;

      return;
      }
      };


      int main() {

      typedef Global<0, string> Global0;
      typedef Global<1, string> Global1;

      Global0 a;
      Global1 b;

      a = "I'm A";

      b = "I'm B";

      cout << (string&)a << " " << (string&)b << endl;

      a = b;

      cout << (string&)a << " " << (string&)b << endl;

      typedef Global<b.Index, Global1::Type> Global2;

      Global2 c;

      c = "I'm C";

      cout << (string&)a << " " << (string&)b << endl;
      }

      I agree about the proxy object as a general solution but in that case
      I think locking should rely on the class itself to keep it
      lightweight.
      Do you think that this code could produce inconsistent
      concurrent r/w sequences?
      [color=blue]
      > 3. IIRC, statics in templates have been a troublesome area for some
      > compilers in the past, so this approach might practically not be as
      > portable as one might wish.
      >[/color]

      What kind of problems? What kind of mistake can the compiler (in my
      case gcc works well) produce with a simple static variable declared
      into a simple 2 typename class template?

      Thanks!
      [color=blue]
      > HTH
      > Paavo[/color]

      Comment

      Working...