If I understand the code correctly, the primary indicator of an item being a link to the parent is that valueType
is null. There are two functions that check this - isEmpty()
and isParentPointer()
, which is a bit redundant. But there is also TaskLocal::NextLinkType::IsParent
flag set in the next
field if next
is non-null, but not set if next
is null. TaskLocal::NextLinkType
looks redundant to me.
Do I understand this correctly? Does TaskLocal::NextLinkType
serve a purpose or is it there only for historical reasons?
Can it be cleaned up? From the one hand it seems to be a part of the ABI, but from the other, it exists only in runtime, and is not part of the binary data emitted by the compiler.
As part of work on the revised version of SE-0371 I want to add a new kind of node - a stop node.
When encountered, stop node terminates lookup in TaskLocal::Storage::getValue()
and copying in TaskLocal::Storage::copyTo()
. But it does not terminate destruction in TaskLocal::Storage::destroy()
.
One way to encode the 3 kinds of nodes without touching lower bits of next
, would be this simple scheme:
Kind | valueType | key |
---|---|---|
Value | non-null | * |
Parent | null | 0 |
Stop | null | 1 |
Alternatively, I can keep using NextLinkType
and use something like this:
Kind | valueType | key | next |
---|---|---|---|
Value | non-null | * | null or pointer |
Parent | null | null | null or (pointer | 1) |
Stop | null | null | pointer | 2 |
As an optimization I can avoid creating stop-nodes when linked list is already empty, then stop nodes will never have null next pointer.
And also looks like TaskLocal::Storage
is always initialised to at least one parent link node for tasks, but can be empty for FallbackTaskLocalStorage
. Can storage also be empty for tasks as well, for consistency and efficiency?