This compare two 32 bits times
Sponsored-by: The FreeBSD Foundation
Differential D25700
linuxkpi: Add time_after32 manu on Jul 17 2020, 8:02 AM. Authored by Tags None Referenced Files
Subscribers
Details
This compare two 32 bits times Sponsored-by: The FreeBSD Foundation
Diff Detail
Event Timeline
Comment Actions Casts do make huge difference. Proposed code matches what Linux does. Btw why not import time_before32() and time_between{,32}() as well ? Comment Actions I simply import what the new drm code uses, I'll see to import them as well tomorow or friday. Comment Actions Konstantin: Please explain why: (int)((unsigned)(x) - (unsigned)(y)) is different from I don't get it. Comment Actions I mean the outer cast should be enough! Else many more macros in this file should be fixed. Comment Actions If both x and y have type unsigned or unsigned types with rank less than unsigned, then indeed there is no change. Otherwise, the proposed code behavior depends on the relative rank of x, y, and uint32_t, and x,y signess. Manu' code does either unsigned promotion or clipping on each argument, then it performs arithmetic mod UINT32_MAX, then reinterprets the result as signed. Your code promotes one of the argument to integer type of rank of other argument, depending on what type is wider. If one type is unsigned, then other value is promoted unsigned, and again arithmetic mod size is performed. But if both types are signed, then arithmetic is done as signed (*) and this potentially invokes undefined behavior if the result cannot be represented as signed.
Comment Actions If clipping must be predictable by use of a (unsigned) case when compiling, then more macros in this file needs an update! Doesn't freebsd specify -fwrapv, to avoid these issues? Comment Actions No, the result has the promoted type of left and right operands. Basically the shorter type is promoted to wider one. But there are additional rules when operands have different signess. Well, clipping is orthogonal to overflow. Idea with -fwrapv is to fix already broken code, but try to not introduce new broken places. With all that corner cases and hard-to-correctly-interpret semantic, I do not see why it is useful to deviate from Linux original. Comment Actions
Instead of casting, would a static inline function be better, and more clean code-wise? Comment Actions I do not see much difference between the macro and an inline function for such small code fragment. My caution with the function would be that it changes evaluation of arguments, in particular, the side-effects, comparing with the Linux version. Comment Actions @manu: What do you think about implementing the set of time_xxx functions we have as time_xxx_32() functions? Even though you don't need them right now, we will have a consistent set of macros there? Comment Actions This is a question about required semantic of the Linux function. If (since ?) they require int32_t result, we should be explicit and not rely on the fact that all our current platforms have int32_t same as int. Comment Actions Agreed, we don't need the int32_t cast but it's clearer to leave it to show what linux expect of the macro. |