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.
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.
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:
Maybe alternatively an elegant approach could be using SWI-Prolog shared tabling.