diff mbox

[U-Boot,04/10] Use uint64_t for time types

Message ID 1413369519-11677-5-git-send-email-sjg@chromium.org
State Accepted
Delegated to: Tom Rini
Headers show

Commit Message

Simon Glass Oct. 15, 2014, 10:38 a.m. UTC
Unfortunately 'unsigned long long' and 'uint64_t' are not necessarily
compatible on 64-bit machines. Use the correct typedef instead of
writing the supposed type out in full.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 include/common.h |  2 +-
 lib/time.c       | 12 ++++++------
 2 files changed, 7 insertions(+), 7 deletions(-)

Comments

Tom Rini Oct. 27, 2014, 10:20 p.m. UTC | #1
On Wed, Oct 15, 2014 at 04:38:33AM -0600, Simon Glass wrote:

> Unfortunately 'unsigned long long' and 'uint64_t' are not necessarily
> compatible on 64-bit machines. Use the correct typedef instead of
> writing the supposed type out in full.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>

Applied to u-boot/master, thanks!
Masahiro Yamada Dec. 15, 2014, 4:55 p.m. UTC | #2
Hi Simon,


2014-10-15 19:38 GMT+09:00 Simon Glass <sjg@chromium.org>:
> Unfortunately 'unsigned long long' and 'uint64_t' are not necessarily
> compatible on 64-bit machines. Use the correct typedef instead of
> writing the supposed type out in full.

I doubt this statement.

I think "unsigned long long" always has 64bit width.

(C specification guarantees that the width of "unsigned long long"
is greater or equal to 64 bit)

Could you tell me which toolchain violates it?
Simon Glass Dec. 15, 2014, 6:38 p.m. UTC | #3
Hi Masahiro,

On 15 December 2014 at 09:55, Masahiro YAMADA <yamada.m@jp.panasonic.com> wrote:
> Hi Simon,
>
>
> 2014-10-15 19:38 GMT+09:00 Simon Glass <sjg@chromium.org>:
>> Unfortunately 'unsigned long long' and 'uint64_t' are not necessarily
>> compatible on 64-bit machines. Use the correct typedef instead of
>> writing the supposed type out in full.
>
> I doubt this statement.
>
> I think "unsigned long long" always has 64bit width.
>
> (C specification guarantees that the width of "unsigned long long"
> is greater or equal to 64 bit)
>
> Could you tell me which toolchain violates it?

Some compilers use 'unsigned long' and some use 'unsigned long long'.
I think that is the core of the problem.

We don't have a problem with unsigned long long not being at least
64-bit. I wonder whether some toolchains use 128-bit for this?

Regards,
Simon
Masahiro Yamada Dec. 16, 2014, 1:38 a.m. UTC | #4
Hi Simon,


2014-12-16 3:38 GMT+09:00 Simon Glass <sjg@chromium.org>:
> Hi Masahiro,
>
> On 15 December 2014 at 09:55, Masahiro YAMADA <yamada.m@jp.panasonic.com> wrote:
>> Hi Simon,
>>
>>
>> 2014-10-15 19:38 GMT+09:00 Simon Glass <sjg@chromium.org>:
>>> Unfortunately 'unsigned long long' and 'uint64_t' are not necessarily
>>> compatible on 64-bit machines. Use the correct typedef instead of
>>> writing the supposed type out in full.
>>
>> I doubt this statement.
>>
>> I think "unsigned long long" always has 64bit width.
>>
>> (C specification guarantees that the width of "unsigned long long"
>> is greater or equal to 64 bit)
>>
>> Could you tell me which toolchain violates it?
>
> Some compilers use 'unsigned long' and some use 'unsigned long long'.
> I think that is the core of the problem.
>
> We don't have a problem with unsigned long long not being at least
> 64-bit. I wonder whether some toolchains use 128-bit for this?

That is not my point.

"unsigned long long" has 64-bit width whether on 32bit compilers
or 64bit compilers or whatever.


We should always hard-code the definition:
  typedef  unsigned long long  uint64_t;

That's all.  We can always use "%llx" for printing uint64_t or u64.
(and this is what U-boot (and Linux) had used until you broke the consistency.)


If we include <stdint.h>, you are right.  It is the beginning of nightmare.
Some compilers use  "unsigned long" for uint64_t and some use
"unsigned long long"
for uint64_t.

