Skip to content

Reentrant caching? #56

@ghost

Description

Is JPL supposed to be multi-threaded capabel, i.e. reentrant? Because this code doesn’t work as a cache: There might be race conditions where two or more jpl_iref_type_cache/2 are asserted. A reentrant cache is a little bit more difficult to implement and needs a mutex.

jpl_object_to_type(Ref, Type) :-
    jpl_is_object(Ref),
    (   jpl_iref_type_cache(Ref, T)
    ->  true                                % T is Tag's type
    ;   jpl_object_to_class(Ref, Cobj),     % else get ref to class obj
        jpl_class_to_type(Cobj, T),         % get type of class it denotes
        jpl_assert(jpl_iref_type_cache(Ref,T))
    ),
    Type = T.

One way to do it, is as follows. But it has the drawback that time is spent inside the mutx by ‘jpl_object_to_class/2’ etc… Using destructive operations which would be also seen through facts, this can be even done outside of the mutex, and would be faster. So this is only an imperfect sketch:

jpl_object_to_type(Ref, Type) :-
    jpl_is_object(Ref),
    (   jpl_iref_type_cache(Ref, T)
    ->  true                                % T is Tag's type
    ;   with_mutex(jpl_iref_type_cache_mutex, 
               (jpl_iref_type_cache(Ref, T)        % need to do check again
               ->  true;
               jpl_object_to_class(Ref, Cobj),     % else get ref to class obj
               jpl_class_to_type(Cobj, T),         % get type of class it denotes
               jpl_assert(jpl_iref_type_cache(Ref,T)))
        )
    ),
    Type = T.

Maybe alternatively an elegant approach could be using SWI-Prolog shared tabling.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions