From patchwork Fri Oct 11 18:06:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joseph Myers X-Patchwork-Id: 1996270 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=RSfm+/ez; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=libc-alpha-bounces~incoming=patchwork.ozlabs.org@sourceware.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4XQF3v18hHz1xtv for ; Sat, 12 Oct 2024 05:08:27 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 53B9B385734D for ; Fri, 11 Oct 2024 18:08:25 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id B6F123858C2B for ; Fri, 11 Oct 2024 18:08:05 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org B6F123858C2B Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org B6F123858C2B Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1728670088; cv=none; b=LvFajCSw3uGw0G78WO4UV8nyPv+avMIbGzYnfOCitgKNjfgpTDfq8f2GJAyVKnicMSY4sTEBOQGaQNlsmy6q2o7KmDBShSselN9JHHAfOZ+KsUnIvkcLM1BC6KpYk8kIV/VJgHEkb78oaNLa/mKKAcBHekbai7cBD1pGbinNI1E= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1728670088; c=relaxed/simple; bh=ND910DoqL+Xw9ndaxxIOIcVH5KZXr9XRO16G2UvTpzM=; h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version; b=DnnOncTbW9qskh5c1ZqPeOsJh8EIij9J8UOuW9reZSWPltfp3leLVnCiM05Whl0AcVbiz9MBwgy+pFG2qJG6fNE2Q1hXQdrMeewbmONS7kjZfgI83dUcbxhQ+A8QUkxcCdPJ1/kZkcBKbNeeJD2+U59cyQv3AZcZjqcuS+1Pvqs= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1728670085; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=RwEePYE19Jiv+RX36bfiAXADmQBBTpVCrcHxZL8IQ0M=; b=RSfm+/ezWpHSllZp9jrso0Yt8OWZUvuxGgRy8bCuayzNQ5Fx3g++Vb0QCgga9gQywf0Vqr jYaLfDtdhzfr6/AR9qHnxr/zRlOrcHF1j/zF+jeokSoZa55YYP1Sf9D35prsn/l9XXvPaI mBV26IfZSTOr3mpp7EyHexoZjP4kEFk= Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-573-XaWoGKKqMLiA5NLE1ya3Ng-1; Fri, 11 Oct 2024 14:07:44 -0400 X-MC-Unique: XaWoGKKqMLiA5NLE1ya3Ng-1 Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-43123d8a33dso2463215e9.3 for ; Fri, 11 Oct 2024 11:07:44 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1728670063; x=1729274863; h=mime-version:references:message-id:in-reply-to:subject:to:from:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=RwEePYE19Jiv+RX36bfiAXADmQBBTpVCrcHxZL8IQ0M=; b=nF7IMF4J869Uj0+CpuFvaBJ/IlJ3XR1DdEgKxnJggnzoY8AilT1f+eW0WaywBdGK9C o218MwI70Vbl6X+U3r4bZINQC6NfrL2RKajKbDgu1Dq5brbM06ySX4nLAjsOzZ5D+Jsm 9ABm3+Sn3WSKx/eqfWrPBRk9GwPmfzF6BWiw2cQHsUXhSOSk7r/ckyYzLulBJSAgPD9C Eks907ocWIm7BEar4TWxmUsi6ULXC2aqSO97EvAc6mRhSoUDD2uCVKBE3vsWNqjgJMBE qtfLYO3jmv1k8ggpgj/xgo8j5l7KZGP1Eg1wyMVxrR72ZKyT8merY00E9+b3Jtj18cOf mnxA== X-Gm-Message-State: AOJu0Yx9BKiT164Q5XFgbkC9mI5fGDoaScDOYyAweEGXmL0Rz/OZK0W9 Wvnsn1EioTEDboHGSS3DmnLk2DkOMbldX/YqBEHT3GWUiVV7rxX24EScM1stxUr06A0nL/T9d6w SGE1TRZuG/oTn+L8FXjDeVrIvJH9vi6ReAJ3/0ClLzUs2nPREsu+1blLu462xYgXs+PPjWKdFRD Rf6H6nTPe9XMkItBKDtlr+RScorUIkuyiPnmCY2lZxsA== X-Received: by 2002:a5d:46d1:0:b0:37d:4d31:e86c with SMTP id ffacd0b85a97d-37d5529f0b7mr2365007f8f.44.1728670062375; Fri, 11 Oct 2024 11:07:42 -0700 (PDT) X-Google-Smtp-Source: AGHT+IG3p0D1jUM1UcW9qo73mqEZl8k7pmJFE+PXdntdYaAg2hF+yuGmzR6kP7mo26sWbIre6GZkTw== X-Received: by 2002:a5d:46d1:0:b0:37d:4d31:e86c with SMTP id ffacd0b85a97d-37d5529f0b7mr2364983f8f.44.1728670061605; Fri, 11 Oct 2024 11:07:41 -0700 (PDT) Received: from digraph.polyomino.org.uk (digraph.polyomino.org.uk. [2001:8b0:bf73:93f7::51bb:e332]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-37d4b917df3sm4448363f8f.111.2024.10.11.11.07.41 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Oct 2024 11:07:41 -0700 (PDT) Received: from jsm28 (helo=localhost) by digraph.polyomino.org.uk with local-esmtp (Exim 4.97) (envelope-from ) id 1szK2V-0000000AMrd-39JL for libc-alpha@sourceware.org; Fri, 11 Oct 2024 18:06:59 +0000 Date: Fri, 11 Oct 2024 18:06:59 +0000 (UTC) From: Joseph Myers To: libc-alpha@sourceware.org Subject: [PATCH v2] Add tests of time, gettimeofday, clock_gettime In-Reply-To: <685b5889-5044-13eb-f93c-68e15b0cd467@redhat.com> Message-ID: <4d9ee30c-c0de-e18b-059d-99302e84fc01@redhat.com> References: <685b5889-5044-13eb-f93c-68e15b0cd467@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-9.1 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~incoming=patchwork.ozlabs.org@sourceware.org Add tests of time, gettimeofday, clock_gettime There are no tests specifically focused on the functions time, gettimeofday and clock_gettime, although there are some incidental uses in tests of other functions. Add tests specifically for these three functions. Tested for x86_64 and x86. --- Changed in v2: allow clock_gettime to fail with CLOCK_REALTIME_ALARM and CLOCK_BOOTTIME_ALARM. It appears these can fail on some system configurations, in particular those used by Linaro CI for both AArch64 and Arm. diff --git a/time/Makefile b/time/Makefile index d06797b06c..de22692683 100644 --- a/time/Makefile +++ b/time/Makefile @@ -53,6 +53,7 @@ tests := \ tst-adjtime \ tst-clock \ tst-clock2 \ + tst-clock_gettime \ tst-clock_nanosleep \ tst-clock_settime \ tst-cpuclock1 \ @@ -61,6 +62,7 @@ tests := \ tst-ftime \ tst-ftime_l \ tst-getdate \ + tst-gettimeofday \ tst-gmtime \ tst-itimer \ tst-mktime \ @@ -77,6 +79,7 @@ tests := \ tst-strptime-whitespace \ tst-strptime2 \ tst-strptime3 \ + tst-time \ tst-timegm \ tst-timespec_get \ tst-timespec_getres \ @@ -90,16 +93,19 @@ tests-time64 := \ tst-adjtime-time64 \ tst-clock-time64 \ tst-clock2-time64 \ + tst-clock_gettime-time64 \ tst-clock_nanosleep-time64 \ tst-clock_settime-time64 \ tst-cpuclock1-time64 \ tst-ctime-time64 \ tst-difftime-time64 \ + tst-gettimeofday-time64 \ tst-gmtime-time64 \ tst-itimer-time64 \ tst-mktime4-time64 \ tst-settimeofday-time64 \ tst-strftime4-time64 \ + tst-time-time64 \ tst-timegm-time64 \ tst-timespec_get-time64 \ tst-timespec_getres-time64 \ diff --git a/time/tst-clock_gettime-time64.c b/time/tst-clock_gettime-time64.c new file mode 100644 index 0000000000..5b215d11f8 --- /dev/null +++ b/time/tst-clock_gettime-time64.c @@ -0,0 +1 @@ +#include "tst-clock_gettime.c" diff --git a/time/tst-clock_gettime.c b/time/tst-clock_gettime.c new file mode 100644 index 0000000000..5f59ec1a6b --- /dev/null +++ b/time/tst-clock_gettime.c @@ -0,0 +1,155 @@ +/* Test clock_gettime function. + Copyright (C) 2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include + +#include +#include + +/* Compare two struct timespec values, returning a value -1, 0 or 1. */ + +int +compare_timespec (const struct timespec *tv1, const struct timespec *tv2) +{ + if (tv1->tv_sec < tv2->tv_sec) + return -1; + if (tv1->tv_sec > tv2->tv_sec) + return 1; + if (tv1->tv_nsec < tv2->tv_nsec) + return -1; + if (tv1->tv_nsec > tv2->tv_nsec) + return 1; + return 0; +} + +struct test_clockid +{ + clockid_t clockid; + const char *name; + bool is_cputime; + bool fail_ok; +}; + +#define CLOCK(clockid) { clockid, # clockid, false, false } +#define CLOCK_CPU(clockid) { clockid, # clockid, true, false } +#define CLOCK_FAIL_OK(clockid) { clockid, # clockid, false, true } + +static const struct test_clockid clocks[] = + { + CLOCK (CLOCK_REALTIME), +#ifdef CLOCK_MONOTONIC + CLOCK (CLOCK_MONOTONIC), +#endif +#ifdef CLOCK_PROCESS_CPUTIME_ID + CLOCK_CPU (CLOCK_PROCESS_CPUTIME_ID), +#endif +#ifdef CLOCK_THREAD_CPUTIME_ID + CLOCK_CPU (CLOCK_THREAD_CPUTIME_ID), +#endif +#ifdef CLOCK_MONOTONIC_RAW + CLOCK (CLOCK_MONOTONIC_RAW), +#endif +#ifdef CLOCK_REALTIME_COARSE + CLOCK (CLOCK_REALTIME_COARSE), +#endif +#ifdef CLOCK_MONOTONIC_COARSE + CLOCK (CLOCK_MONOTONIC_COARSE), +#endif +#ifdef CLOCK_BOOTTIME + CLOCK (CLOCK_BOOTTIME), +#endif +#ifdef CLOCK_REALTIME_ALARM + CLOCK_FAIL_OK (CLOCK_REALTIME_ALARM), +#endif +#ifdef CLOCK_BOOTTIME_ALARM + CLOCK_FAIL_OK (CLOCK_BOOTTIME_ALARM), +#endif +#ifdef CLOCK_TAI + CLOCK (CLOCK_TAI), +#endif + }; + +int +do_test (void) +{ + /* Verify that the calls to clock_gettime succeed, that the time does + not decrease, and that time returns a truncated (not rounded) + version of the time. */ + for (size_t i = 0; i < sizeof clocks / sizeof clocks[0]; i++) + { + printf ("testing %s\n", clocks[i].name); + struct timespec ts1, ts2, ts3; + int ret; + time_t t1; + t1 = time (NULL); + TEST_VERIFY_EXIT (t1 != (time_t) -1); + ret = clock_gettime (clocks[i].clockid, &ts1); + if (clocks[i].fail_ok && ret == -1) + { + printf ("failed (OK for this clock): %m\n"); + continue; + } + TEST_VERIFY_EXIT (ret == 0); + if (clocks[i].clockid == CLOCK_REALTIME) + TEST_VERIFY (t1 <= ts1.tv_sec); + TEST_VERIFY (ts1.tv_nsec >= 0); + TEST_VERIFY (ts1.tv_nsec < 1000000000); + ret = clock_gettime (clocks[i].clockid, &ts2); + TEST_VERIFY_EXIT (ret == 0); + TEST_VERIFY (compare_timespec (&ts1, &ts2) <= 0); + TEST_VERIFY (ts2.tv_nsec >= 0); + TEST_VERIFY (ts2.tv_nsec < 1000000000); + /* Also verify that after sleeping, the time returned has + increased. Repeat several times to verify that each time, + the time from the time function is truncated not rounded. + For CPU time clocks, the time spent spinning on the CPU, and + so whether we end in the later half of a second, is not + predictable; thus, only test once for those clocks. */ + const struct timespec duration = { .tv_nsec = 100000000 }; + for (int j = 0; j < 5; j++) + { + if (clocks[i].is_cputime) + for (volatile unsigned int x = 0; x != (unsigned int) -1; x++) + ; + else + { + ret = nanosleep (&duration, NULL); + TEST_VERIFY_EXIT (ret == 0); + } + t1 = time (NULL); + TEST_VERIFY_EXIT (t1 != (time_t) -1); + ret = clock_gettime (clocks[i].clockid, &ts3); + TEST_VERIFY_EXIT (ret == 0); + TEST_VERIFY (compare_timespec (&ts2, &ts3) < 0); + if (clocks[i].clockid == CLOCK_REALTIME) + TEST_VERIFY (t1 <= ts3.tv_sec); + TEST_VERIFY (ts3.tv_nsec >= 0); + TEST_VERIFY (ts3.tv_nsec < 1000000000); + ts2 = ts3; + if (clocks[i].is_cputime) + break; + } + } + return 0; +} + +#define TIMEOUT 60 + +#include diff --git a/time/tst-gettimeofday-time64.c b/time/tst-gettimeofday-time64.c new file mode 100644 index 0000000000..6c08761ef9 --- /dev/null +++ b/time/tst-gettimeofday-time64.c @@ -0,0 +1 @@ +#include "tst-gettimeofday.c" diff --git a/time/tst-gettimeofday.c b/time/tst-gettimeofday.c new file mode 100644 index 0000000000..978ae28587 --- /dev/null +++ b/time/tst-gettimeofday.c @@ -0,0 +1,93 @@ +/* Test gettimeofday function. + Copyright (C) 2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + +#include +#include + +/* Compare two struct timeval values, returning a value -1, 0 or 1. */ + +int +compare_timeval (const struct timeval *tv1, const struct timeval *tv2) +{ + if (tv1->tv_sec < tv2->tv_sec) + return -1; + if (tv1->tv_sec > tv2->tv_sec) + return 1; + if (tv1->tv_usec < tv2->tv_usec) + return -1; + if (tv1->tv_usec > tv2->tv_usec) + return 1; + return 0; +} + +int +do_test (void) +{ + struct timeval tv1, tv2, tv3; + int ret; + time_t t1; + /* Verify that the calls to gettimeofday succeed, that the time does + not decrease, and that time returns a truncated (not rounded) + version of the time. */ + t1 = time (NULL); + TEST_VERIFY_EXIT (t1 != (time_t) -1); + ret = gettimeofday (&tv1, NULL); + TEST_VERIFY_EXIT (ret == 0); + TEST_VERIFY (t1 <= tv1.tv_sec); + TEST_VERIFY (tv1.tv_usec >= 0); + TEST_VERIFY (tv1.tv_usec < 1000000); + ret = gettimeofday (&tv2, NULL); + TEST_VERIFY_EXIT (ret == 0); + TEST_VERIFY (compare_timeval (&tv1, &tv2) <= 0); + TEST_VERIFY (tv2.tv_usec >= 0); + TEST_VERIFY (tv2.tv_usec < 1000000); + /* Also verify that after sleeping, the time returned has increased. + Repeat several times to verify that each time, the time from the + time function is truncated not rounded. */ + const struct timespec duration = { .tv_nsec = 100000000 }; + for (int i = 0; i < 10; i++) + { + ret = nanosleep (&duration, NULL); + TEST_VERIFY_EXIT (ret == 0); + t1 = time (NULL); + TEST_VERIFY_EXIT (t1 != (time_t) -1); + ret = gettimeofday (&tv3, NULL); + TEST_VERIFY_EXIT (ret == 0); + TEST_VERIFY (compare_timeval (&tv2, &tv3) < 0); + TEST_VERIFY (t1 <= tv3.tv_sec); + TEST_VERIFY (tv3.tv_usec >= 0); + TEST_VERIFY (tv3.tv_usec < 1000000); + tv2 = tv3; + } + /* Also test with the obsolete tz argument not being NULL. */ + struct timezone tz = { 0 }; + t1 = time (NULL); + TEST_VERIFY_EXIT (t1 != (time_t) -1); + ret = gettimeofday (&tv3, &tz); + TEST_VERIFY_EXIT (ret == 0); + TEST_VERIFY (t1 <= tv3.tv_sec); + TEST_VERIFY (compare_timeval (&tv2, &tv3) <= 0); + TEST_VERIFY (tv3.tv_usec >= 0); + TEST_VERIFY (tv3.tv_usec < 1000000); + return 0; +} + +#include diff --git a/time/tst-time-time64.c b/time/tst-time-time64.c new file mode 100644 index 0000000000..30e8d3c86e --- /dev/null +++ b/time/tst-time-time64.c @@ -0,0 +1 @@ +#include "tst-time.c" diff --git a/time/tst-time.c b/time/tst-time.c new file mode 100644 index 0000000000..7f24bed353 --- /dev/null +++ b/time/tst-time.c @@ -0,0 +1,51 @@ +/* Test time function. + Copyright (C) 2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + +#include +#include + +int +do_test (void) +{ + time_t t1, t2, t3, t4, t5, t6; + /* Verify that the calls to time succeed, that the value returned + directly equals that returned through the pointer passed, and + that the time does not decrease. */ + t1 = time (&t2); + TEST_VERIFY_EXIT (t1 != (time_t) -1); + TEST_VERIFY (t1 == t2); + t3 = time (NULL); + TEST_VERIFY_EXIT (t3 != (time_t) -1); + TEST_VERIFY (t3 >= t1); + /* Also verify that after sleeping, the time returned has + increased. */ + sleep (2); + t4 = time (&t5); + TEST_VERIFY_EXIT (t4 != (time_t) -1); + TEST_VERIFY (t4 == t5); + TEST_VERIFY (t4 > t3); + t6 = time (NULL); + TEST_VERIFY_EXIT (t6 != (time_t) -1); + TEST_VERIFY (t6 >= t4); + return 0; +} + +#include