Performance improvement to strnlen().

Václav Zeman vhaisman at gmail.com
Mon May 27 11:55:49 UTC 2013


On 27 May 2013 12:20, Lee Thomas wrote:
> On 2013-05-27 04:37, Václav Zeman wrote:
>>
>> On 26 May 2013 21:01, Lee Thomas wrote:
>>>
>>> On 2013-05-26 08:00, Václav Zeman wrote:
>>>>
>>>>
>>>> On 05/25/2013 10:27 PM, Lee Thomas wrote:
>>>>>
>>>>>
>>>>> +       lp = (const unsigned long *)((uintptr_t)str & ~LONGPTR_MASK);
>>>>> +       va = (*lp - mask01);
>>>>> +       vb = ((~*lp) & mask80);
>>>>
>>>>
>>>> I do not think that this correct C. This is type punning violating the
>>>> rules of the language.
>>>
>>>
>>>
>>> Hello Václav,
>>>
>>> The aliasing here is safe, because there are no writes through either of
>>> the
>>> pointers, and the reads are correctly aligned.
>>
>> I disagree. IANALL but AFAIK, this is simply not allowed by the
>> language => UB => even though it seems to work in this instance, you
>> are just lucky the UB is actually doing what you expect.
>>
>> --
>> VZ
>
>
> Hello Václav,
>
> I am not an expert in C either, so you may be right that this is technically
> illegal. However, I copied this code from strlen.c, which has had it, and
> still has it, for 4.5 years, and I can't see any way any alias analysis done
> by the compiler could invalidate this code. In addition, there are many
> places in the kernel, and in other codebases I've worked on, where this kind
> of type conversion is done. See for instance
> /sys/amd64/amd64/vm_macdep.c:200, where we compute the base of a thread's
> stackframe from a pointer to an unrelated type of 'struct pcb', and then
> write to it.
>
> I am willing to uglify the code in the way you suggest if that is the
> general concensus, but I think the code as it stands is both safe and more
> legible.
You could always put the three lines into a macro to keep the
strnlen() more readable.


--
VZ


More information about the freebsd-hackers mailing list