freenode/#clasp - IRC Chatlog
Search
13:51:27
frgo
When readingf the logs I thought it would be good to have a macro AS-CRITICAL-SECTION() that wraps a piece of code into a safeguard thereby guaranteeing that whatever code is in this section is thread-safe. Is that doable at all? How?
13:54:02
Shinmera
There's multiple ways of going about it. One way would be to put up a barrier for all threads on entry, keep all other threads sleeping until you resume.
13:55:32
frgo
Ok, true - that's not what I wanted. I wanted to have a macro that walks code to ensure that every place is treated in an atomic way. Does that sound crazy?
14:20:22
drmeister
I'm switching the GF call-history and specializer-profile update to use 'copy-and-swap'.
15:16:36
drmeister
The question is: about memoizing a new call history entry - I'm using CAS to update the call history. I created a loop where I read the call-history, I generate a new call history and then I use CAS to install the new call history. If the call-history has been updated in the meantime I start from the beginning again.
15:17:29
drmeister
Once I have updated the call-history I recompile and install a new discriminating function.
15:18:43
drmeister
I think I should have a loop within a loop. The outer loop uses CAS to update the discriminating function and the inner loop uses CAS to update the call-history.
15:20:28
drmeister
Thinking that the point of using CAS is to ensure that when I leave this function that memoizes a new call that the discriminator function should be completely up to date.
15:22:11
drmeister
I'm worried about two threads T1 and T2 getting a dispatch-miss at the same time. T1 updates the call history and recompiles a discriminator function but in the meantime T2 updates the call history again and installs a new discriminator function - then T1 overwrites it.
15:23:29
beach
Are you sure you can't get an infinite sequence of first updating the call history and then the discriminating function this way?
15:25:41
drmeister
The inner loop would update the call-history. If the outer loop detects that the discriminator function has changed the outer loop starts again. This time the inner loop detects that the call history already includes the specializers and it returns to the outer loop.
15:28:33
beach
Before, did you mean "copy-and-swap" (A C++ idiom apparently) or "compare-and-swap" (an instruction to help with synchronization)?
15:32:31
drmeister
There's a problem with my suggestion however. The MOP SET-FUNCALLABLE-INSTANCE-FUNCTION is not useful for this - I need a COMPARE-AND-SWAP-FUNCALLABLE-INSTANCE-FUNCTION
15:34:00
drmeister
That causes me a lot of anxiety - if I can't do something without the MOP - have I gone off the rails?
15:37:24
drmeister
Or - I'm causing problems by compiling a new discriminating function after memoizing an entry in the call history.
15:38:41
drmeister
Perhaps I should just be invalidating the discriminating function and let the invalidated-dispatch-function call compile a new discriminating function (I use dispatch function and discriminating function interchangeably).
15:39:42
beach
That would be my preferred solution. But then, I haven't worked out the scenarios, and I can't, because they depend a lot on the representation of things.
15:40:18
beach
Also, there are different reasons for updating the call history, and they might need to be handled differently.
15:41:17
drmeister
They will need to be handled differently. I'm worrying about the routine updating of the call-history due to dispatch-misses. Changing classes and methods is a whole other can of worms.
15:45:42
beach
For example, in SICL, I have a rack containing both the call history and the discriminating function. I could make the protocol so that it has to allocate a new rack. Then I can use a single CAS to update the entire thing.
15:47:31
beach
Notice that I am not saying it is a GOOD idea. Just that the possibilities depend intimately on the representation.
15:50:10
beach
When I made that decision (representing every object with a header and a rack), I had a hunch that it would help both with synchronization and with memory management. But I fully admit that I didn't work out all the scenarios at that point. I still haven't.
15:59:48
frgo
beach: where in SICL di see the object representation being coded/implemented? (I want to learn how you actually did that header + rack thing)
16:00:59
beach
During the bootstrapping process, the header is represented as a host standard instance, and the rack as a host vector.
16:02:01
beach
Once I have a graph in the host that is isomorphic to the one I want in the executable, I traverse that graph and generate binary code in the form of an executable.
16:53:21
drmeister
beach: Clasp also has a header/rack implementation for CLOS objects. Although there are a few more things in the header to mimic ECL-style objects.
17:53:20
Serenitty[m]
Otherwise, the target triple error messages make it practically unusable. It's hard to see the actual output.
18:01:04
Serenitty[m]
Huh. The issue is that it still lags whenever all a slew of those error messages comes up — they're just invisible.
18:03:16
Serenitty[m]
Oh, so it normally takes a minute to compile whenever you define a function in the REPL?
21:25:37
drmeister
I've converted the fastgf over from using a generic function lock to using compare-and-swap on all updates to the call-history and the specializer-profile.