http://appcore.home.comcast.net/vzoom/refcount/
It includes has MSVC++ 7.1 and Dev-C++ IDE project/solution files and
pre-build assembly language object files. It currently compiles with
MASM/GAS or MSVC/GCC; a versions' for the SPARC 32/64 is also in the works.
You can assemble the GAS version and then make use of GCC in order to get
you up and running on most IA-32 based operating systems (e.g., Linux,
Solaris, Unix, ect...).
If you try it, let me know how everything worked out. Can you
compile/assemble it? The IDE project/solution files should make it easy.
Any comments/questions/whatever?
Thank you for you time!
Chris Thomasson
It's on the way! :)
I have wrapped the C API with some C++ in the form of a couple of smart
pointer classes. I am planning on releasing the experimental C++ wrappers
within the next two or three days; maybe sooner... I am also going to
release some fairly crude, but complete, documentation that explains exactly
how to use the raw C API. Anyway, once you get your hands on the smart
pointers you should have no real problems wrt understanding how to make
proper use them. The smart pointer classes should be virtually
crowbar-proof, as long as you don't do something completely stupid. For
instance, you would not want to execute the following "suicide" code:
typedef vzoom::thread::sync::wptr<myobj_t> myobj_wptr_t;
myobj_t *stupid_retard = 0;
{
myobj_wptr_t ptr(new myobj_t);
stupid_retard = ptr.operator ->();
}
// OH HELL NO!!!
stupid_retard->something_really_really_dumb(); // :^O
LOL!
;)
http://appcore.home.comcast.net/vzoom/refcount/
http://appcore.home.comcast.net/vzoom/refcount/refcount.hpp
http://appcore.home.comcast.net/vzoom/refcount/refcount-sys.hpp
http://appcore.home.comcast.net/vzoom/refcount/refcount-ia32-0-0-0-2.zip
Adding CAS shortly...
I found a killed a bug. It only existed in the C++ Abstraction API. It has
to do with the fact that pointers to user objects are contained in the
userstate<T>::m_state member. I was returning a pointer to the userstate<T>,
rather than the userstate<T>::m_state member in the following functions:
inline T* load_ptr() throw() {
return static_cast<T*>(atomic_state_load_depends());
}
inline T const* load_ptr() const throw() {
return static_cast<T const*>(atomic_state_load_depends());
}
They have to be changed to this:
inline T* load_ptr() throw() {
return static_cast<userstate<T>*>(atomic_state_load_depends())->m_state;
}
inline T const* load_ptr() const throw() {
return static_cast<userstate<T>*>(atomic_state_load_depends())->m_state;
}
Also, you need to add this to the userstate<T> class:
friend class ptr_base<T>;
The code is fixed on my site. Sorry for any confusion!
;^(...
Luckily, the bug was in the C++ layer, and not in the assembly!
;^)
I am curious, *did anyone else notice (e.g., seg-fault) that little god
dam%ed# hell-spawn lurking around? Man, it slipped under my radar!
FU@#$@K@!!
Here is a direct link to the fixed file:
http://appcore.home.comcast.net/vzoom/refcount/refcount-sys.hpp
The bug was only in the C++ stuff, so you don't have to re-download the
entire library, just the fixed C++ header file...
Again, sorry for not noticing this crappy little bug sitting in my C++! I
hate little bullshi% bugs like that... I think I hate them more than those
completely annoying and subtle pointer de-referencing demon-seed bugs!!!!
:O
* - Has anyone downloaded and experimented with my refcount algorithm at
all??? If so, any thoughts?
;^)
I had to add this file:
http://appcore.home.comcast.net/vzoom/refcount/spinlock-ia32.c
And alter this one:
http://appcore.home.comcast.net/vzoom/refcount/spinlock-ia32.h
You should probably re-download:
http://appcore.home.comcast.net/vzoom/refcount/refcount-ia32-0-0-0-2.zip
Thank You.
http://appcore.home.comcast.net/vzoom/refcount/doc/
I am going to be steadily adding to this initial documentation over the next
week or so. Documentation that covers the C++ API is coming shortly...
Thank You,
Chris Thomasson
http://appcore.home.comcast.net/
(portable lock-free data structures)
Shouldn't the library initialisation function return an instance of the
library?
It's good library etiquette, especially if you hope to write threaded
code using it.
I'm sure you're aware of this, so I'm probably missing a sizeable point
somewhere.
RF
IMHO, your correct when the library requires a process to make a call to
some sort of destructor function. If no destruction call is required by the
library you can bypass the logic that is required to maintain a global
dynamic library pointer (e.g., implies some sort of atomic reference
counting or PDR logic is implied here), so you can get around that
overhead...
Ideally, the library initialization function should be called by a process
early in its lifetime and perhaps before it creates threads. If the process
can't do that, then it can rely on stores into ptr::global to atomically
initialize their internal refcount_t objects and any user-state that is tied
to it; including pointers to their own libraries dynamic global instance
state.
> It's good library etiquette, especially if you hope to write threaded
> code using it.
> I'm sure you're aware of this, so I'm probably missing a sizeable point
> somewhere.
Stores intro ptr::global will ensure that everything is visible. I defined
the function like that in order to give the calling process a chance to
optimize... It can take the fact that than call to initialize the refcount
library is not thread-safe, and choose to put it under the protection of one
of their in-house synchronization objects... The more low-level you get, the
more flexible everything becomes...
;^)
> Stores intro ptr::global will ensure that everything is visible. I defined
> the function like that
^^^^^^^^^^^^^^^^^^^^^^^
is suppose to read:
the refcount library initialization function like that
> in order to give the calling process a chance to optimize... It can take
> the fact that than call to initialize the refcount library is not
> thread-safe, and choose to put it under the protection of one of their
> in-house synchronization objects... The more low-level you get, the more
> flexible everything becomes...
[...]
> ;^)
> >> http://appcore.home.comcast.net/vzoom/refcount/doc/
> >
> > Shouldn't the library initialisation function return an instance of the
> > library?
>
> IMHO, your correct when the library requires a process to make a call to
> some sort of destructor function. If no destruction call is required by the
> library you can bypass the logic that is required to maintain a global
> dynamic library pointer (e.g., implies some sort of atomic reference
> counting or PDR logic is implied here), so you can get around that
> overhead...
>
> Ideally, the library initialization function should be called by a process
> early in its lifetime and perhaps before it creates threads. If the process
> can't do that, then it can rely on stores into ptr::global to atomically
> initialize their internal refcount_t objects and any user-state that is tied
> to it; including pointers to their own libraries dynamic global instance
> state.
[...]
> Stores intro ptr::global will ensure that everything is visible. I defined
> the function like that in order to give the calling process a chance to
> optimize... It can take the fact that than call to initialize the refcount
> library is not thread-safe, and choose to put it under the protection of one
> of their in-house synchronization objects... The more low-level you get, the
> more flexible everything becomes...
Hmm, if you say so. However it sounds like you're putting your
library's requirements in the comments rather than in the syntax,
making them anything but intransigent.
In any case, at least you don't require the overriding of main,
an unforgivable sin in my eyes mainly because libraries that
do so aren't libraries anymore... the list of shame includes
SDL, Clanlib, MFC, gtk, etc...
RF