Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

vesoljc

shared data

This topic is 5263 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

i''m trying to design a number of objects that would take care of problems, which arise when using shared data on multiple threads. and i need help most of these objects will be COM-like. they''ll have reference counting which will in combination with smart pointers take care of automatic cleanup. so, the first object to create is a base which will provide ref counting. since these will be shared data, normal ref counting does not provide everything i want. with the help of a GD community i came up with this: pseudocode
class MTRefCountedObject
{
   public:
       void AddRef    (const ThreadID&);
       void Release   (const ThreadID&);
   protected:
        map<ThreadID, uint>       mdRefMap;
        status_bitset             mdStatus;         
};
so, when using addref and release, we need to provide the "users" thread id. if object is used in nonMT enviroment, only one item is created in the map and the status is having the "notshared" flag. if used by multiple threads, more items are created and the status flag is chaneged to "shared". now, this class provides a base for smart pointer templated class. the next thing is the actuall data wrapper. as i see it, we need accessor functions which work based on the status. if shared flag is set, these functions will use internal locking, if not, "normal" way will be used. pseudocode
template
class SharedData<TYPE>: public MTRefCountedObject
{
    public:
      TYPE  ReadData     ();
            WriteData    (TYPE);
    protected:
    private:
        TYPE         mdData;    // actuall data

};
1) however, one thing is giving me troubles. how should read data be returned? as a temporary? is it logical to assume that "users" have their local copy of that object? what bout writing? 2) one idea is also to make a double buffered SharedData. now, this gives me an idea to make a base class (abstract?) "SharedData", on which SharedDataSimple and SharedDataDoubleBuf would be implemented. this makes any sense? Abnormal behaviour of abnormal brain makes me normal...

Share this post


Link to post
Share on other sites
Advertisement
A couple of things you might find useful:

* The C++ volatile keyword. A must-know when you have shared data.
* Loki''s smart pointer code, which includes thread safety policy classes.

Share this post


Link to post
Share on other sites
<regains consciousness>

Your multi-threaded reference counter is not thread safe.

And I don''t understand why you need to keep track of a reference count per-thread.

Share this post


Link to post
Share on other sites
heh, u were out for two minutes? that was funny

my ref counter is not thread safe? well, i wrote in front of it that it''s just pseudocode.

and as for the second question: is there any other way for an object to know if it''s being used by a single thread or by multiple? and yes, i know that objects should not care about this, but this one is special

Abnormal behaviour of abnormal brain makes me normal...

Share this post


Link to post
Share on other sites
You need to pessemistically lock access to the map and the static_bit just-in-case it is accessed by more than one thread at a time (you will have a race condition if you don't). So you /always/ must handle it in the multi-threaded manor. So the presence of status_bitset means it cannot be a correct design.

You could tell it at compile time if it lives in a STA or a MTA (single-thread or multi-thread apartment). You could get fancy and make a multi-threaded policy. If you keep the map, you will need a mutex (use a process-local mutex, aka Win32 critical section). It you drop the map, you can use an atomic increment and decrement on an integer - on Win32 these functions are called InterlockedIncrement/Decrement - and then you don't need a mutex.



template<bool MultiThreaded=true>
class RefCountedObject
{
//...

};




Classic reference counting works fairly well in a multi-threaded environment. What are you doing that's special?

[edited by - Magmai Kai Holmlor on April 23, 2004 1:06:41 AM]

Share this post


Link to post
Share on other sites
IMHO the concept of having ownership of some data shared between 2 threads is kinda flawed from start. Personally I think building a system that allows it easily, is promoting bad practice. Maybe there is some isolted case when is the only solution, I just cannot see any right now.

ciao
Alberto

Share this post


Link to post
Share on other sites
first, tnx for the replies.

@mkh

i know that in above example i need a lock to protect data, allways. but why not try to avoid it higher in the object hierarchy?

as for the compile time solution, i dont like, coz the enviroment could change in a dinamic fashion.


@fagiano

i''m not seeing it as ownership, only as an access point.

Abnormal behaviour of abnormal brain makes me normal...

Share this post


Link to post
Share on other sites
If it can change in a dynamic fashion then you must pessimistically assume the multi-threaded case - and once again you can decide at compile time. It''ll still work fine for the single-thread case, it''ll just have unneeded overhead.

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!