LCOV - code coverage report
Current view: top level - monetdb5/modules/kernel - alarm.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 11 48 22.9 %
Date: 2021-10-13 02:24:04 Functions: 3 6 50.0 %

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

Generated by: LCOV version 1.14