LCOV - code coverage report
Current view: top level - monetdb5/modules/kernel - alarm.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 16 59 27.1 %
Date: 2024-04-25 20:03:45 Functions: 3 6 50.0 %

          Line data    Source code
       1             : /*
       2             :  * SPDX-License-Identifier: MPL-2.0
       3             :  *
       4             :  * This Source Code Form is subject to the terms of the Mozilla Public
       5             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       6             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       7             :  *
       8             :  * Copyright 2024 MonetDB Foundation;
       9             :  * Copyright August 2008 - 2023 MonetDB B.V.;
      10             :  * Copyright 1997 - July 2008 CWI.
      11             :  */
      12             : 
      13             : /*
      14             :  * @f alarm
      15             :  * @a M.L. Kersten, P. Boncz
      16             :  *
      17             :  * @+ Timers and Timed Interrupts
      18             :  * This module handles various signaling/timer functionalities.
      19             :  * The Monet interface supports two timer commands: @emph{ alarm} and @emph{ sleep}.
      20             :  * Their argument is the number of seconds to wait before the timer goes off.
      21             :  * The @emph{ sleep} command blocks till the alarm goes off.
      22             :  * The @emph{ alarm} command continues directly, executes off a
      23             :  * string when it goes off.
      24             :  * The parameterless routines @emph{ time} and @emph{ ctime} provide access to
      25             :  * the cpu clock.They return an integer and string, respectively.
      26             :  */
      27             : #include "monetdb_config.h"
      28             : #include "mal.h"
      29             : #include "mal_client.h"
      30             : #include "mal_interpreter.h"
      31             : #include <time.h>
      32             : #include "mal_exception.h"
      33             : 
      34             : static str
      35          30 : ALARMusec(lng *ret)
      36             : {
      37          30 :         *ret = GDKusec();
      38          30 :         return MAL_SUCCEED;
      39             : }
      40             : 
      41             : #define SLEEP_SINGLE(TPE)                                                                                               \
      42             :         do {                                                                                                                            \
      43             :                 TPE *res = (TPE*) getArgReference(stk, pci, 0), *msecs = (TPE*) getArgReference(stk,pci,1); \
      44             :                 if (is_##TPE##_nil(*msecs))                                                                             \
      45             :                         throw(MAL, "alarm.sleep", "NULL values not allowed for sleeping time"); \
      46             :                 if (*msecs < 0)                                                                                                      \
      47             :                         throw(MAL, "alarm.sleep", "Cannot sleep for a negative time"); \
      48             :                 MT_sleep_ms((unsigned int) *msecs);                                                             \
      49             :                 *res = *msecs;                                                                                                  \
      50             :         } while (0)
      51             : 
      52             : #define SLEEP_MULTI(TPE)                                                                                                \
      53             :         do {                                                                                                                            \
      54             :                 for (i = 0; i < j ; i++) {                                                                           \
      55             :                         if (is_##TPE##_nil(bb[i])) {                                                            \
      56             :                                 bat_iterator_end(&bi);                                                                      \
      57             :                                 BBPreclaim(r);                                                                                  \
      58             :                                 BBPunfix(b->batCacheid);                                                             \
      59             :                                 throw(MAL, "alarm.sleep", "NULL values not allowed for sleeping time"); \
      60             :                         }                                                                                                                       \
      61             :                         if (bb[i] < 0) {                                                                                     \
      62             :                                 bat_iterator_end(&bi);                                                                      \
      63             :                                 BBPreclaim(r);                                                                                  \
      64             :                                 BBPunfix(b->batCacheid);                                                             \
      65             :                                 throw(MAL, "alarm.sleep", "Cannot sleep for a negative time"); \
      66             :                         }                                                                                                                       \
      67             :                 }                                                                                                                               \
      68             :                 for (i = 0; i < j ; i++) {                                                                           \
      69             :                         MT_sleep_ms((unsigned int) bb[i]);                                                      \
      70             :                         rb[i] = bb[i];                                                                                          \
      71             :                 }                                                                                                                               \
      72             :         } while (0)
      73             : 
      74             : static str
      75          10 : ALARMsleep(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
      76             : {
      77          10 :         BAT *r = NULL, *b = NULL;
      78          10 :         int *restrict rb, *restrict bb, tpe;
      79          10 :         BUN i, j;
      80             : 
      81          10 :         (void) cntxt;
      82          10 :         if (getArgType(mb, pci, 0) != TYPE_void
      83          10 :                 && isaBatType(getArgType(mb, pci, 1))) {
      84           0 :                 bat *res = getArgReference_bat(stk, pci, 0);
      85           0 :                 bat *bid = getArgReference_bat(stk, pci, 1);
      86           0 :                 tpe = getArgType(mb, pci, 1);
      87             : 
      88           0 :                 if (!(b = BATdescriptor(*bid)))
      89           0 :                         throw(MAL, "alarm.sleep",
      90             :                                   SQLSTATE(HY005) "Cannot access column descriptor");
      91             : 
      92           0 :                 BATiter bi = bat_iterator(b);
      93           0 :                 j = bi.count;
      94           0 :                 bb = bi.base;
      95             : 
      96           0 :                 if (!(r = COLnew(0, tpe, j, TRANSIENT))) {
      97           0 :                         bat_iterator_end(&bi);
      98           0 :                         BBPunfix(b->batCacheid);
      99           0 :                         throw(MAL, "alarm.sleep", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     100             :                 }
     101           0 :                 rb = Tloc(r, 0);
     102             : 
     103           0 :                 switch (tpe) {
     104             :                 case TYPE_bte:
     105             :                         SLEEP_MULTI(bte);
     106             :                         break;
     107             :                 case TYPE_sht:
     108             :                         SLEEP_MULTI(sht);
     109             :                         break;
     110             :                 case TYPE_int:
     111             :                         SLEEP_MULTI(int);
     112             :                         break;
     113             :                 default:{
     114           0 :                         bat_iterator_end(&bi);
     115           0 :                         BBPreclaim(r);
     116           0 :                         BBPunfix(b->batCacheid);
     117           0 :                         throw(MAL, "alarm.sleep",
     118             :                                   SQLSTATE(42000) "Sleep function not available for type %s",
     119             :                                   ATOMname(tpe));
     120             :                 }
     121             :                 }
     122             :                 bat_iterator_end(&bi);
     123             : 
     124             :                 BBPunfix(b->batCacheid);
     125             :                 *res = r->batCacheid;
     126             :                 BBPkeepref(r);
     127             :         } else {
     128          10 :                 switch (getArgType(mb, pci, 1)) {
     129           0 :                 case TYPE_bte:
     130           0 :                         SLEEP_SINGLE(bte);
     131           0 :                         break;
     132           0 :                 case TYPE_sht:
     133           0 :                         SLEEP_SINGLE(sht);
     134           0 :                         break;
     135          10 :                 case TYPE_int:
     136          10 :                         SLEEP_SINGLE(int);
     137          10 :                         break;
     138           0 :                 default:
     139           0 :                         throw(MAL, "alarm.sleep",
     140             :                                   SQLSTATE(42000) "Sleep function not available for type %s",
     141             :                                   ATOMname(getArgType(mb, pci, 1)));
     142             :                 }
     143             :         }
     144             :         return MAL_SUCCEED;
     145             : }
     146             : 
     147             : static str
     148           0 : ALARMctime(str *res)
     149             : {
     150           0 :         time_t t = time(0);
     151           0 :         char *base;
     152           0 :         char buf[26];
     153             : 
     154             : #ifdef HAVE_CTIME_R3
     155             :         base = ctime_r(&t, buf, sizeof(buf));
     156             : #else
     157           0 :         base = ctime_r(&t, buf);
     158             : #endif
     159           0 :         if (base == NULL)
     160             :                 /* very unlikely to happen... */
     161           0 :                 throw(MAL, "alarm.ctime", "failed to format time");
     162             : 
     163           0 :         base[24] = 0;                           /* squash final newline */
     164           0 :         *res = GDKstrdup(base);
     165           0 :         if (*res == NULL)
     166           0 :                 throw(MAL, "alarm.ctime", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     167             :         return MAL_SUCCEED;
     168             : }
     169             : 
     170             : static str
     171           0 : ALARMepoch(int *res)
     172             : {                                                               /* XXX should be lng */
     173           0 :         *res = (int) time(0);
     174           0 :         return MAL_SUCCEED;
     175             : }
     176             : 
     177             : static str
     178           0 : ALARMtime(int *res)
     179             : {
     180           0 :         *res = GDKms();
     181           0 :         return MAL_SUCCEED;
     182             : }
     183             : 
     184             : #include "mel.h"
     185             : mel_func alarm_init_funcs[] = {
     186             :  pattern("alarm", "sleep", ALARMsleep, true, "Sleep a few milliseconds", args(1,2, arg("",void),argany("msecs",1))),
     187             :  pattern("alarm", "sleep", ALARMsleep, true, "Sleep a few milliseconds and return the slept value", args(1,2, argany("",1),argany("msecs",1))),
     188             :  pattern("alarm", "sleep", ALARMsleep, true, "Sleep a few milliseconds and return the slept value", args(1,2, batargany("",1),batargany("msecs",1))),
     189             :  command("alarm", "usec", ALARMusec, true, "Return time since Jan 1, 1970 in microseconds.", args(1,1, arg("",lng))),
     190             :  command("alarm", "time", ALARMtime, true, "Return time since program start in milliseconds.", args(1,1, arg("",int))),
     191             :  command("alarm", "epoch", ALARMepoch, true, "Return time since Jan 1, 1970 in seconds.", args(1,1, arg("",int))),
     192             :  command("alarm", "ctime", ALARMctime, true, "Return the current time as a C-time string.", args(1,1, arg("",str))),
     193             :  { .imp=NULL }
     194             : };
     195             : #include "mal_import.h"
     196             : #ifdef _MSC_VER
     197             : #undef read
     198             : #pragma section(".CRT$XCU",read)
     199             : #endif
     200         329 : LIB_STARTUP_FUNC(init_alarm_mal)
     201         329 : { mal_module("alarm", NULL, alarm_init_funcs); }

Generated by: LCOV version 1.14