Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make gettimeofday available in time module #53325

Closed
abalkin opened this issue Jun 25, 2010 · 43 comments
Closed

Make gettimeofday available in time module #53325

abalkin opened this issue Jun 25, 2010 · 43 comments
Assignees
Labels
extension-modules C modules in the Modules dir type-feature A feature request or enhancement

Comments

@abalkin
Copy link
Member

abalkin commented Jun 25, 2010

BPO 9079
Nosy @tim-one, @birkenfeld, @rhettinger, @mdickinson, @abalkin, @pitrou, @vstinner, @tjguk, @briancurtin, @rnk
Files
  • issue9079.diff
  • issue9079-fail.diff: this fails to build
  • issue9079-builds.diff: this builds
  • issue9079a.diff: Patch for py3k branch, revision 82936.
  • issue9079b.diff
  • issue9079c.diff
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = 'https://github.com/abalkin'
    closed_at = <Date 2012-03-14.00:49:07.012>
    created_at = <Date 2010-06-25.00:52:32.489>
    labels = ['extension-modules', 'type-feature']
    title = 'Make gettimeofday available in time module'
    updated_at = <Date 2012-03-14.00:49:07.011>
    user = 'https://github.com/abalkin'

    bugs.python.org fields:

    activity = <Date 2012-03-14.00:49:07.011>
    actor = 'vstinner'
    assignee = 'belopolsky'
    closed = True
    closed_date = <Date 2012-03-14.00:49:07.012>
    closer = 'vstinner'
    components = ['Extension Modules']
    creation = <Date 2010-06-25.00:52:32.489>
    creator = 'belopolsky'
    dependencies = []
    files = ['17767', '18032', '18033', '18045', '18108', '18403']
    hgrepos = []
    issue_num = 9079
    keywords = []
    message_count = 43.0
    messages = ['108575', '108577', '108599', '108612', '108614', '108942', '108947', '110104', '110112', '110113', '110114', '110125', '110158', '110475', '110476', '110478', '110479', '110480', '110482', '110483', '110488', '110491', '110493', '110496', '110498', '110508', '110509', '110510', '110516', '110535', '110583', '110603', '111077', '111085', '111095', '111096', '111098', '111099', '111102', '111105', '113000', '113001', '155698']
    nosy_count = 10.0
    nosy_names = ['tim.peters', 'georg.brandl', 'rhettinger', 'mark.dickinson', 'belopolsky', 'pitrou', 'vstinner', 'tim.golden', 'brian.curtin', 'rnk']
    pr_nums = []
    priority = 'normal'
    resolution = 'fixed'
    stage = 'needs patch'
    status = 'closed'
    superseder = None
    type = 'enhancement'
    url = 'https://bugs.python.org/issue9079'
    versions = ['Python 3.2']

    @abalkin
    Copy link
    Member Author

    abalkin commented Jun 25, 2010

    Attached patch moves cross-platform logic of obtaining current time to _time.c which is shared between time and datetime modules. This simplifies both modules and reduces the datetime module dependency on the time module.

    @abalkin abalkin self-assigned this Jun 25, 2010
    @abalkin abalkin added the extension-modules C modules in the Modules dir label Jun 25, 2010
    @abalkin
    Copy link
    Member Author

    abalkin commented Jun 25, 2010

    The new patch, bpo-9079.diff exposes gettimeofday as time.gettimeofday() returning (sec, usec) pair.

    @abalkin
    Copy link
    Member Author

    abalkin commented Jun 25, 2010

    Mark,

    I am reassigning this to you for commit review. I am changing the title to reflect the visible part of the change. The datetime module gains direct access to system gettimeofday at the C level while time module grows time.gettimeofday() Python method.

    I am not sure I made the best choice defining struct timeval on systems without gettimeofday. Maybe it is better to do

    typedef struct timeval _PyTime_timeval;

    on systems with gettimeofday and equivalent explicit definition on systems without.

    The cast selection logic for time_t is a bit of a hack as well, but this is the best I could come up with without resorting to configure tests. Unless this breaks on a known platform, I would rather commit this as is and have a separate project to clean up cross-platform time handling later.

    This patch builds on refactoring started in bpo-9012.

    @abalkin abalkin assigned mdickinson and unassigned abalkin Jun 25, 2010
    @abalkin abalkin changed the title Make gettimeofday available in datetime module Make gettimeofday available in time module Jun 25, 2010
    @abalkin abalkin added the type-feature A feature request or enhancement label Jun 25, 2010
    @rhettinger
    Copy link
    Contributor

    It would be great if Tim Peters could be consulted about some of these ideas. He put a great deal of thought into the API, what should be included and what should be excluded.

    @abalkin
    Copy link
    Member Author

    abalkin commented Jun 25, 2010

    I would very much appreciate Tim's input on datetime issues. This particular issue is fairly minor, but Tim's expertise will be invaluable for anything timezone related. I do appreciate the incredible amount of brainpower that went into the design of datetime module and I think the result is very good. There is only one thing that I would like to improve - eliminate the need to reach out to the time module when working with the datetime instances. This patch is a small step to removing the dependency at the implementation level.

    @mdickinson
    Copy link
    Member

    To keep things clean, would it be possible to separate this into two patches, one containing the refactoring and one for the newly exposed gettimeofday?

    @abalkin
    Copy link
    Member Author

    abalkin commented Jun 29, 2010

    The original patch, gettimeofday.diff was just refactoring. I unlinked it to keep the file list clean, but it is still available:

    http://bugs.python.org/file17766/gettimeofday.diff

    I decided to expose time.gettimeofday() in the same patch mostly in order to be able to better explain the consequences of the change such as date.today() now being equivalent to date.fromtimestamp(time.gettimeofday()[0]) rather than date.fromtimestamp(time.time()).

    @pitrou
    Copy link
    Member

    pitrou commented Jul 12, 2010

    Instead of being defined in _time.h, perhaps the new API function should be provided by core Python? It would probably help in certain threading primitives.

    @abalkin
    Copy link
    Member Author

    abalkin commented Jul 12, 2010

    On Mon, Jul 12, 2010 at 12:07 PM, Antoine Pitrou <report@bugs.python.org> wrote:
    ..

    Instead of being defined in _time.h, perhaps the new API function should be provided by core Python?

    This is an interesting idea, but proposed Py_gettimeofday inherits
    float_time logic of falling back on ftime and then plain time in case
    gettimeofday is not available. I am not sure this behavior is always
    beneficial. I notice that Python/ceval_gil.h has a comment /* We
    assume all modern POSIX systems have gettimeofday() */, which means it
    handles windows completely differently and using Py_gettimeofday
    instead of GETTIMEOFDAY in gil code may not be appropriate.

    @pitrou
    Copy link
    Member

    pitrou commented Jul 12, 2010

    > Instead of being defined in _time.h, perhaps the new API function should be provided by core Python?

    This is an interesting idea, but proposed Py_gettimeofday inherits
    float_time logic of falling back on ftime and then plain time in case
    gettimeofday is not available. I am not sure this behavior is always
    beneficial.

    I would say this is fine as long as it's "documented". The whole point
    of this API is precisely to avoid having to code the various fallbacks
    and conversions by yourself. People wanting full control over the code
    path can just write their own routine.

    I notice that Python/ceval_gil.h has a comment /* We
    assume all modern POSIX systems have gettimeofday() */, which means it
    handles windows completely differently and using Py_gettimeofday
    instead of GETTIMEOFDAY in gil code may not be appropriate.

    Indeed, the GIL code would probably still use its own code paths.
    However, other less sensitive code could rely on the new API. For
    example, it is not critical for lock timeouts to benefit from the full
    gettimeofday() precision.

    @abalkin
    Copy link
    Member Author

    abalkin commented Jul 12, 2010

    On Mon, Jul 12, 2010 at 1:06 PM, Antoine Pitrou <report@bugs.python.org> wrote:
    ..

    Indeed, the GIL code would probably still use its own code paths.
    However, other less sensitive code could rely on the new API. For
    example, it is not critical for lock timeouts to benefit from the full
    gettimeofday() precision.

    That may be true, but I would rather proceed in small steps. First
    expose it in _time.h so that it is shared by time and datetime
    modulesand then if specific uses are found inside core python, move it
    to a more appropriate header. Lock timeouts are not a good use case
    for gettimeofday because POSIX APIs use nonoseconds instead of
    microseconds.

    @mdickinson
    Copy link
    Member

    Assigning back to Alexander; sorry I haven't had time to look at this.

    @mdickinson mdickinson assigned abalkin and unassigned mdickinson Jul 12, 2010
    @rnk
    Copy link
    Mannequin

    rnk mannequin commented Jul 13, 2010

    The patch looks good to me FWIW.

    I would be interested in using this perhaps in bpo-8844, which involves lock timeouts. It may be true that the POSIX API uses nanoseconds, but pythreads only exposes microsecond precision.

    In order to use it from the thread module, it need to get moved into Python/. My best guess at the best place to put it would be sysmodule.c, since that already wraps other system calls. Or, you know, we could live a little and make a new file for it. :)

    @abalkin
    Copy link
    Member Author

    abalkin commented Jul 16, 2010

    OK, can someone show me an example of how functions defined in core Python can be made available to extension modules? I thought I could model pytime.h/.c after pymath.h/.c, but the later is not used in extension modules. I must be missing something trivial here.

    @pitrou
    Copy link
    Member

    pitrou commented Jul 16, 2010

    OK, can someone show me an example of how functions defined in core
    Python can be made available to extension modules? I thought I could
    model pytime.h/.c after pymath.h/.c, but the later is not used in
    extension modules. I must be missing something trivial here.

    You should just need to #include "pytime.h" from Include/Python.h.
    Actually, pymath.h is already included from there.

    @abalkin
    Copy link
    Member Author

    abalkin commented Jul 16, 2010

    No it must be something else. Attached bpo-9079-fail.diff fails with

    Symbol not found: __PyTime_gettimeofday
    Referenced from: .../build/lib.macosx-10.4-x86_64-3.2-pydebug/datetime.so

    even though it is in pytime.o

    $ nm ./Python/pytime.o
    00000000000009f0 s EH_frame1
    0000000000000000 T __PyTime_gettimeofday
    0000000000000a08 S __PyTime_gettimeofday.eh
                     U _gettimeofday
                     U _time

    @pitrou
    Copy link
    Member

    pitrou commented Jul 16, 2010

    Le vendredi 16 juillet 2010 à 19:51 +0000, Alexander Belopolsky a
    écrit :

    Alexander Belopolsky <belopolsky@users.sourceforge.net> added the comment:

    No it must be something else. Attached bpo-9079-fail.diff fails with

    Here it fails earlier:

    gcc -pthread -c -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I. -IInclude -I./Include -DPy_BUILD_CORE -o Python/structmember.o Python/structmember.c
    Python/pytime.c: In function ‘_PyTime_gettimeofday’:
    Python/pytime.c:37: erreur: storage size of ‘t’ isn’t known
    Python/pytime.c:38: attention : implicit declaration of function ‘ftime’
    Python/pytime.c:37: attention : unused variable ‘t’
    make: *** [Python/pytime.o] Erreur 1
    make: *** Attente des tâches non terminées....

    @abalkin
    Copy link
    Member Author

    abalkin commented Jul 16, 2010

    Antoine,

    you must be building on Windows. I'll try to guess where ftime is defined and repost the patch.

    @birkenfeld
    Copy link
    Member

    I'd like to help diagnose but I don't know what "Erreur 1" means.

    @abalkin
    Copy link
    Member Author

    abalkin commented Jul 16, 2010

    I fixed the ftime issue (I hope), but the build still fails. I did not test on Linux, but I tested on OSX with HAVE_FTIME. Replacing the failing patch.

    @abalkin
    Copy link
    Member Author

    abalkin commented Jul 16, 2010

    Removing spurious configure change from the "fail" patch.

    @abalkin
    Copy link
    Member Author

    abalkin commented Jul 16, 2010

    It looks like my reluctance to add gettimeofday to core without using it there was well founded. Simply adding a dummy call to _PyTime_gettimeofday in main() fixed the build problem. This is a hack, of course, so I am still looking for suggestions on how to make this work.

    ===================================================================

    --- Modules/python.c	(revision 82921)
    +++ Modules/python.c	(working copy)
    @@ -34,6 +34,8 @@
         m = fpgetmask();
         fpsetmask(m & ~FP_X_OFL);
     #endif
    +    struct timeval tv;
    +    _PyTime_gettimeofday(&tv);
         if (!argv_copy || !argv_copy2) {
             fprintf(stderr, "out of memory\n");
             return 1;

    @pitrou
    Copy link
    Member

    pitrou commented Jul 16, 2010

    It looks like my reluctance to add gettimeofday to core without using
    it there was well founded. Simply adding a dummy call to
    _PyTime_gettimeofday in main() fixed the build problem.

    It's rather strange. I'm sure we have external API functions which never
    get called in the core. Just a couple of attempts found one candidate:

    $ grep -r _PyImport_IsScript Modules/ Objects/ Python/ Include/
    Python/import.c:1804:PyAPI_FUNC(int) _PyImport_IsScript(struct filedescr * fd)
    Include/import.h:43:PyAPI_FUNC(int) _PyImport_IsScript(struct filedescr *);

    @pitrou
    Copy link
    Member

    pitrou commented Jul 16, 2010

    > It looks like my reluctance to add gettimeofday to core without using
    > it there was well founded. Simply adding a dummy call to
    > _PyTime_gettimeofday in main() fixed the build problem.

    It's rather strange. I'm sure we have external API functions which never
    get called in the core. Just a couple of attempts found one candidate:

    Hmm, after thinking about it, what happens is that the C object file is
    not used at all, so it's probably optimized away by the linker.
    In any case, you could use the new API in Python/thread_pthread.h.

    @mdickinson
    Copy link
    Member

    Hmm, after thinking about it, what happens is that the C object file is
    not used at all, so it's probably optimized away by the linker.

    That sounds right. I recall similar problems with pymath.c at one stage: none of the functions it defined was being used in the core, so it didn't get compiled into the python executable and the build failed similarly.

    @rnk
    Copy link
    Mannequin

    rnk mannequin commented Jul 16, 2010

    Right, it's one of the peculiarities of archive files (I think). When none of an object file's symbols are used from the main program, the object file is dropped on the floor, ie not included. This has bizarre consequences in C++ with static initializers, which get dropped.

    On Windows, the PyAPI_FUNC macros should prevent the linker from stripping the datetime stuff.

    Jeff Yasskin says you should create a noop function in your object file and call it from PyMain for force linkage of the object file you're building.

    @pitrou
    Copy link
    Member

    pitrou commented Jul 16, 2010

    Jeff Yasskin says you should create a noop function in your object
    file and call it from PyMain for force linkage of the object file
    you're building.

    Indeed, something like _PyTime_Init().
    I don't think Modules/python.c is a good place though, since it means
    that applications embedding Python won't get the symbol.
    Perhaps Python/pythonrun.c instead?

    @abalkin
    Copy link
    Member Author

    abalkin commented Jul 16, 2010

    Reid,

    I am leaning towards reverting to Plan A (bpo-9079.diff). Would your use case be served well by a _time module exposing C API via a capsule? This what datetime does currently.

    @rnk
    Copy link
    Mannequin

    rnk mannequin commented Jul 16, 2010

    I'd really rather not try to rely module loading from a threading primitive. :)

    I think if you follow Antoine's suggestion of adding _PyTime_Init (which does nothing in the body other than a comment) it should work fine.

    @abalkin
    Copy link
    Member Author

    abalkin commented Jul 17, 2010

    It turns out I misunderstood how date.today() worked [1] and bpo-9079.diff introduced significant change in behavior. Bringing timeofday into core rather than _time.c also introduced several complications. As a result it makes sense to start with just internal restructuring: bring gettimeofday into core and reuse it in time.time and datetime.datetime.now. The new patch, issue9079a.diff contains no user visible changes.

    [1] "Curious datetime method" http://mail.python.org/pipermail/python-dev/2010-July/102003.html

    @rnk
    Copy link
    Mannequin

    rnk mannequin commented Jul 17, 2010

    I think you forgot to svn add pytime.c before making the diff.

    @abalkin
    Copy link
    Member Author

    abalkin commented Jul 17, 2010

    Indeed. Replacing issue9079a.diff now.

    @rnk
    Copy link
    Mannequin

    rnk mannequin commented Jul 21, 2010

    pytime.h looks like it got pasted into the file twice. Other than that, it looks good to me and the tests pass on OS X here.

    @briancurtin
    Copy link
    Member

    issue9079a.diff doesn't compile on Windows - timeval isn't defined. You'd have to include Winsock2.h [0]. Adding something like the following within the HAVE_FTIME block would work...
    #ifdef MS_WINDOWS
    #include <Winsock2.h>
    #endif

    I don't currently have time to dig deeper into this stuff, but test_queue hangs. Running the suite without test_queue leaves 31 other failures and something hangs in the background so the test never completes. That was all done with issue9079a.diff applied, plus my winsock include.

    [0] http://msdn.microsoft.com/en-us/library/ms740560(VS.85).aspx

    @abalkin
    Copy link
    Member Author

    abalkin commented Jul 21, 2010

    Interesting. As far as I can tell, struct timeval should not be used unless HAVE_GETTIMEOFDAY is defined:

    +#ifdef HAVE_GETTIMEOFDAY
    +typedef struct timeval _PyTime_timeval;
    +#else
    +typedef struct {
    + time_t tv_sec; /* seconds since Jan. 1, 1970 */
    + long tv_usec; /* and microseconds */
    +} _PyTime_timeval;
    +#endif

    Brian, where do you get undefined symbol error?

    @rnk
    Copy link
    Mannequin

    rnk mannequin commented Jul 21, 2010

    I think you used 'struct timeval *' in the function definition instead of '_PyTimeVal *'.

    @briancurtin
    Copy link
    Member

    Here are the errors I get:

    Error 104 error C2037: left of 'tv_sec' specifies undefined struct/union 'timeval' c:\python-dev\py3k\Python\pytime.c 46 pythoncore
    Error 105 error C2037: left of 'tv_usec' specifies undefined struct/union 'timeval' c:\python-dev\py3k\Python\pytime.c 47 pythoncore

    @abalkin
    Copy link
    Member Author

    abalkin commented Jul 21, 2010

    I think Reid nailed the issue. Fix is coming.

    @abalkin
    Copy link
    Member Author

    abalkin commented Jul 21, 2010

    issue9079b.diff should fix the Windows issue.

    @briancurtin
    Copy link
    Member

    I won't have time to review this, but I can say issue9079b.diff works fine on Windows.

    @abalkin
    Copy link
    Member Author

    abalkin commented Aug 5, 2010

    Updated the patch to reflect recent datetimemodule.c renaming to _datetimemodule.c. No other changes between issue9079b.diff and issue9079c.diff. I am going to commit issue9079c.diff soon unless someone wants more time to review.

    @abalkin
    Copy link
    Member Author

    abalkin commented Aug 5, 2010

    Committed issue9079c.diff as r83744. This commit does not provide time.gettimeofday() and therefore does not close the issue.

    @vstinner
    Copy link
    Member

    The new patch, bpo-9079.diff exposes gettimeofday
    as time.gettimeofday() returning (sec, usec) pair.

    A tuple is not the preferred type for a timestamp: Python uses float and is not going to use something different (the PEP-410 was just rejected).

    I don't see what we need a new function: there is always time.time().

    I'm closing this issue because I consider it as done.

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    extension-modules C modules in the Modules dir type-feature A feature request or enhancement
    Projects
    None yet
    Development

    No branches or pull requests

    7 participants