[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Gwydion & threads



On Mon, 18 Mar 2002 02:19:17 GMT, Neelakantan Krishnaswami
<neelk@alum.mit.edu> wrote:
>What I'm worried about is about programs seeing impossible values and
>dumping core. Suppose that object representation is (type-word,
>value-or-pointer), where each of the two components are a word. So an
>integer would be represented as (Integer-tag, <some-number>), and a
>string would be (String-tag, <pointer>).
>
>Now, take the following code:
>
>define variable x = 1234567;  // representation (Int, 1234567)
>
>// in thread A
>
>  x := "foobar"; // x becomes (String-tag, pointer to "foobar")
>
>// in thread B
>
>  frob(x);
>
>Now, suppose that frob(x) is called when the assignment in thread A
>has started but not completed, so that x has the value
>
>  (String-tag, 1234567).
>
>Then frob could reach into random bits of memory and do unpredictable
>things -- the language would be unsafe in the painful C sense, rather
>than safe in the happy Lisp/Smalltalk sense.
>
>When values are words, then even if the value of a variable is not
>consistent across threads, they are alawys *values*, rather than
>totally random bit-patterns. Now, I've not done much concurrent
>programming, so I'd like to know if this a realistic concern?

I am not familiar with the internal affairs of d2c, but it just struck me
that this problem could be solved by using a slightly different
representation of Dylan objects. As I have understood from this
discussion, in the general case, the object representation is something
like:

typedef struct
{
    u32 type_tag;
    u32 pointer_or_immediate_value;
} descriptor_t;

The problem with this in a multi-threaded environment is that an immediate
value can mistakenly be interpreted as a pointer with disastrous results.
It should be possible to avoid this by instead defining a general object
descriptor as:

typedef struct
{
    u32 type_tag_or_pointer;
    u32 immediate_value;
} new_descriptor_t;

The idea here is to represent type tags for immediate values by illegal
pointer bit patterns, for example 0x0, 0x1, 0x2 etc. or any unaligned
pointer. Heap allocated objects have to carry their own type tags (the tag
will not be encoded in the descriptor). With this representation, writing
a pointer to a descriptor will be an atomic operation: just update the
type_tag_or_pointer field with the new value. Writing an immediate value
will not be an atomic operation, since both fields will have to be
updated. This could cause interesting effects in other threads, since
funny objects could be read during the update. These can, however, not be
interpreted as pointer, but merely as immediate objects with incorrect
data.

Usage should be as follows:

Reading

if desc.type_tag_or_pointer is a valid pointer
    // use the pointed-to heap object
else
    // the object is immediate
end if;

Writing a pointer

desc.type_tag_or_pointer = &heap_object;

Writing an immediate value

desc.type_tag_or_pointer = INTEGER_TAG; // e.g. 0x1
desc.immediate_value = 42;


/Jonas ึster