What did it buy us?

You just introduced unreadability by using PRIu64  for printing 64bit
width variables.




Best Regards
Masahiro Yamada
Simon Glass Dec. 17, 2014, 4:38 a.m. UTC | #5
Hi Masahiro,

On 15 December 2014 at 18:38, Masahiro YAMADA <yamada.m@jp.panasonic.com> wrote:
>
> Hi Simon,
>
>
> 2014-12-16 3:38 GMT+09:00 Simon Glass <sjg@chromium.org>:
> > Hi Masahiro,
> >
> > On 15 December 2014 at 09:55, Masahiro YAMADA <yamada.m@jp.panasonic.com> wrote:
> >> Hi Simon,
> >>
> >>
> >> 2014-10-15 19:38 GMT+09:00 Simon Glass <sjg@chromium.org>:
> >>> Unfortunately 'unsigned long long' and 'uint64_t' are not necessarily
> >>> compatible on 64-bit machines. Use the correct typedef instead of
> >>> writing the supposed type out in full.
> >>
> >> I doubt this statement.
> >>
> >> I think "unsigned long long" always has 64bit width.
> >>
> >> (C specification guarantees that the width of "unsigned long long"
> >> is greater or equal to 64 bit)
> >>
> >> Could you tell me which toolchain violates it?
> >
> > Some compilers use 'unsigned long' and some use 'unsigned long long'.
> > I think that is the core of the problem.
> >
> > We don't have a problem with unsigned long long not being at least
> > 64-bit. I wonder whether some toolchains use 128-bit for this?
>
> That is not my point.
>
> "unsigned long long" has 64-bit width whether on 32bit compilers
> or 64bit compilers or whatever.

I think that might be true at least for gcc. But in principle a 64-bit
machine should use 128-bit for long long.

>
>
> We should always hard-code the definition:
>   typedef  unsigned long long  uint64_t;
>
> That's all.  We can always use "%llx" for printing uint64_t or u64.
> (and this is what U-boot (and Linux) had used until you broke the consistency.)
>
>
> If we include <stdint.h>, you are right.  It is the beginning of nightmare.
> Some compilers use  "unsigned long" for uint64_t and some use
> "unsigned long long"
> for uint64_t.
>
> What did it buy us?
>
> You just introduced unreadability by using PRIu64  for printing 64bit
> width variables.

I have also hit this problem with m68k and one other compiler in
U-Boot. Is it because these compilers are broken, or something else?

Regards,
Simon
Masahiro Yamada Dec. 22, 2014, 10:22 a.m. UTC | #6
Hi Simon,



On Tue, 16 Dec 2014 21:38:34 -0700
Simon Glass <sjg@chromium.org> wrote:

> Hi Masahiro,
> 
> On 15 December 2014 at 18:38, Masahiro YAMADA <yamada.m@jp.panasonic.com> wrote:
> >
> > Hi Simon,
> >
> >
> > 2014-12-16 3:38 GMT+09:00 Simon Glass <sjg@chromium.org>:
> > > Hi Masahiro,
> > >
> > > On 15 December 2014 at 09:55, Masahiro YAMADA <yamada.m@jp.panasonic.com> wrote:
> > >> Hi Simon,
> > >>
> > >>
> > >> 2014-10-15 19:38 GMT+09:00 Simon Glass <sjg@chromium.org>:
> > >>> Unfortunately 'unsigned long long' and 'uint64_t' are not necessarily
> > >>> compatible on 64-bit machines. Use the correct typedef instead of
> > >>> writing the supposed type out in full.
> > >>
> > >> I doubt this statement.
> > >>
> > >> I think "unsigned long long" always has 64bit width.
> > >>
> > >> (C specification guarantees that the width of "unsigned long long"
> > >> is greater or equal to 64 bit)
> > >>
> > >> Could you tell me which toolchain violates it?
> > >
> > > Some compilers use 'unsigned long' and some use 'unsigned long long'.
> > > I think that is the core of the problem.
> > >
> > > We don't have a problem with unsigned long long not being at least
> > > 64-bit. I wonder whether some toolchains use 128-bit for this?
> >
> > That is not my point.
> >
> > "unsigned long long" has 64-bit width whether on 32bit compilers
> > or 64bit compilers or whatever.
> 
> I think that might be true at least for gcc. But in principle a 64-bit
> machine should use 128-bit for long long.

