Phil,

The code in your latest blog post omits an important detail, you have
to 'unbox' an alien pointer before you can do anything with it. The
values for old/new, as well as the result value, should probably be
unboxed and boxed too.

Passing an instance of the alien class to an int-rep register will
generate no conversion at all, and you'll have a tagged pointer to a
container holding the alien pointer -- not what you want in this case.
Also, passing untagged integers on the stack will quickly crash Factor
because it will confuse GC.

While Factor will eventually support intrinsics for boxing and
unboxing word-size integers, you'll be able to move forward for now
with fixnums only. Take a look at ^^unbox-c-ptr, ^^tag-fixnum and
^^untag-fixnum.

Since the x86 instruction here supports indexed addressing, you may as
well have ##atomic-compare-exchange also take an immediate offset.
This will eliminate add instructions in some cases, as well as
facilitate unboxing of displaced-alien instances. If you make this
change, you can reuse the machinery in compiler.cfg.intrinsics.alien
for generating the relevant unboxing code.

Your instruction produces a value _and_ has a side effect. I don't
remember if there are compiler passes that assume anything producing a
value is also side effect free. If there are, we'll need to change
things around a bit. In particular, if you drop the result, does the
operation remain in the IR?

A good eventual destination for some atomic integer abstractions would
be a vocabulary named concurrency.atomic. You could structure it in
the same manner as the SIMD library:
- concurrency.atomic: high-level words
- concurrency.atomic.intrinsics: unsafe intrinsics
- compiler.cfg.intrinsics.atomic: "intrinsic" word-prop definitions

I assume your next step is to implement a mailbox which is backed by
unmanaged memory. Ideally, this would use the same protocol as the
mailboxes in concurrency.mailboxes. Given an arbitrary object, they
would serialize and deserialize it. Long-term, I envision something
like a 'spawn-vm' word that spawns a new VM in a new native thread,
transmitting it a serialized quotation you pass in;

[ [ blahblah ] map ] "My VM" spawn-vm

Of course, the thread could pass itself in for communication back and
forth via messages:

self '[ _ blahblah ] "My VM" spawn-vm

serialization will need to be set up to do the right thing with thread
instances. I think distributed concurrency already supports this in
fact.

The VM would start, run the quotation, and shut down as soon as the
quotation returns. Of course you could implement something fancier on
top of this.

I've been pushing some extensive VM refactorings to the new_gc branch.
If you intend on doing more VM re-entrancy work, you should rebase
onto this branch since a lot has changed, particularly GC. Do you
think it is time to remove the ASSERT_VM_PTR stuff soon? I haven't
seen any assertion failures for a while.

A big project that someone will need to carry out in order for the
re-entrant VM stuff to be truly useful is to go through all the
libraries and fix certain idioms. Right now, many libraries have
initialization hooks which create external resources, but none of the
init hooks ever clean up. You'd need to make sure each library has an
uninit hook that can run to free those resources. A related issue
would be to find usages of 'exit' and replace it with something less
drastic. A good test would be to create a Factor VM, run
load-all/test-all, then shut it down and see if anything leaked. This
will take a while to get right.

For a real native-threaded Factor, the compiler would need to generate
safe-points for every backward branch or tail-recursive word call, so
that a potentially infinite loop can always be interrupted from
another thread. This is needed to support GC and other VM features in
a threaded environment. I would like to try implementing safe points
very soon, and using them to get a sampling profiler going, as well as
the ability to run arbitrary Factor code from Unix signal handlers.
Think being able to press ^C in the listener to safely interrupt an
infinite loo, etc. The issues with getting a consistent call stack
trace, and interrupting an arbitrary computation to safely run some
code, obviously carry over to native threads as well, so getting safe
points worked out first would be a plus.

Slava

------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Factor-talk mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/factor-talk

Reply via email to