Ignore:
Timestamp:
Dec 9, 2000, 8:19:42 PM (25 years ago)
Author:
umoeller
Message:

Major updates; timers, LVM, miscellaneous.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/helpers/dosh.c

    r13 r14  
    3131/*
    3232 *      This file Copyright (C) 1997-2000 Ulrich M”ller.
    33  *      This file is part of the XWorkplace source package.
    34  *      XWorkplace is free software; you can redistribute it and/or modify
     33 *      This file is part of the "XWorkplace helpers" source package.
     34 *      This is free software; you can redistribute it and/or modify
    3535 *      it under the terms of the GNU General Public License as published
    3636 *      by the Free Software Foundation, in version 2 as it comes in the
     
    4747    // as unsigned char
    4848
    49 #define INCL_DOS
     49#define INCL_DOSMODULEMGR
     50#define INCL_DOSPROCESS
     51#define INCL_DOSSESMGR
     52#define INCL_DOSQUEUES
     53#define INCL_DOSMISC
     54#define INCL_DOSDEVICES
    5055#define INCL_DOSDEVIOCTL
    5156#define INCL_DOSERRORS
     57
    5258#define INCL_KBD
    5359#include <os2.h>
     60
    5461#include <stdlib.h>
    5562#include <string.h>
    5663#include <stdio.h>
    57 // #include <ctype.h>
    5864
    5965#include "setup.h"                      // code generation and debugging options
     
    7076
    7177/* ******************************************************************
    72  *                                                                  *
    73  *   Miscellaneous                                                  *
    74  *                                                                  *
     78 *
     79 *   Miscellaneous
     80 *
    7581 ********************************************************************/
    7682
     
    172178
    173179    return (s_brc);
     180}
     181
     182/*
     183 *@@ doshQueryAvailPhysMem:
     184 *      returns the amount of physical memory which
     185 *      is presently available (before the swapper
     186 *      would have to be expanded).
     187 *
     188 *      This number is calculated by getting the
     189 *      total available memory (QSV_TOTRESMEM)
     190 *      and subtracting the free space on the
     191 *      drive with the swap file from it.
     192 *
     193 *      As a result, you also need to specify
     194 *      the logical drive on which the swapper
     195 *      resides (3 = C, 4 = D, and so on).
     196 *
     197 *@@added V0.9.7 (2000-12-01) [umoeller]
     198 */
     199
     200APIRET doshQueryAvailPhysMem(PULONG pulMem,
     201                             ULONG ulLogicalSwapDrive)
     202{
     203    APIRET arc = DosQuerySysInfo(QSV_TOTAVAILMEM,
     204                                 QSV_TOTAVAILMEM,
     205                                 pulMem,
     206                                 sizeof(*pulMem));
     207    if (arc == NO_ERROR)
     208    {
     209        double dFree = 0;
     210        arc = doshQueryDiskFree(ulLogicalSwapDrive,
     211                                &dFree);
     212        *pulMem -= (ULONG)dFree;
     213    }
     214
     215    return (arc);
    174216}
    175217
     
    213255
    214256/* ******************************************************************
    215  *                                                                  *
    216  *   Memory helpers                                                 *
    217  *                                                                  *
     257 *
     258 *   Memory helpers
     259 *
    218260 ********************************************************************/
    219261
     
    283325
    284326/* ******************************************************************
    285  *                                                                  *
    286  *   Drive helpers                                                  *
    287  *                                                                  *
     327 *
     328 *   Drive helpers
     329 *
    288330 ********************************************************************/
    289331
     
    417459{
    418460    ULONG ulBootDrive;
    419     DosQuerySysInfo(5, 5, &ulBootDrive, sizeof(ulBootDrive));
     461    DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
     462                    &ulBootDrive,
     463                    sizeof(ulBootDrive));
    420464    return (G_acDriveLetters[ulBootDrive]);
    421465}
     
    461505                  OPEN_FLAGS_DASD
    462506                         | OPEN_FLAGS_FAIL_ON_ERROR
     507                         | OPEN_FLAGS_NOINHERIT     // V0.9.6 (2000-11-25) [pr]
    463508                         | OPEN_ACCESS_READONLY
    464509                         | OPEN_SHARE_DENYNONE,
     
    523568
    524569/*
     570 *@@ doshSetLogicalMap:
     571 *       sets the mapping of logical floppy drives onto a single
     572 *       physical floppy drive.
     573 *       This means selecting either drive A: or drive B: to refer
     574 *       to the physical drive.
     575 *
     576 *@@added V0.9.6 (2000-11-24) [pr]
     577 */
     578
     579APIRET doshSetLogicalMap(ULONG ulLogicalDrive)
     580{
     581    CHAR    name[3] = "?:";
     582    ULONG   fd = 0,
     583            action = 0,
     584            paramsize = 0,
     585            datasize = 0;
     586    APIRET    rc = NO_ERROR;
     587    USHORT    data,
     588              param;
     589
     590    name[0] = doshQueryBootDrive();
     591    rc = DosOpen(name,
     592                 &fd,
     593                 &action,
     594                 0,
     595                 0,
     596                 OPEN_ACTION_FAIL_IF_NEW
     597                          | OPEN_ACTION_OPEN_IF_EXISTS,
     598                 OPEN_FLAGS_DASD
     599                       | OPEN_FLAGS_FAIL_ON_ERROR
     600                       | OPEN_FLAGS_NOINHERIT
     601                       | OPEN_ACCESS_READONLY
     602                       | OPEN_SHARE_DENYNONE,
     603                 0);
     604    if (rc == NO_ERROR)
     605    {
     606        param = 0;
     607        data = (USHORT)ulLogicalDrive;
     608        paramsize = sizeof(param);
     609        datasize = sizeof(data);
     610        rc = DosDevIOCtl(fd,
     611                         IOCTL_DISK, DSK_SETLOGICALMAP,
     612                         &param, paramsize, &paramsize,
     613                         &data, datasize, &datasize);
     614        DosClose(fd);
     615    }
     616
     617    return(rc);
     618}
     619
     620/*
    525621 *@@ doshQueryDiskFree:
    526622 *       returns the number of bytes remaining on the disk
    527  *       specified by the given logical drive, or -1 upon errors.
     623 *       specified by the given logical drive.
    528624 *
    529625 *       Note: This returns a "double" value, because a ULONG
     
    532628 *
    533629 *@@changed V0.9.0 [umoeller]: fixed another > 4 GB bug (thanks to Rdiger Ihle)
    534  */
    535 
    536 double doshQueryDiskFree(ULONG ulLogicalDrive) // in: 1 for A:, 2 for B:, 3 for C:, ...
    537 {
     630 *@@changed V0.9.7 (2000-12-01) [umoeller]: changed prototype
     631 */
     632
     633APIRET doshQueryDiskFree(ULONG ulLogicalDrive, // in: 1 for A:, 2 for B:, 3 for C:, ...
     634                         double *pdFree)
     635{
     636    APIRET      arc = NO_ERROR;
    538637    FSALLOCATE  fsa;
    539638    double      dbl = -1;
    540639
    541     if (ulLogicalDrive)
    542         if (DosQueryFSInfo(ulLogicalDrive, FSIL_ALLOC, &fsa, sizeof(fsa))
    543                 == NO_ERROR)
    544             dbl = ((double)fsa.cSectorUnit * fsa.cbSector * fsa.cUnitAvail);
     640    arc = DosQueryFSInfo(ulLogicalDrive, FSIL_ALLOC, &fsa, sizeof(fsa));
     641    if (arc == NO_ERROR)
     642        *pdFree = ((double)fsa.cSectorUnit * fsa.cbSector * fsa.cUnitAvail);
    545643                   // ^ fixed V0.9.0
    546644
    547     return (dbl);
     645    return (arc);
    548646}
    549647
     
    779877
    780878/* ******************************************************************
    781  *                                                                  *
    782  *   File helpers                                                   *
    783  *                                                                  *
     879 *
     880 *   File helpers
     881 *
    784882 ********************************************************************/
    785883
     
    12261324
    12271325/* ******************************************************************
    1228  *                                                                  *
    1229  *   Directory helpers                                              *
    1230  *                                                                  *
     1326 *
     1327 *   Directory helpers
     1328 *
    12311329 ********************************************************************/
    12321330
     
    14591557
    14601558/*
     1559 *@@category: Helpers\Control program helpers\Performance (CPU load) helpers
     1560 */
     1561
     1562/* ******************************************************************
     1563 *
     1564 *   Performance Counters (CPU Load)
     1565 *
     1566 ********************************************************************/
     1567
     1568/*
     1569 *@@ doshPerfOpen:
     1570 *      initializes the OS/2 DosPerfSysCall API for
     1571 *      the calling thread.
     1572 *
     1573 *      Note: This API is not supported on all OS/2
     1574 *      versions. I believe it came up with some Warp 4
     1575 *      fixpak. The API is resolved dynamically by
     1576 *      this function (using DosQueryProcAddr). Only
     1577 *      if NO_ERROR is returned, you may call doshPerfGet
     1578 *      afterwards.
     1579 *
     1580 *      This properly initializes the internal counters
     1581 *      which the OS/2 kernel uses for this API. Apparently,
     1582 *      with newer kernels (FP13/14), IBM has chosen to no
     1583 *      longer do this automatically, which is the reason
     1584 *      why many "pulse" utilities display garbage with these
     1585 *      fixpaks.
     1586 *
     1587 *      After NO_ERROR is returned, DOSHPERFSYS.cProcessors
     1588 *      contains the no. of processors found on the system.
     1589 *      All pointers in DOSHPERFSYS then point to arrays
     1590 *      which have exactly cProcessors array items.
     1591 *
     1592 *      Call doshPerfClose to clean up resources allocated
     1593 *      by this function.
     1594 *
     1595 *      Example code:
     1596 *
     1597 +      PDOSHPERFSYS pPerf = NULL;
     1598 +      APIRET arc = doshPerfOpen(&pPerf);
     1599 +      if (arc == NO_ERROR)
     1600 +      {
     1601 +          // this should really be in a timer
     1602 +          ULONG   ulCPU;
     1603 +          arc = doshPerfGet(&pPerf);
     1604 +          // go thru all CPUs
     1605 +          for (ulCPU = 0; ulCPU < pPerf->cProcessors; ulCPU++)
     1606 +          {
     1607 +              LONG lLoadThis = pPerf->palLoads[ulCPU];
     1608 +              ...
     1609 +          }
     1610 +
     1611 +          ...
     1612 +
     1613 +          // clean up
     1614 +          doshPerfClose(&pPerf);
     1615 +      }
     1616 +
     1617 *
     1618 *@@added V0.9.7 (2000-12-02) [umoeller]
     1619 */
     1620
     1621APIRET doshPerfOpen(PDOSHPERFSYS *ppPerfSys)  // out: new DOSHPERFSYS structure
     1622{
     1623    APIRET  arc = NO_ERROR;
     1624
     1625    // allocate DOSHPERFSYS structure
     1626    *ppPerfSys = (PDOSHPERFSYS)malloc(sizeof(DOSHPERFSYS));
     1627    if (!*ppPerfSys)
     1628        arc = ERROR_NOT_ENOUGH_MEMORY;
     1629    else
     1630    {
     1631        // initialize structure
     1632        PDOSHPERFSYS pPerfSys = *ppPerfSys;
     1633        memset(pPerfSys, 0, sizeof(*pPerfSys));
     1634
     1635        // resolve DosPerfSysCall API entry
     1636        arc = DosLoadModule(NULL, 0, "DOSCALLS", &pPerfSys->hmod);
     1637        if (arc == NO_ERROR)
     1638        {
     1639            arc = DosQueryProcAddr(pPerfSys->hmod,
     1640                                   976,
     1641                                   "DosPerfSysCall",
     1642                                   (PFN*)(&pPerfSys->pDosPerfSysCall));
     1643            if (arc == NO_ERROR)
     1644            {
     1645                // OK, we got the API: initialize!
     1646                arc = pPerfSys->pDosPerfSysCall(CMD_KI_ENABLE, 0, 0, 0);
     1647                if (arc == NO_ERROR)
     1648                {
     1649                    pPerfSys->fInitialized = TRUE;
     1650                            // call CMD_KI_DISABLE later
     1651
     1652                    arc = pPerfSys->pDosPerfSysCall(CMD_PERF_INFO,
     1653                                                    0,
     1654                                                    (ULONG)(&pPerfSys->cProcessors),
     1655                                                    0);
     1656                    if (arc == NO_ERROR)
     1657                    {
     1658                        ULONG   ul = 0;
     1659
     1660                        // allocate arrays
     1661                        pPerfSys->paCPUUtils = (PCPUUTIL)calloc(pPerfSys->cProcessors,
     1662                                                                sizeof(CPUUTIL));
     1663                        if (!pPerfSys->paCPUUtils)
     1664                            arc = ERROR_NOT_ENOUGH_MEMORY;
     1665                        else
     1666                        {
     1667                            pPerfSys->padBusyPrev = (double*)malloc(pPerfSys->cProcessors * sizeof(double));
     1668                            if (!pPerfSys->padBusyPrev)
     1669                                arc = ERROR_NOT_ENOUGH_MEMORY;
     1670                            else
     1671                            {
     1672                                pPerfSys->padTimePrev
     1673                                    = (double*)malloc(pPerfSys->cProcessors * sizeof(double));
     1674                                if (!pPerfSys->padTimePrev)
     1675                                    arc = ERROR_NOT_ENOUGH_MEMORY;
     1676                                else
     1677                                {
     1678                                    pPerfSys->palLoads = (PLONG)malloc(pPerfSys->cProcessors * sizeof(LONG));
     1679                                    if (!pPerfSys->palLoads)
     1680                                        arc = ERROR_NOT_ENOUGH_MEMORY;
     1681                                    else
     1682                                    {
     1683                                        for (ul = 0; ul < pPerfSys->cProcessors; ul++)
     1684                                        {
     1685                                            pPerfSys->padBusyPrev[ul] = 0.0;
     1686                                            pPerfSys->padTimePrev[ul] = 0.0;
     1687                                            pPerfSys->palLoads[ul] = 0;
     1688                                        }
     1689                                    }
     1690                                }
     1691                            }
     1692                        }
     1693                    }
     1694                }
     1695            } // end if (arc == NO_ERROR)
     1696        } // end if (arc == NO_ERROR)
     1697
     1698        if (arc != NO_ERROR)
     1699        {
     1700            doshPerfClose(ppPerfSys);
     1701        }
     1702    } // end else if (!*ppPerfSys)
     1703
     1704    return (arc);
     1705}
     1706
     1707/*
     1708 *@@ doshPerfGet:
     1709 *      calculates a current snapshot of the system load,
     1710 *      compared with the load which was calculated on
     1711 *      the previous call.
     1712 *
     1713 *      If you want to continually measure the system CPU
     1714 *      load, this is the function you will want to call
     1715 *      regularly -- e.g. with a timer once per second.
     1716 *
     1717 *      Call this ONLY if doshPerfOpen returned NO_ERROR,
     1718 *      or you'll get crashes.
     1719 *
     1720 *      If this call returns NO_ERROR, you get a LONG
     1721 *      CPU load for each CPU in the system in the
     1722 *      DOSHPERFSYS.palLoads array (in per-mille, 0-1000).
     1723 *
     1724 *      For example, if there are two CPUs, after this call,
     1725 *
     1726 *      -- DOSHPERFSYS.palLoads[0] contains the load of
     1727 *         the first CPU,
     1728 *
     1729 *      -- DOSHPERFSYS.palLoads[1] contains the load of
     1730 *         the second CPU.
     1731 *
     1732 *      See doshPerfOpen for example code.
     1733 *
     1734 *@@added V0.9.7 (2000-12-02) [umoeller]
     1735 */
     1736
     1737APIRET doshPerfGet(PDOSHPERFSYS pPerfSys)
     1738{
     1739    APIRET arc = NO_ERROR;
     1740    if (!pPerfSys->pDosPerfSysCall)
     1741        arc = ERROR_INVALID_PARAMETER;
     1742    else
     1743    {
     1744        arc = pPerfSys->pDosPerfSysCall(CMD_KI_RDCNT,
     1745                                        (ULONG)pPerfSys->paCPUUtils,
     1746                                        0, 0);
     1747        if (arc == NO_ERROR)
     1748        {
     1749            // go thru all processors
     1750            ULONG ul = 0;
     1751            for (; ul < pPerfSys->cProcessors; ul++)
     1752            {
     1753                PCPUUTIL    pCPUUtilThis = &pPerfSys->paCPUUtils[ul];
     1754
     1755                double      dTime = LL2F(pCPUUtilThis->ulTimeHigh,
     1756                                         pCPUUtilThis->ulTimeLow);
     1757                double      dBusy = LL2F(pCPUUtilThis->ulBusyHigh,
     1758                                         pCPUUtilThis->ulBusyLow);
     1759
     1760                double      *pdBusyPrevThis = &pPerfSys->padBusyPrev[ul];
     1761                double      *pdTimePrevThis = &pPerfSys->padTimePrev[ul];
     1762
     1763                // avoid division by zero
     1764                double      dTimeDelta = (dTime - *pdTimePrevThis);
     1765                if (dTimeDelta)
     1766                    pPerfSys->palLoads[ul]
     1767                        = (LONG)( (double)(   (dBusy - *pdBusyPrevThis)
     1768                                            / dTimeDelta
     1769                                            * 1000.0
     1770                                          )
     1771                                );
     1772                else
     1773                    pPerfSys->palLoads[ul] = 0;
     1774
     1775                *pdTimePrevThis = dTime;
     1776                *pdBusyPrevThis = dBusy;
     1777            }
     1778        }
     1779    }
     1780
     1781    return (arc);
     1782}
     1783
     1784/*
     1785 *@@ doshPerfClose:
     1786 *      frees all resources allocated by doshPerfOpen.
     1787 *
     1788 *@@added V0.9.7 (2000-12-02) [umoeller]
     1789 */
     1790
     1791APIRET doshPerfClose(PDOSHPERFSYS *ppPerfSys)
     1792{
     1793    APIRET arc = NO_ERROR;
     1794    PDOSHPERFSYS pPerfSys = *ppPerfSys;
     1795    if (!pPerfSys)
     1796        arc = ERROR_INVALID_PARAMETER;
     1797    else
     1798    {
     1799        if (pPerfSys->fInitialized)
     1800            pPerfSys->pDosPerfSysCall(CMD_KI_DISABLE,
     1801                                      0, 0, 0);
     1802
     1803        if (pPerfSys->paCPUUtils)
     1804            free(pPerfSys->paCPUUtils);
     1805        if (pPerfSys->padBusyPrev)
     1806            free(pPerfSys->padBusyPrev);
     1807        if (pPerfSys->padTimePrev)
     1808            free(pPerfSys->padTimePrev);
     1809
     1810        if (pPerfSys->hmod)
     1811            DosFreeModule(pPerfSys->hmod);
     1812        free(pPerfSys);
     1813        *ppPerfSys = NULL;
     1814    }
     1815
     1816    return (arc);
     1817}
     1818
     1819/*
    14611820 *@@category: Helpers\Control program helpers\Process management
    14621821 */
    14631822
    14641823/* ******************************************************************
    1465  *                                                                  *
    1466  *   Process helpers                                                *
    1467  *                                                                  *
     1824 *
     1825 *   Process helpers
     1826 *
    14681827 ********************************************************************/
    14691828
Note: See TracChangeset for help on using the changeset viewer.