128-bit variable?  Are you kidding?

I am not talking about "in principle" things, but talking
about real compilers.

So, on which compiler do you have problems?
For instance, please?



> >
> >
> > We should always hard-code the definition:
> >   typedef  unsigned long long  uint64_t;
> >
> > That's all.  We can always use "%llx" for printing uint64_t or u64.
> > (and this is what U-boot (and Linux) had used until you broke the consistency.)
> >
> >
> > If we include <stdint.h>, you are right.  It is the beginning of nightmare.
> > Some compilers use  "unsigned long" for uint64_t and some use
> > "unsigned long long"
> > for uint64_t.
> >
> > What did it buy us?
> >
> > You just introduced unreadability by using PRIu64  for printing 64bit
> > width variables.
> 
> I have also hit this problem with m68k and one other compiler in
> U-Boot. Is it because these compilers are broken, or something else?


I guess you are mentioning "size_t" problem on m68k.
http://thread.gmane.org/gmane.comp.boot-loaders.u-boot/188121/focus=188932

If so, you are already confused.

"size_t" is another problem that should be discussed separetely.


Notice
 [1] uint32_t, int32_t, uint64_t, int64_t, uintptr_t are provided by <stdint.h>
 [2] PRIx32, PRIx64, PRId32, PRId64 etc. are provided by <inttypes.h>
 [3] size_t is provided by <stddef.h>


We are talking about [1] and [2].

And also notice [1] and [2] should be provided by the same compiler to work correctly.

[3] should not be mixed up with [1].


If you are interested in the topic about the conflict between "size_t" type and "%z",
I can introduce you another thread.

But I am not showing that, in case this discussion goes wrong.




Best Regards
Masahiro Yamada
diff mbox

Patch

diff --git a/include/common.h b/include/common.h
index d8584dd..02befa6 100644
--- a/include/common.h
+++ b/include/common.h
@@ -776,7 +776,7 @@  void	invalidate_dcache_all(void);
 void	invalidate_icache_all(void);
 
 /* arch/$(ARCH)/lib/ticks.S */
-unsigned long long get_ticks(void);
+uint64_t get_ticks(void);
 void	wait_ticks    (unsigned long);
 
 /* arch/$(ARCH)/lib/time.c */
diff --git a/lib/time.c b/lib/time.c
index c7b0264..fe43ccb 100644
--- a/lib/time.c
+++ b/lib/time.c
@@ -41,7 +41,7 @@  unsigned long notrace timer_read_counter(void)
 extern unsigned long __weak timer_read_counter(void);
 #endif
 
-unsigned long long __weak notrace get_ticks(void)
+uint64_t __weak notrace get_ticks(void)
 {
 	unsigned long now = timer_read_counter();
 
@@ -49,11 +49,11 @@  unsigned long long __weak notrace get_ticks(void)
 	if (now < gd->timebase_l)
 		gd->timebase_h++;
 	gd->timebase_l = now;
-	return ((unsigned long long)gd->timebase_h << 32) | gd->timebase_l;
+	return ((uint64_t)gd->timebase_h << 32) | gd->timebase_l;
 }
 
 /* Returns time in milliseconds */
-static unsigned long long notrace tick_to_time(unsigned long long tick)
+static uint64_t notrace tick_to_time(uint64_t tick)
 {
 	ulong div = get_tbclk();
 
@@ -78,9 +78,9 @@  unsigned long __weak notrace timer_get_us(void)
 	return tick_to_time(get_ticks() * 1000);
 }
 
-static unsigned long long usec_to_tick(unsigned long usec)
+static uint64_t usec_to_tick(unsigned long usec)
 {
-	unsigned long long tick = usec;
+	uint64_t tick = usec;
 	tick *= get_tbclk();
 	do_div(tick, 1000000);
 	return tick;
@@ -88,7 +88,7 @@  static unsigned long long usec_to_tick(unsigned long usec)
 
 void __weak __udelay(unsigned long usec)
 {
-	unsigned long long tmp;
+	uint64_t tmp;
 
 	tmp = get_ticks() + usec_to_tick(usec);	/* get current timestamp */