Changeset eae0863 in rtems


Ignore:
Timestamp:
04/27/14 08:11:09 (9 years ago)
Author:
Chris Johns <chrisj@…>
Branches:
4.11, 5, master
Children:
18bd35bc
Parents:
a070c8b
git-author:
Chris Johns <chrisj@…> (04/27/14 08:11:09)
git-committer:
Chris Johns <chrisj@…> (05/22/14 06:38:01)
Message:

rtems: Fix sp2038 test.

Avoid using newlib's gmtime_r call which fails with a max signed int.
Add an RTEMS specific version for 1/1/1988 to 31/12/2100.

Update sp2038 to test every day from 1/1/1988 to 31/12/2100. Only days
need be tested as the code splits the seconds based on days.

Files:
2 edited

Legend:

Unmodified
Added
Removed
  • cpukit/rtems/src/clockgettod.c

    ra070c8b reae0863  
    2323#include <rtems/config.h>
    2424
     25#define RTEMS_SECS_PER_MINUTE (60UL)
     26#define RTEMS_MINUTE_PER_HOUR (60UL)
     27#define RTEMS_SECS_PER_HOUR   (RTEMS_SECS_PER_MINUTE * RTEMS_MINUTE_PER_HOUR)
     28#define RTEMS_HOURS_PER_DAY   (24UL)
     29#define RTEMS_SECS_PER_DAY    (RTEMS_SECS_PER_HOUR * RTEMS_HOURS_PER_DAY)
     30#define RTEMS_DAYS_PER_YEAR   (365UL)
     31#define RTEMS_YEAR_BASE       (1970UL)
     32
     33extern const uint16_t _TOD_Days_to_date[2][13];
     34
     35static bool _Leap_year(
     36  uint32_t year
     37)
     38{
     39  return (((year % 4) == 0) && ((year % 100) != 0)) || ((year % 400) == 0);
     40}
     41
     42static uint32_t _Leap_years_before(
     43  uint32_t year
     44)
     45{
     46  year -= 1;
     47  return (year / 4) - (year / 100) + (year / 400);
     48}
     49
     50static uint32_t _Leap_years_between(
     51  uint32_t from, uint32_t to
     52)
     53{
     54  return _Leap_years_before( to ) - _Leap_years_before( from + 1 );
     55}
     56
     57static uint32_t _Year_day_as_month(
     58  uint32_t year, uint32_t *day
     59)
     60{
     61  const uint16_t* days_to_date;
     62  uint32_t        month = 0;
     63
     64  if ( _Leap_year( year ) )
     65    days_to_date = _TOD_Days_to_date[1];
     66  else
     67    days_to_date = _TOD_Days_to_date[0];
     68
     69  days_to_date += 2;
     70
     71  while (month < 11) {
     72    if (*day < *days_to_date)
     73      break;
     74    ++month;
     75    ++days_to_date;
     76  }
     77
     78  *day -= *(days_to_date - 1);
     79
     80  return month;
     81}
     82
    2583rtems_status_code rtems_clock_get_tod(
    2684  rtems_time_of_day  *time_buffer
    2785)
    2886{
    29   rtems_time_of_day *tmbuf = time_buffer;
    30   struct tm time;
    3187  struct timeval now;
     88  uint32_t       days;
     89  uint32_t       day_secs;
     90  uint32_t       year;
     91  uint32_t       year_days;
     92  uint32_t       leap_years;
    3293
    3394  if ( !time_buffer )
     
    40101  _TOD_Get_timeval( &now );
    41102
    42   /* Split it into a closer format */
    43   gmtime_r( &now.tv_sec, &time );
     103  /* How many days and how many seconds in the day ? */
     104  days = now.tv_sec / RTEMS_SECS_PER_DAY;
     105  day_secs = now.tv_sec % RTEMS_SECS_PER_DAY;
    44106
    45   /* Now adjust it to the RTEMS format */
    46   tmbuf->year   = time.tm_year + 1900;
    47   tmbuf->month  = time.tm_mon + 1;
    48   tmbuf->day    = time.tm_mday;
    49   tmbuf->hour   = time.tm_hour;
    50   tmbuf->minute = time.tm_min;
    51   tmbuf->second = time.tm_sec;
    52   tmbuf->ticks  = now.tv_usec /
    53     rtems_configuration_get_microseconds_per_tick();
     107  /* How many non-leap year years ? */
     108  year = ( days / RTEMS_DAYS_PER_YEAR ) + RTEMS_YEAR_BASE;
     109
     110  /* Determine the number of leap years. */
     111  leap_years = _Leap_years_between( RTEMS_YEAR_BASE, year );
     112
     113  /* Adjust the remaining number of days based on the leap years. */
     114  year_days = ( days - leap_years ) % RTEMS_DAYS_PER_YEAR;
     115
     116  /* Adjust the year and days in the year if in the leap year overflow. */
     117  if ( leap_years > ( days % RTEMS_DAYS_PER_YEAR ) ) {
     118    year -= 1;
     119    if ( _Leap_year( year ) ) {
     120      year_days += 1;
     121    }
     122  }
     123
     124  time_buffer->year   = year;
     125  time_buffer->month  = _Year_day_as_month( year, &year_days ) + 1;
     126  time_buffer->day    = year_days + 1;
     127  time_buffer->hour   = day_secs / RTEMS_SECS_PER_HOUR;
     128  time_buffer->minute = day_secs % RTEMS_SECS_PER_HOUR;
     129  time_buffer->second = time_buffer->minute % RTEMS_SECS_PER_MINUTE;
     130  time_buffer->minute = time_buffer->minute / RTEMS_SECS_PER_MINUTE;
     131  time_buffer->ticks  = now.tv_usec /
     132    rtems_configuration_get_microseconds_per_tick( );
    54133
    55134  return RTEMS_SUCCESSFUL;
  • testsuites/sptests/sp2038/init.c

    ra070c8b reae0863  
    284284}
    285285
     286static bool test_year_is_leap_year(uint32_t year)
     287{
     288    return (((year % 4) == 0) && ((year % 100) != 0)) || ((year % 400) == 0);
     289}
     290
     291static void test_every_day(void)
     292{
     293    rtems_time_of_day every_day = {
     294        .year = 1970,
     295        .month = 1,
     296        .day = 1,
     297        .hour = 0,
     298        .minute = 1,
     299        .second = 2
     300    };
     301    const int days_per_month[2][12] = {
     302        { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
     303        { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
     304    };
     305    rtems_status_code sc = RTEMS_SUCCESSFUL;
     306    rtems_time_of_day now;
     307
     308    for (every_day.year = 1988; every_day.year <= 2100; ++every_day.year) {
     309        int leap_year = test_year_is_leap_year(every_day.year) ? 1 : 0;
     310        for (every_day.month = 1; every_day.month <= 12; ++every_day.month) {
     311            int days = days_per_month[leap_year][every_day.month - 1];
     312            for (every_day.day = 1; every_day.day <= days; ++every_day.day) {
     313                sc = rtems_clock_set(&every_day);
     314                ASSERT_SC(sc);
     315                sc = rtems_clock_get_tod(&now);
     316                ASSERT_SC(sc);
     317                rtems_test_assert(memcmp(&now, &every_day, sizeof(now)) == 0);
     318            }
     319        }
     320    }
     321}
    286322
    287323rtems_task Init(rtems_task_argument argument)
     
    290326
    291327  test_tod_to_seconds();
     328  test_every_day();
    292329  test_problem_year();
    293330  test_leap_year();
Note: See TracChangeset for help on using the changeset viewer.