Changeset 1337


Ignore:
Timestamp:
Apr 7, 2004, 1:14:06 AM (21 years ago)
Author:
bird
Message:

#356: Don't care about the OS/2 reported timezone stuff. Reimplemented the function making it faster and more precise.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified branches/GCC_3-2-2_BETA4_BRANCH/src/emx/src/lib/sys/__ftime.c

    • Property cvs2svn:cvs-rev changed from 1.6 to 1.6.2.1
    r1336 r1337  
    1 /* sys/ftime.c (emx+gcc) -- Copyright (c) 1992-1996 by Eberhard Mattes */
     1/* $Id: $ */
     2/** @file
     3 *
     4 * LIBC SYS Backend - ftime.
     5 *
     6 * InnoTek Systemberatung GmbH confidential
     7 *
     8 * Copyright (c) 2004 InnoTek Systemberatung GmbH
     9 * Author: knut st. osmundsen <bird-srcspam@anduin.net>
     10 *
     11 * All Rights Reserved
     12 *
     13 */
    214
     15
     16/*******************************************************************************
     17*   Header Files                                                               *
     18*******************************************************************************/
    319#include "libc-alias.h"
     20#define INCL_BASE
     21#define INCL_DOSINFOSEG
    422#define INCL_FSMACROS
    523#include <os2emx.h>
     
    1129#include "syscalls.h"
    1230
    13 /* Return time in local format */
    14 void __ftime (struct timeb *ptr)
     31/**
     32 * Calcs the uDiff in formula timeb.millitm = (msecs + uDiff) % 1000.
     33 */
     34static unsigned calcdiff(void)
    1535{
    16   DATETIME now;
    17   struct tm tm;
    18   FS_VAR();
     36    /*
     37     * We make a little effort to lower the chances of preempting
     38     * while reading the msecs and hundredths members of GIS.
     39     */
     40    #pragma pack(1)
     41    union combined2
     42    {
     43        volatile unsigned long long ull;
     44        struct s
     45        {
     46            ULONG   msecs;
     47            UCHAR   hour;
     48            UCHAR   minutes;
     49            UCHAR   seconds;
     50            UCHAR   hundredths;
     51        } s;
     52    };
     53    #pragma pack()
     54    unsigned            uDiff;
     55    PGINFOSEG           pGIS = GETGINFOSEG();
     56    union combined2    *pCombined = (union combined2 *)&pGIS->msecs;
     57    union combined2     Combined;
    1958
    20   FS_SAVE_LOAD();
    21   DosGetDateTime (&now);
    22   FS_RESTORE();
    23   tm.tm_sec = now.seconds;
    24   tm.tm_min = now.minutes;
    25   tm.tm_hour = now.hours;
    26   tm.tm_mday = now.day;
    27   tm.tm_mon = now.month - 1;
    28   tm.tm_year = now.year - 1900;
     59    /*
     60     * Get a usable data set.
     61     *
     62     * We try to skip any msecs which end with 0. The two PCs I've got
     63     * here indicates that this is a good idea for consistency in the result.
     64     */
     65    Combined.ull = pCombined->ull;
     66    if (!(Combined.s.msecs % 10))
     67    {
     68        int i = 0;
     69        FS_VAR();
     70        FS_SAVE_LOAD();
     71        do
     72        {
     73            DosSleep(1);
     74            Combined.ull = pCombined->ull;
     75        } while (!(Combined.s.msecs % 10) && ++i < 2);
     76        FS_RESTORE();
     77    }
    2978
    30   ptr->time = (time_t)_mktime (&tm);
    31   /* Apply timezone correction to get UTC time since we don't know what
    32      timezone DosGetDateTime uses and whether it honors the TZ variable.
    33      Then apply application's own timezone to get local time back. */
    34   if (now.timezone != -1)
    35     ptr->time = ptr->time - (long)now.timezone * 60 + _tzi.tz;
    36   ptr->millitm = now.hundredths * 10;
     79    /*
     80     * Calc the diff value.
     81     */
     82    uDiff = Combined.s.hundredths * 10 - (Combined.s.msecs % 1000);
     83    if ((int)uDiff < 0)
     84        uDiff += 1000;                  /* must be positive for the rounding. */
     85    /* round up to closes 10. */
     86    uDiff += 9;
     87    uDiff /= 10;
     88    uDiff *= 10;
     89    return uDiff;
    3790}
     91
     92
     93/**
     94 * Get the current local time.
     95 * @param   ptr     Where to store the result.
     96 *                  Note that only the members time and millitm are filled in,
     97 *                  the caller is expected to fill the remaining fields.
     98 */
     99void __ftime(struct timeb *ptr)
     100{
     101    union combined
     102    {
     103        volatile unsigned long long ull;
     104        struct
     105        {
     106            ULONG       time;
     107            ULONG       msecs;
     108        } s;
     109    };
     110    static union
     111    {
     112        PGINFOSEG       pGIS;
     113        union combined *pCombined;
     114    } uGIS;
     115    static unsigned     uDiff;
     116    union combined      Combined;
     117
     118    /*
     119     * Init.
     120     */
     121    if (!uGIS.pGIS)
     122    {
     123        uDiff = calcdiff();
     124        uGIS.pGIS = GETGINFOSEG();
     125    }
     126
     127    /*
     128     * Get the value and convert it to the return format.
     129     */
     130    Combined = *uGIS.pCombined;
     131    ptr->time       = Combined.s.time;
     132    ptr->millitm    = (Combined.s.msecs + uDiff) % 1000;
     133    ptr->timezone   = 0;
     134    ptr->dstflag    = 0;
     135}
Note: See TracChangeset for help on using the changeset viewer.