LCOV - code coverage report
Current view: top level - monetdb5/modules/kernel - status.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 2 323 0.6 %
Date: 2021-10-13 02:24:04 Functions: 1 14 7.1 %

          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             :  * author M.L. Kersten, P. Boncz, N.Nes
      11             :  * System state information
      12             :  * This document introduces a series of bats  and operations that provide access
      13             :  * to information stored within the Monet Version 5 internal data structures.
      14             :  * In all cases, pseudo BAT operation returns a transient BAT that
      15             :  * should be garbage collected after being used.
      16             :  *
      17             :  * The main performance drain would be to use a pseudo BAT directly to
      18             :  * successively access it components. This can be avoided by first assigning
      19             :  * the pseudo BAT to a variable.
      20             :  */
      21             : 
      22             : #include "monetdb_config.h"
      23             : #include "gdk.h"
      24             : #include <time.h>
      25             : #include "mal_exception.h"
      26             : #ifdef HAVE_UNISTD_H
      27             : # include <unistd.h>
      28             : #endif
      29             : 
      30             : #ifdef HAVE_SYS_TIMES_H
      31             : # include <sys/times.h>
      32             : #endif
      33             : 
      34             : #ifdef HAVE_SYS_RESOURCE_H
      35             : # include <sys/resource.h>
      36             : #endif
      37             : 
      38             : static int
      39             : pseudo(bat *ret, bat *ret2, BAT *bn, BAT *b) {
      40           0 :         *ret = bn->batCacheid;
      41           0 :         BBPkeepref(*ret);
      42           0 :         *ret2 = b->batCacheid;
      43           0 :         BBPkeepref(*ret2);
      44             :         return 0;
      45             : }
      46             : 
      47             : static str
      48           0 : SYSgetmem_cursize(lng *num)
      49             : {
      50           0 :         *num = GDKmem_cursize();
      51           0 :         return MAL_SUCCEED;
      52             : }
      53             : 
      54             : static str
      55           0 : SYSgetmem_maxsize(lng *num)
      56             : {
      57           0 :         *num = GDK_mem_maxsize;
      58           0 :         return MAL_SUCCEED;
      59             : }
      60             : 
      61             : static str
      62           0 : SYSsetmem_maxsize(void *ret, const lng *num)
      63             : {
      64             :         size_t sze = 0;
      65             :         (void) ret;
      66           0 :         if (*num < 0)
      67           0 :                 throw(ILLARG, "status.mem_maxsize", "new size must not be < 0");
      68             : #if SIZEOF_SIZE_T == SIZEOF_INT
      69             :         {
      70             :                 lng size_t_max = 2 * (lng)INT_MAX;
      71             :                 if (*num > size_t_max)
      72             :                         throw(ILLARG, "status.mem_maxsize", "new size must not be > " LLFMT, size_t_max);
      73             :         }
      74             : #endif
      75           0 :         GDK_mem_maxsize = sze;
      76           0 :         return MAL_SUCCEED;
      77             : }
      78             : 
      79             : static str
      80           0 : SYSgetvm_cursize(lng *num)
      81             : {
      82           0 :         *num = GDKvm_cursize();
      83           0 :         return MAL_SUCCEED;
      84             : }
      85             : 
      86             : static str
      87           0 : SYSgetvm_maxsize(lng *num)
      88             : {
      89           0 :         *num = GDK_vm_maxsize;
      90           0 :         return MAL_SUCCEED;
      91             : }
      92             : 
      93             : static str
      94           0 : SYSsetvm_maxsize(void *ret, const lng *num)
      95             : {
      96             :         (void) ret;
      97           0 :         GDK_vm_maxsize = (size_t) *num;
      98           0 :         return MAL_SUCCEED;
      99             : }
     100             : 
     101             : /*
     102             :  * Performance
     103             :  * To obtain a good impression of the Monet performance we need timing information.
     104             :  * The most detailed information is best obtained with the system profiler.
     105             :  *
     106             :  * However, the direct approach is to enable the user to read the timers maintained
     107             :  * internally. This is done with the CPU, IO, MEMORY, and BBP command which
     108             :  * displays the elapsed time in seconds, user- and system-cpu time in milliseconds
     109             :  * since its last invocation and the amount of space in use.  The process
     110             :  * identifier is used to differentiate among the possible processes.
     111             :  *
     112             :  * Note that in multi threaded mode the routine prints the elapsed
     113             :  * time since the beginning of each process.
     114             :  */
     115             : #ifdef HAVE_TIMES
     116             : static time_t clk = 0;
     117             : static struct tms state;
     118             : #endif
     119             : 
     120             : static str
     121           0 : SYScpuStatistics(bat *ret, bat *ret2)
     122             : {
     123             :         lng i;
     124             :         BAT *b, *bn;
     125             : #ifdef HAVE_TIMES
     126             :         struct tms newst;
     127             : # ifndef HZ
     128             :         static int HZ = 0;
     129             : 
     130             :         if (HZ == 0) {
     131             : #  if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
     132             :                 HZ = sysconf(_SC_CLK_TCK);
     133             : #  else
     134             :                 HZ = CLK_TCK;
     135             : #  endif
     136             :         }
     137             : # endif
     138             : #endif
     139             : 
     140           0 :         bn = COLnew(0, TYPE_str, 32, TRANSIENT);
     141           0 :         b = COLnew(0, TYPE_lng, 32, TRANSIENT);
     142           0 :         if (b == 0 || bn == 0){
     143           0 :                 if ( b) BBPunfix(b->batCacheid);
     144           0 :                 if ( bn) BBPunfix(bn->batCacheid);
     145           0 :                 throw(MAL, "status.cpuStatistics", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     146             :         }
     147             : #ifdef HAVE_TIMES
     148           0 :         if (clk == 0) {
     149           0 :                 clk = time(0);
     150           0 :                 times(&state);
     151             :         }
     152           0 :         times(&newst);
     153             :         /* store counters, ignore errors */
     154           0 :         i = (lng) (time(0) - clk);
     155           0 :         if (BUNappend(bn, "elapsed", false) != GDK_SUCCEED ||
     156           0 :                 BUNappend(b, &i, false) != GDK_SUCCEED)
     157           0 :                 goto bailout;
     158           0 :         i = newst.tms_utime * 1000 / HZ;
     159           0 :         if (BUNappend(bn, "user", false) != GDK_SUCCEED ||
     160           0 :                 BUNappend(b, &i, false) != GDK_SUCCEED)
     161           0 :                 goto bailout;
     162           0 :         i = (newst.tms_utime - state.tms_utime) * 1000 / HZ;
     163           0 :         if (BUNappend(bn, "elapuser", false) != GDK_SUCCEED ||
     164           0 :                 BUNappend(b, &i, false) != GDK_SUCCEED)
     165           0 :                 goto bailout;
     166           0 :         i = newst.tms_stime * 1000 / HZ;
     167           0 :         if (BUNappend(bn, "system", false) != GDK_SUCCEED ||
     168           0 :                 BUNappend(b, &i, false) != GDK_SUCCEED)
     169           0 :                 goto bailout;
     170           0 :         i = (newst.tms_stime - state.tms_stime) * 1000 / HZ;
     171           0 :         if (BUNappend(bn, "elapsystem", false) != GDK_SUCCEED ||
     172           0 :                 BUNappend(b, &i, false) != GDK_SUCCEED)
     173           0 :                 goto bailout;
     174             : 
     175           0 :         state = newst;
     176             : #else
     177             :         i = lng_nil;
     178             :         if (BUNappend(bn, "elapsed", false) != GDK_SUCCEED ||
     179             :                 BUNappend(b, &i, false) != GDK_SUCCEED ||
     180             :                 BUNappend(bn, "user", false) != GDK_SUCCEED ||
     181             :                 BUNappend(b, &i, false) != GDK_SUCCEED ||
     182             :                 BUNappend(bn, "elapuser", false) != GDK_SUCCEED ||
     183             :                 BUNappend(b, &i, false) != GDK_SUCCEED ||
     184             :                 BUNappend(bn, "system", false) != GDK_SUCCEED ||
     185             :                 BUNappend(b, &i, false) != GDK_SUCCEED ||
     186             :                 BUNappend(bn, "elapsystem", false) != GDK_SUCCEED ||
     187             :                 BUNappend(b, &i, false) != GDK_SUCCEED)
     188             :                 goto bailout;
     189             : #endif
     190             :         if (pseudo(ret,ret2,bn,b))
     191             :                 goto bailout;
     192           0 :         return MAL_SUCCEED;
     193           0 :   bailout:
     194           0 :         BBPunfix(b->batCacheid);
     195           0 :         BBPunfix(bn->batCacheid);
     196           0 :         throw(MAL, "status.cpuStatistics", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     197             : }
     198             : 
     199             : static size_t memincr;
     200             : static str
     201           0 : SYSmemStatistics(bat *ret, bat *ret2)
     202             : {
     203             :         BAT *b, *bn;
     204             :         lng i;
     205             : 
     206           0 :         bn = COLnew(0,TYPE_str, 32, TRANSIENT);
     207           0 :         b = COLnew(0, TYPE_lng, 32, TRANSIENT);
     208           0 :         if (b == 0 || bn == 0) {
     209           0 :                 if ( b) BBPunfix(b->batCacheid);
     210           0 :                 if ( bn) BBPunfix(bn->batCacheid);
     211           0 :                 throw(MAL, "status.memStatistics", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     212             :         }
     213             : 
     214             :         /* store counters, ignore errors */
     215           0 :         i = (lng) (GDKmem_cursize() - memincr);
     216           0 :         memincr = GDKmem_cursize();
     217           0 :         if (BUNappend(bn, "memincr", false) != GDK_SUCCEED ||
     218           0 :                 BUNappend(b, &i, false) != GDK_SUCCEED)
     219           0 :                 goto bailout;
     220             :         if (pseudo(ret,ret2,bn,b))
     221             :                 goto bailout;
     222           0 :         return MAL_SUCCEED;
     223             :   bailout:
     224           0 :         BBPunfix(b->batCacheid);
     225           0 :         BBPunfix(bn->batCacheid);
     226           0 :         throw(MAL, "status.memStatistics", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     227             : }
     228             : 
     229             : #define heap(X1,X2,X3,X4,UNLOCK)                                                        \
     230             :         if (X1) {                                                                                               \
     231             :                 sz = HEAPmemsize(X2);                                                           \
     232             :                 if (sz > *minsize) {                                                         \
     233             :                         sprintf(buf, X4"/%s", s);                                             \
     234             :                         if (BUNappend(bn, buf, false) != GDK_SUCCEED || \
     235             :                                 BUNappend(b, &sz, false) != GDK_SUCCEED) {  \
     236             :                                 UNLOCK;                                                                         \
     237             :                                 goto bailout;                                                           \
     238             :                         }                                                                                               \
     239             :                 }                                                                                                       \
     240             :                 X3 += sz; tot += sz;                                                            \
     241             :         }
     242             : #define heapvm(X1,X2,X3,X4,UNLOCK)                                                      \
     243             :         if (X1) {                                                                                               \
     244             :                 sz = HEAPvmsize(X2);                                                            \
     245             :                 if (sz > *minsize) {                                                         \
     246             :                         sprintf(buf, X4"/%s", s);                                             \
     247             :                         if (BUNappend(bn, buf, false) != GDK_SUCCEED || \
     248             :                                 BUNappend(b, &sz, false) != GDK_SUCCEED) {  \
     249             :                                 UNLOCK;                                                                         \
     250             :                                 goto bailout;                                                           \
     251             :                         }                                                                                               \
     252             :                 }                                                                                                       \
     253             :                 X3 += sz; tot += sz;                                                            \
     254             :         }
     255             : 
     256             : static str
     257           0 : SYSmem_usage(bat *ret, bat *ret2, const lng *minsize)
     258             : {
     259           0 :         lng hbuns = 0, tbuns = 0, hhsh = 0, thsh = 0, hind = 0, tind = 0, head = 0, tail = 0, tot = 0, n = 0, sz;
     260           0 :         BAT *bn = COLnew(0, TYPE_str, 2 * getBBPsize(), TRANSIENT);
     261           0 :         BAT *b = COLnew(0, TYPE_lng, 2 * getBBPsize(), TRANSIENT);
     262             :         char buf[1024];
     263             :         bat i;
     264             : 
     265           0 :         if (b == 0 || bn == 0) {
     266           0 :                 if ( b) BBPunfix(b->batCacheid);
     267           0 :                 if ( bn) BBPunfix(bn->batCacheid);
     268           0 :                 throw(MAL, "status.memUsage", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     269             :         }
     270           0 :         BBPlock();
     271           0 :         for (i = 1; i < getBBPsize(); i++) {
     272           0 :                 BAT *c = BBPquickdesc(i);
     273             :                 str s;
     274             : 
     275           0 :                 if( c == NULL  || !BBPvalid(i))
     276           0 :                         continue;
     277             : 
     278             :                 s = BBP_logical(i);
     279           0 :                 sz = 0;
     280           0 :                 if (BBP_desc(i))
     281           0 :                         sz += sizeof(BAT);
     282             :                 if (BBP_logical(i))
     283           0 :                         n += strLen(BBP_logical(i));
     284           0 :                 if (BBP_physical(i))
     285           0 :                         n += strLen(BBP_physical(i));
     286             : 
     287           0 :                 if (sz > *minsize) {
     288           0 :                         sprintf(buf, "desc/%s", s);
     289           0 :                         if (BUNappend(bn, buf, false) != GDK_SUCCEED ||
     290           0 :                                 BUNappend(b, &sz, false) != GDK_SUCCEED)
     291           0 :                                 goto bailout;
     292             :                 }
     293           0 :                 tot += (lng) sz;
     294             : 
     295             :                 if (c)
     296           0 :                         MT_lock_set(&c->theaplock);
     297           0 :                 if (c == NULL || isVIEW(c)) {
     298             :                         if (c)
     299           0 :                                 MT_lock_unset(&c->theaplock);
     300           0 :                         continue;
     301             :                 }
     302             : 
     303           0 :                 heap(1,c->theap,tbuns,"tbuns", MT_lock_unset(&c->theaplock));
     304           0 :                 heap(c->tvheap,c->tvheap,tail,"tail", MT_lock_unset(&c->theaplock));
     305           0 :                 MT_lock_unset(&c->theaplock);
     306           0 :                 MT_rwlock_rdlock(&c->thashlock);
     307           0 :                 heap(c->thash && c->thash != (Hash *) 1,&c->thash->heaplink,thsh,"thshl",MT_rwlock_rdunlock(&c->thashlock));
     308           0 :                 heap(c->thash && c->thash != (Hash *) 1,&c->thash->heapbckt,thsh,"thshb",MT_rwlock_rdunlock(&c->thashlock));
     309           0 :                 MT_rwlock_rdunlock(&c->thashlock);
     310             :         }
     311             :         /* totals per category */
     312           0 :         if (BUNappend(bn, "_tot/hbuns", false) != GDK_SUCCEED ||
     313           0 :                 BUNappend(b, &hbuns, false) != GDK_SUCCEED ||
     314           0 :                 BUNappend(bn, "_tot/tbuns", false) != GDK_SUCCEED ||
     315           0 :                 BUNappend(b, &tbuns, false) != GDK_SUCCEED ||
     316           0 :                 BUNappend(bn, "_tot/head", false) != GDK_SUCCEED ||
     317           0 :                 BUNappend(b, &head, false) != GDK_SUCCEED ||
     318           0 :                 BUNappend(bn, "_tot/tail", false) != GDK_SUCCEED ||
     319           0 :                 BUNappend(b, &tail, false) != GDK_SUCCEED ||
     320           0 :                 BUNappend(bn, "_tot/hhsh", false) != GDK_SUCCEED ||
     321           0 :                 BUNappend(b, &hhsh, false) != GDK_SUCCEED ||
     322           0 :                 BUNappend(bn, "_tot/thsh", false) != GDK_SUCCEED ||
     323           0 :                 BUNappend(b, &thsh, false) != GDK_SUCCEED ||
     324           0 :                 BUNappend(bn, "_tot/hind", false) != GDK_SUCCEED ||
     325           0 :                 BUNappend(b, &hind, false) != GDK_SUCCEED ||
     326           0 :                 BUNappend(bn, "_tot/tind", false) != GDK_SUCCEED ||
     327           0 :                 BUNappend(b, &tind, false) != GDK_SUCCEED)
     328           0 :                 goto bailout;
     329             : 
     330             :         /* special area 1: BBP rec */
     331           0 :         sz = BBPlimit * sizeof(BBPrec) + n;
     332           0 :         if (BUNappend(bn, "_tot/bbp", false) != GDK_SUCCEED ||
     333           0 :                 BUNappend(b, &sz, false) != GDK_SUCCEED)
     334           0 :                 goto bailout;
     335           0 :         tot += sz;
     336             : 
     337             :         /* this concludes all major traceable Monet memory usages */
     338           0 :         tot += sz;
     339           0 :         if (BUNappend(bn, "_tot/found", false) != GDK_SUCCEED ||
     340           0 :                 BUNappend(b, &tot, false) != GDK_SUCCEED)
     341           0 :                 goto bailout;
     342             : 
     343             :         /* now look at what the global statistics report (to see if it coincides) */
     344             : 
     345             :         /* measure actual heap size, includes wasted fragmented space and anon mmap space used by malloc() */
     346           0 :         sz = GDKmem_cursize();
     347           0 :         if (BUNappend(bn, "_tot/heap", false) != GDK_SUCCEED ||
     348           0 :                 BUNappend(b, &sz, false) != GDK_SUCCEED)
     349           0 :                 goto bailout;
     350             : 
     351           0 :         tot = GDKmem_cursize();
     352             : 
     353             :         /* allocated swap area memory that is not plain malloc() */
     354           0 :         sz = MAX(0, sz - tot);
     355           0 :         if (BUNappend(bn, "_tot/valloc", false) != GDK_SUCCEED ||
     356           0 :                 BUNappend(b, &sz, false) != GDK_SUCCEED)
     357           0 :                 goto bailout;
     358             : 
     359             :         /* swap-area memory is in either GDKvmalloc or heap */
     360           0 :         if (BUNappend(bn, "_tot/swapmem", false) != GDK_SUCCEED ||
     361           0 :                 BUNappend(b, &tot, false) != GDK_SUCCEED)
     362           0 :                 goto bailout;
     363             : 
     364           0 :         BBPunlock();
     365           0 :         *ret = bn->batCacheid;
     366           0 :         BBPkeepref(bn->batCacheid);
     367           0 :         *ret2 = b->batCacheid;
     368           0 :         BBPkeepref(b->batCacheid);
     369             : 
     370           0 :         return MAL_SUCCEED;
     371             : 
     372           0 :   bailout:
     373           0 :         BBPunlock();
     374           0 :         BBPunfix(b->batCacheid);
     375           0 :         BBPunfix(bn->batCacheid);
     376           0 :         throw(MAL, "status.memUsage", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     377             : }
     378             : 
     379             : static str
     380           0 : SYSvm_usage(bat *ret, bat *ret2, const lng *minsize)
     381             : {
     382           0 :         lng hbuns = 0, tbuns = 0, hhsh = 0, thsh = 0, hind = 0, tind = 0, head = 0, tail = 0, tot = 0, sz;
     383           0 :         BAT *bn = COLnew(0, TYPE_str, 2 * getBBPsize(), TRANSIENT);
     384           0 :         BAT *b = COLnew(0, TYPE_lng, 2 * getBBPsize(), TRANSIENT);
     385             :         char buf[1024];
     386             :         bat i;
     387             : 
     388           0 :         if (b == 0 || bn == 0) {
     389           0 :                 if ( b) BBPunfix(b->batCacheid);
     390           0 :                 if ( bn) BBPunfix(bn->batCacheid);
     391           0 :                 throw(MAL, "status.vmStatistics", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     392             :         }
     393           0 :         BBPlock();
     394           0 :         for (i = 1; i < getBBPsize(); i++) {
     395             :                 BAT *c;
     396             :                 str s;
     397             : 
     398           0 :                 if (!BBPvalid(i))
     399           0 :                         continue;
     400             : 
     401             :                 s = BBP_logical(i);
     402           0 :                 c = BBP_cache(i);
     403             : 
     404           0 :                 if (c)
     405           0 :                         MT_lock_set(&c->theaplock);
     406           0 :                 if (c == NULL || isVIEW(c)) {
     407           0 :                         if (c)
     408           0 :                                 MT_lock_unset(&c->theaplock);
     409           0 :                         continue;
     410             :                 }
     411             : 
     412           0 :                 heapvm(1,c->theap,tbuns,"tcuns",MT_lock_unset(&c->theaplock));
     413           0 :                 heapvm(c->tvheap,c->tvheap,tail,"tail",MT_lock_unset(&c->theaplock));
     414           0 :                 MT_lock_unset(&c->theaplock);
     415           0 :                 MT_rwlock_rdlock(&c->thashlock);
     416           0 :                 heapvm(c->thash && c->thash != (Hash *) 1,&c->thash->heaplink,thsh,"thshl",MT_rwlock_rdunlock(&c->thashlock));
     417           0 :                 heapvm(c->thash && c->thash != (Hash *) 1,&c->thash->heapbckt,thsh,"thshb",MT_rwlock_rdunlock(&c->thashlock));
     418           0 :                 MT_rwlock_rdunlock(&c->thashlock);
     419             :         }
     420             :         /* totals per category */
     421           0 :         if (BUNappend(bn, "_tot/hbuns", false) != GDK_SUCCEED ||
     422           0 :                 BUNappend(b, &hbuns, false) != GDK_SUCCEED ||
     423           0 :                 BUNappend(bn, "_tot/tbuns", false) != GDK_SUCCEED ||
     424           0 :                 BUNappend(b, &tbuns, false) != GDK_SUCCEED ||
     425           0 :                 BUNappend(bn, "_tot/head", false) != GDK_SUCCEED ||
     426           0 :                 BUNappend(b, &head, false) != GDK_SUCCEED ||
     427           0 :                 BUNappend(bn, "_tot/tail", false) != GDK_SUCCEED ||
     428           0 :                 BUNappend(b, &tail, false) != GDK_SUCCEED ||
     429           0 :                 BUNappend(bn, "_tot/hhsh", false) != GDK_SUCCEED ||
     430           0 :                 BUNappend(b, &hhsh, false) != GDK_SUCCEED ||
     431           0 :                 BUNappend(bn, "_tot/thsh", false) != GDK_SUCCEED ||
     432           0 :                 BUNappend(b, &thsh, false) != GDK_SUCCEED ||
     433           0 :                 BUNappend(bn, "_tot/hind", false) != GDK_SUCCEED ||
     434           0 :                 BUNappend(b, &hind, false) != GDK_SUCCEED ||
     435           0 :                 BUNappend(bn, "_tot/tind", false) != GDK_SUCCEED ||
     436           0 :                 BUNappend(b, &tind, false) != GDK_SUCCEED)
     437           0 :                 goto bailout;
     438             : 
     439             :         /* special area 1: BBP rec */
     440           0 :         sz = BBPlimit * sizeof(BBPrec);
     441           0 :         if (BUNappend(bn, "_tot/bbp", false) != GDK_SUCCEED ||
     442           0 :                 BUNappend(b, &sz, false) != GDK_SUCCEED)
     443           0 :                 goto bailout;
     444           0 :         tot += sz;
     445             : 
     446             : 
     447             :         /* this concludes all major traceable Monet virtual memory usages */
     448           0 :         tot += sz;
     449           0 :         if (BUNappend(bn, "_tot/found", false) != GDK_SUCCEED ||
     450           0 :                 BUNappend(b, &tot, false) != GDK_SUCCEED)
     451           0 :                 goto bailout;
     452             : 
     453             :         /* all VM is either GDKmmap or GDKvmalloc (possibly redirected GDKmalloc), *plus* the heap */
     454           0 :         sz = GDKvm_cursize();
     455           0 :         if (BUNappend(bn, "_tot/vm", false) != GDK_SUCCEED ||
     456           0 :                 BUNappend(b, &sz, false) != GDK_SUCCEED)
     457           0 :                 goto bailout;
     458             : 
     459           0 :         BBPunlock();
     460           0 :         *ret = bn->batCacheid;
     461           0 :         BBPkeepref(bn->batCacheid);
     462           0 :         *ret2 = b->batCacheid;
     463           0 :         BBPkeepref(b->batCacheid);
     464           0 :         return MAL_SUCCEED;
     465             : 
     466           0 :   bailout:
     467           0 :         BBPunlock();
     468           0 :         BBPunfix(b->batCacheid);
     469           0 :         BBPunfix(bn->batCacheid);
     470           0 :         throw(MAL, "status.vmStatistics", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     471             : }
     472             : 
     473             : /*
     474             :  * Additional information on the process utilization is given by
     475             :  * the ioStatistics command. The following information is obtained.
     476             :  *
     477             :  * @T
     478             :  * \begin{tabular}{| l| l|}\hline
     479             :  * maxrss     &the maximum resident set size utilized (in kilobytes).\\
     480             :  * minflt     &the number of page faults serviced without any I/O\\
     481             :  *       &activity; here I/O activity is avoided by "reclaiming" a\\
     482             :  *
     483             :  *       &activity; here I/O activity is avoided by "reclaiming" a\\
     484             :  *       &page frame from the list of pages awaiting reallocation.\\
     485             :  * majflt     &the number of page faults serviced that required I/O\\
     486             :  *       &activity.\\
     487             :  * nswap      &the number of times a process was "swapped" out of main\\
     488             :  *       &memory\\
     489             :  * inblock    &the number of times the file system had to perform input.\\
     490             :  * oublock    &the number of times the file system had to perform output.\\
     491             :  * nvcsw      &the number of times a context switch resulted due to a\\
     492             :  *       &process voluntarily giving up the processor before its\\
     493             :  *       &time slice was completed (usually to await availability of\\
     494             :  *       &a resource).\\
     495             :  * nivcsw     &the number of times a context switch resulted due to a\\
     496             :  *       &higher priority process becoming runnable or because the\\
     497             :  *       &current process exceeded its time slice.\\
     498             :  * \end{tabular}
     499             :  *
     500             :  * The resource statistics are collected in a BAT. It can then
     501             :  * be queried. A default listing is produced by the command usagecmd.
     502             :  * (which should be moved to Monet)
     503             :  *
     504             :  * The BAT grows. It should be compacted.
     505             :  */
     506             : static str
     507           0 : SYSioStatistics(bat *ret, bat *ret2)
     508             : {
     509             : #ifdef HAVE_SYS_RESOURCE_H
     510             :         struct rusage ru;
     511             : #endif
     512             :         lng i;
     513             :         BAT *b, *bn;
     514             : 
     515             : #ifdef HAVE_SYS_RESOURCE_H
     516           0 :         getrusage(RUSAGE_SELF, &ru);
     517             : #endif
     518           0 :         bn = COLnew(0, TYPE_str, 32, TRANSIENT);
     519           0 :         b = COLnew(0, TYPE_lng, 32, TRANSIENT);
     520           0 :         if (b == 0 || bn == 0) {
     521           0 :                 if ( b) BBPunfix(b->batCacheid);
     522           0 :                 if ( bn) BBPunfix(bn->batCacheid);
     523           0 :                 throw(MAL, "status.ioStatistics", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     524             :         }
     525             : 
     526             : #ifdef HAVE_SYS_RESOURCE_H
     527             :         /* store counters, ignore errors */
     528           0 :         i = ru.ru_maxrss;
     529           0 :         if (BUNappend(bn, "maxrss", false) != GDK_SUCCEED ||
     530           0 :                 BUNappend(b, &i, false) != GDK_SUCCEED)
     531           0 :                 goto bailout;
     532           0 :         i = ru.ru_minflt;
     533           0 :         if (BUNappend(bn, "minflt", false) != GDK_SUCCEED ||
     534           0 :                 BUNappend(b, &i, false) != GDK_SUCCEED)
     535           0 :                 goto bailout;
     536           0 :         i = ru.ru_majflt;
     537           0 :         if (BUNappend(bn, "majflt", false) != GDK_SUCCEED ||
     538           0 :                 BUNappend(b, &i, false) != GDK_SUCCEED)
     539           0 :                 goto bailout;
     540           0 :         i = ru.ru_nswap;
     541           0 :         if (BUNappend(bn, "nswap", false) != GDK_SUCCEED ||
     542           0 :                 BUNappend(b, &i, false) != GDK_SUCCEED)
     543           0 :                 goto bailout;
     544           0 :         i = ru.ru_inblock;
     545           0 :         if (BUNappend(bn, "inblock", false) != GDK_SUCCEED ||
     546           0 :                 BUNappend(b, &i, false) != GDK_SUCCEED)
     547           0 :                 goto bailout;
     548           0 :         i = ru.ru_oublock;
     549           0 :         if (BUNappend(bn, "oublock", false) != GDK_SUCCEED ||
     550           0 :                 BUNappend(b, &i, false) != GDK_SUCCEED)
     551           0 :                 goto bailout;
     552           0 :         i = ru.ru_nvcsw;
     553           0 :         if (BUNappend(bn, "nvcsw", false) != GDK_SUCCEED ||
     554           0 :                 BUNappend(b, &i, false) != GDK_SUCCEED)
     555           0 :                 goto bailout;
     556           0 :         i = ru.ru_nivcsw;
     557           0 :         if (BUNappend(bn, "ninvcsw", false) != GDK_SUCCEED ||
     558           0 :                 BUNappend(b, &i, false) != GDK_SUCCEED)
     559           0 :                 goto bailout;
     560             : #else
     561             :         i = lng_nil;
     562             :         if (BUNappend(bn, "maxrss", false) != GDK_SUCCEED ||
     563             :                 BUNappend(b, &i, false) != GDK_SUCCEED ||
     564             :                 BUNappend(bn, "minflt", false) != GDK_SUCCEED ||
     565             :                 BUNappend(b, &i, false) != GDK_SUCCEED ||
     566             :                 BUNappend(bn, "majflt", false) != GDK_SUCCEED ||
     567             :                 BUNappend(b, &i, false) != GDK_SUCCEED ||
     568             :                 BUNappend(bn, "nswap", false) != GDK_SUCCEED ||
     569             :                 BUNappend(b, &i, false) != GDK_SUCCEED ||
     570             :                 BUNappend(bn, "inblock", false) != GDK_SUCCEED ||
     571             :                 BUNappend(b, &i, false) != GDK_SUCCEED ||
     572             :                 BUNappend(bn, "oublock", false) != GDK_SUCCEED ||
     573             :                 BUNappend(b, &i, false) != GDK_SUCCEED ||
     574             :                 BUNappend(bn, "nvcsw", false) != GDK_SUCCEED ||
     575             :                 BUNappend(b, &i, false) != GDK_SUCCEED ||
     576             :                 BUNappend(bn, "ninvcsw", false) != GDK_SUCCEED ||
     577             :                 BUNappend(b, &i, false) != GDK_SUCCEED)
     578             :                 goto bailout;
     579             : #endif
     580             : 
     581             :         if (pseudo(ret,ret2,bn,b))
     582             :                 goto bailout;
     583           0 :         return MAL_SUCCEED;
     584             : 
     585           0 :   bailout:
     586           0 :         BBPunfix(b->batCacheid);
     587           0 :         BBPunfix(bn->batCacheid);
     588           0 :         throw(MAL, "status.ioStatistics", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     589             : }
     590             : 
     591             : static str
     592           0 : SYSgdkEnv(bat *ret, bat *ret2)
     593             : {
     594           0 :         int pbat = 0;
     595           0 :         int pdisk = 0;
     596             :         bat i;
     597           0 :         int tmp = 0, per = 0;
     598             :         BAT *b,*bn;
     599             : 
     600           0 :         bn = COLnew(0, TYPE_str, 32, TRANSIENT);
     601           0 :         b = COLnew(0, TYPE_int, 32, TRANSIENT);
     602           0 :         if (b == 0 || bn == 0) {
     603           0 :                 if ( b) BBPunfix(b->batCacheid);
     604           0 :                 if ( bn) BBPunfix(bn->batCacheid);
     605           0 :                 throw(MAL, "status.batStatistics", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     606             :         }
     607             : 
     608           0 :         for (i = 1; i < getBBPsize(); i++) {
     609           0 :                 if (BBPvalid(i)) {
     610           0 :                         pbat++;
     611           0 :                         if (BBP_cache(i)) {
     612           0 :                                 if (BBP_cache(i)->batTransient)
     613           0 :                                         tmp++;
     614             :                                 else
     615           0 :                                         per++;
     616             :                         } else {
     617           0 :                                 pdisk++;
     618             :                         }
     619             :                 }
     620             :         }
     621           0 :         if (BUNappend(bn, "bats", false) != GDK_SUCCEED ||
     622           0 :                 BUNappend(b, &pbat, false) != GDK_SUCCEED ||
     623           0 :                 BUNappend(bn, "tmpbats", false) != GDK_SUCCEED ||
     624           0 :                 BUNappend(b, &tmp, false) != GDK_SUCCEED ||
     625           0 :                 BUNappend(bn, "perbats", false) != GDK_SUCCEED ||
     626           0 :                 BUNappend(b, &per, false) != GDK_SUCCEED ||
     627           0 :                 BUNappend(bn, "ondisk", false) != GDK_SUCCEED ||
     628           0 :                 BUNappend(b, &pdisk, false) != GDK_SUCCEED ||
     629             :                 pseudo(ret,ret2, bn,b)) {
     630           0 :                 BBPunfix(b->batCacheid);
     631           0 :                 BBPunfix(bn->batCacheid);
     632           0 :                 throw(MAL, "status.batStatistics", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     633             :         }
     634           0 :         return MAL_SUCCEED;
     635             : }
     636             : 
     637             : static str
     638           0 : SYSgdkThread(bat *ret, bat *ret2)
     639             : {
     640             :         BAT *b, *bn;
     641             :         int i;
     642             :         Thread thr;
     643             : 
     644           0 :         bn = COLnew(0,TYPE_int, THREADS, TRANSIENT);
     645           0 :         b = COLnew(0, TYPE_str, THREADS, TRANSIENT);
     646           0 :         if (b == 0 || bn == 0) {
     647           0 :                 if ( b) BBPunfix(b->batCacheid);
     648           0 :                 if ( bn) BBPunfix(bn->batCacheid);
     649           0 :                 throw(MAL, "status.getThreads", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     650             :         }
     651             : 
     652           0 :         for (i = 1; i <= THREADS; i++) {
     653           0 :                 thr = THRget(i);
     654           0 :                 if (ATOMIC_GET(&thr->pid)){
     655           0 :                         if (BUNappend(bn, &thr->tid, false) != GDK_SUCCEED ||
     656           0 :                                 BUNappend(b, thr->name, false) != GDK_SUCCEED)
     657           0 :                                 goto bailout;
     658             :                 }
     659             :         }
     660             :         if (pseudo(ret,ret2,bn,b))
     661             :                 goto bailout;
     662           0 :         return MAL_SUCCEED;
     663             : 
     664             :   bailout:
     665           0 :         BBPunfix(b->batCacheid);
     666           0 :         BBPunfix(bn->batCacheid);
     667           0 :         throw(MAL, "status.getThreads", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     668             : }
     669             : 
     670             : #include "mel.h"
     671             : mel_func status_init_funcs[] = {
     672             :  command("status", "cpuStatistics", SYScpuStatistics, false, "Global cpu usage information", args(2,2, batarg("",str),batarg("",lng))),
     673             :  command("status", "memStatistics", SYSmemStatistics, false, "Global memory usage information", args(2,2, batarg("",str),batarg("",lng))),
     674             :  command("status", "ioStatistics", SYSioStatistics, false, "Global IO activity information", args(2,2, batarg("",str),batarg("",lng))),
     675             :  command("status", "vmStatistics", SYSvm_usage, false, "Get a split-up of how much virtual memory blocks are in use", args(2,3, batarg("",str),batarg("",lng),arg("minsize",lng))),
     676             :  command("status", "memUsage", SYSmem_usage, false, "Get a split-up of how much memory blocks are in use", args(2,3, batarg("",str),batarg("",lng),arg("minsize",lng))),
     677             :  command("status", "batStatistics", SYSgdkEnv, false, "Show distribution of bats by kind", args(2,2, batarg("",str),batarg("",str))),
     678             :  command("status", "getThreads", SYSgdkThread, false, "Produce overview of active threads", args(2,2, batarg("",int),batarg("",str))),
     679             :  command("status", "mem_cursize", SYSgetmem_cursize, false, "The amount of physical swapspace in KB that is currently in use", args(1,1, arg("",lng))),
     680             :  command("status", "mem_maxsize", SYSgetmem_maxsize, false, "The maximum usable amount of physical swapspace in KB (target only)", args(1,1, arg("",lng))),
     681             :  command("status", "mem_maxsize", SYSsetmem_maxsize, false, "Set the maximum usable amount of physical swapspace in KB", args(1,2, arg("",void),arg("v",lng))),
     682             :  command("status", "vm_cursize", SYSgetvm_cursize, false, "The amount of logical VM space in KB that is currently in use", args(1,1, arg("",lng))),
     683             :  command("status", "vm_maxsize", SYSgetvm_maxsize, false, "The maximum usable amount of logical VM space in KB (target only)", args(1,1, arg("",lng))),
     684             :  command("status", "vm_maxsize", SYSsetvm_maxsize, false, "Set the maximum usable amount of physical swapspace in KB", args(1,2, arg("",void),arg("v",lng))),
     685             :  { .imp=NULL }
     686             : };
     687             : #include "mal_import.h"
     688             : #ifdef _MSC_VER
     689             : #undef read
     690             : #pragma section(".CRT$XCU",read)
     691             : #endif
     692         259 : LIB_STARTUP_FUNC(init_status_mal)
     693         259 : { mal_module("status", NULL, status_init_funcs); }

Generated by: LCOV version 1.14