home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / salomo.zip / SALOMON.TXT
Text File  |  1993-05-17  |  38KB  |  1,141 lines

  1. #--------------------------------------------------------------------------
  2. # Program name:  MAKEFILE       Title:  Memory toolbox make file
  3. # OS/2 Developer Magazine       Issue:  Spring '93, page 127
  4. #
  5. # Article:  "Writing Memory Allocation Functions With DosSubAllocMem"
  6. # Author:  Larry Salomon, Jr.
  7. # Phone:  n/a                   Fax:  n/a
  8. #
  9. # Description:  The following is a component of the complete source to the
  10. # above article in the specified issue of OS/2 Developer Magazine.  This
  11. # source is provided AS-IS without any implied or expressed warranty.  The
  12. # author can be contacted via the Internet at the email address
  13. # "os2man@panix.com".
  14. #
  15. # This component contains the make file needed to build the memory
  16. # toolbox.  Before building, the following macro definitions need to be
  17. # changed to reflect the directory structure on your machine:
  18. #
  19. # MYLIB         - specifies the directory to copy the library into for
  20. #                 linking by other programs and to copy the programming
  21. #                 reference into.
  22. #
  23. # To build the 32-bit version, type "nmake 32bit" on any OS/2 command line.
  24. # To build the 16-bit version, type "nmake 16bit" on any OS/2 command line.
  25. #
  26. # Program requirements:  IBM C-Set/2 for 32-bit compilation, Microsoft
  27. # C 6.0 (or better) for 16-bit compilation.
  28. #--------------------------------------------------------------------------
  29. MYLIB=D:\MYLIB
  30.  
  31. 32BIT:
  32.         @NMAKE SUFFIX=32 TBMEM32.LIB
  33.  
  34. 16BIT:
  35.         @NMAKE SUFFIX=16 TBMEM16.LIB
  36.  
  37. !IF "$(SUFFIX)"=="32"
  38. CLOPTS=-C+ -Kb+ -Ss+ -W3 -D_32BIT
  39.  
  40. !IFDEF DEBUG
  41. CLOPTS=$(CLOPTS) -Ti+
  42. !ENDIF
  43.  
  44. CLEXE=ICC
  45. LIBEXE=LIB
  46. !ELSE
  47. CLOPTS=-c -AL -W4 -G2 -D_16BIT
  48.  
  49. !IFDEF DEBUG
  50. CLOPTS=$(CLOPTS) -Zipde -Od
  51. !ELSE
  52. CLOPTS=$(CLOPTS) -Zpe -Ol
  53. !ENDIF
  54.  
  55. CLEXE=CL
  56. LIBEXE=LIB
  57. !ENDIF
  58.  
  59. TBMEM$(SUFFIX).LIB:             TBMEM$(SUFFIX).OBJ
  60.         IF EXIST TBMEM$(SUFFIX).LIB DEL TBMEM$(SUFFIX).LIB
  61.         $(LIBEXE) @<<
  62. TBMEM$(SUFFIX).LIB
  63. Y
  64. + TBMEM$(SUFFIX).OBJ;
  65. <<
  66.         COPY TBMEM$(SUFFIX).LIB $(MYLIB)
  67.  
  68. TBMEM$(SUFFIX).OBJ:             TBMEM.C \
  69.                                 TBMEM.H
  70.         $(CLEXE) $(CLOPTS) -FoTBMEM$(SUFFIX).OBJ TBMEM.C
  71.  
  72. TBMEM.INF:                      TBMEM.IPF
  73.         IPFC /INF TBMEM.IPF
  74.         COPY TBMEM.INF $(MYLIB)
  75.  
  76. ---------------------------------------------------------
  77.  
  78. //-------------------------------------------------------------------------
  79. // Program name:  TBMEM.C        Title:  Memory toolbox
  80. // OS/2 Developer Magazine       Issue:  Spring '93, page 127
  81. //
  82. // Article:  "Writing Memory Allocation Functions With DosSubAllocMem"
  83. // Author:  Larry Salomon, Jr.
  84. // Phone:  n/a                   Fax:  n/a
  85. //
  86. // Description:  The following is a component of the complete source to the
  87. // above article in the specified issue of OS/2 Developer Magazine.  This
  88. // source is provided AS-IS without any implied or expressed warranty.  The
  89. // author can be contacted via the Internet at the email address
  90. // "os2man@panix.com".
  91. //
  92. // This component contains the implementation source for the routines
  93. // as described by the article.
  94. //
  95. // Program requirements:  IBM C-Set/2 for 32-bit compilation, Microsoft
  96. // C 6.0 (or better) for 16-bit compilation.
  97. //-------------------------------------------------------------------------
  98. #define INCL_DOSMEMMGR
  99. #define INCL_DOSSEMAPHORES
  100. #include <os2.h>
  101. #include <stdlib.h>
  102. #include <string.h>
  103. #include <tbheader.h>
  104. #include "tbmem.h"
  105.  
  106. #define TBSIG_HTBMEM             MAKEULONG(TBSIG_TBMEM,0x0000)
  107. #define SZACTUAL(ulSzBuf)
  108. (ULONG)((ulSzBuf+sizeof(TBHEAPINFO))+8-((ulSzBuf+sizeof(TBHEAPINFO))%8))
  109.  
  110. static PVOID myMalloc(ULONG ulSzBuf)
  111. //-------------------------------------------------------------------------
  112. // This function allocates a block of memory using the appropriate
  113. // system call.
  114. //
  115. // Input:  ulSzBuf - specifies the requested size of the buffer in bytes
  116. // Returns:  pointer to the buffer if successful, NULL otherwise
  117. //-------------------------------------------------------------------------
  118. {
  119.    PVOID pvBuf;
  120.  
  121. #ifdef _32BIT
  122.    if (DosAllocMem(&pvBuf,ulSzBuf,PAG_READ|PAG_WRITE|PAG_COMMIT|OBJ_TILE)) {
  123.       return NULL;
  124.    } /* endif */
  125.  
  126.    memset(pvBuf,0,ulSzBuf);
  127. #else
  128.    if (DosAllocSeg((USHORT)ulSzBuf,&SELECTOROF(pvBuf),SEG_NONSHARED)) {
  129.       return NULL;
  130.    } /* endif */
  131.  
  132.    OFFSETOF(pvBuf)=0;
  133.  
  134.    memset(pvBuf,0,(USHORT)ulSzBuf);
  135. #endif
  136.    return pvBuf;
  137. }
  138.  
  139. static BOOL myFree(PVOID pvBuf)
  140. //-------------------------------------------------------------------------
  141. // This function frees the buffer.  It assumes that the buffer was
  142. // allocated with myMalloc().
  143. //
  144. // Input:  pvBuf - points to the buffer to free
  145. // Returns:  TRUE if successful, FALSE otherwise
  146. //-------------------------------------------------------------------------
  147. {
  148. #ifdef _32BIT
  149.    if (pvBuf==NULL) {
  150.       return FALSE;
  151.    } else
  152.    if (DosFreeMem(pvBuf)) {
  153.       return FALSE;
  154.    } else {
  155.       return TRUE;
  156.    } /* endif */
  157. #else
  158.    if (pvBuf==NULL) {
  159.       return FALSE;
  160.    } else
  161.    if (DosFreeSeg(SELECTOROF(pvBuf))) {
  162.       return FALSE;
  163.    } else {
  164.       return TRUE;
  165.    } /* endif */
  166. #endif
  167. }
  168.  
  169. static USHORT semAccess(PTBHEADER ptbhHeader,USHORT usAction)
  170. //-------------------------------------------------------------------------
  171. // This function provides access to the specified handle via the
  172. // appropriate system semaphore function.
  173. //
  174. // Input:  ptbhHeader - pointer to the toolbox handle header
  175. //         usAction - specifies the action to take as a TBSEM_* constant
  176. // Returns:  TBSEM_ERROR if an error occurs, value for usAction to for
  177. //           next call to function otherwise
  178. //-------------------------------------------------------------------------
  179. {
  180.    switch (usAction) {
  181.    case TBSEM_SET:
  182.       if ((ptbhHeader->ulStatus & TBSTS_INTOOLBOX)!=0) {
  183.          return TBSEM_ALREADYSET;
  184.       } /* endif */
  185.  
  186. #ifdef _32BIT
  187.       DosRequestMutexSem(ptbhHeader->hsmAccess,SEM_INDEFINITE_WAIT);
  188. #else
  189.       DosSemRequest(&ptbhHeader->hsmAccess,SEM_INDEFINITE_WAIT);
  190.       DosSemSet(&ptbhHeader->hsmAccess);
  191. #endif
  192.       ptbhHeader->ulStatus|=TBSTS_INTOOLBOX;
  193.       return TBSEM_CLEAR;
  194.    case TBSEM_CLEAR:
  195.       if ((ptbhHeader->ulStatus & TBSTS_INTOOLBOX)==0) {
  196.          return TBSEM_NOTSET;
  197.       } /* endif */
  198.  
  199. #ifdef _32BIT
  200.       DosReleaseMutexSem(ptbhHeader->hsmAccess);
  201. #else
  202.       DosSemClear(&ptbhHeader->hsmAccess);
  203. #endif
  204.       ptbhHeader->ulStatus&=~TBSTS_INTOOLBOX;
  205.       return TBSEM_SET;
  206.    case TBSEM_ALREADYSET:
  207.       return TBSEM_NOTSET;
  208.    case TBSEM_NOTSET:
  209.       return TBSEM_ALREADYSET;
  210.    default:
  211.       return TBSEM_ERROR;
  212.    } /* endswitch */
  213. }
  214.  
  215. TBERROR MemInitialize(PTBMEMINFO ptbmiInfo,PHTBMEM phtbmMem)
  216. //-------------------------------------------------------------------------
  217. // This function initializes an instance to the memory manager and
  218. // returns a handle to the instance.
  219. //
  220. // Input:  ptbmiInfo - pointer to the TBMEMINFO structure specifying
  221. //                     the desired attributes of the instance.  If this
  222. //                     is NULL, the defaults are used
  223. //         phtbmMem - pointer to the variable which receives the result.
  224. //                    On return, this variable contains a memory handle
  225. // Returns:  TBMEM_EC_* constant
  226. //-------------------------------------------------------------------------
  227. {
  228.    TBMEMINFO tbmiInfo;
  229.    ULONG ulSzBuf;
  230.  
  231.    *phtbmMem=NULL;
  232.  
  233.    if (ptbmiInfo!=NULL) {
  234.       tbmiInfo=*ptbmiInfo;
  235.    } else {
  236.       tbmiInfo.usNumHeaps=256;
  237.       tbmiInfo.ulSzHeap=61440;
  238.    } /* endif */
  239.  
  240.    ulSzBuf=sizeof(TBMEM)+sizeof(TBHEAP)*(tbmiInfo.usNumHeaps-1);
  241.  
  242.    *phtbmMem=myMalloc(ulSzBuf);
  243.    if (*phtbmMem==NULL) {
  244.       return TBMEM_EC_NOMEMORY;
  245.    } /* endif */
  246.  
  247.    (*phtbmMem)->ulSig=TBSIG_HTBMEM;
  248.    (*phtbmMem)->ulStatus=0L;
  249.  
  250. #ifdef _32BIT
  251.    if (DosCreateMutexSem(NULL,&(*phtbmMem)->hsmAccess,0,FALSE)) {
  252.       free(*phtbmMem);
  253.       return TBMEM_EC_INITFAILED;
  254.    } /* endif */
  255. #else
  256.    (*phtbmMem)->hsmAccess=0L;
  257. #endif
  258.  
  259.    (*phtbmMem)->tbmiInfo=tbmiInfo;
  260.  
  261.    return TBMEM_EC_NOERROR;
  262. }
  263.  
  264. TBERROR MemTerminate(HTBMEM htbmMem)
  265. //-------------------------------------------------------------------------
  266. // This function destroys the memory handle specified and returns all
  267. // used memory to the system (via a call to MemReset()).
  268. //
  269. // Input:  htbmMem - specifies the handle to destroy
  270. // Returns:  TBMEM_EC_* constant
  271. //-------------------------------------------------------------------------
  272. {
  273.    USHORT usSemAction;
  274.  
  275.    if (MemQueryHandle(htbmMem)!=TBMEM_QH_HTBMEM) {
  276.       return TBMEM_EC_BADHANDLE;
  277.    } /* endif */
  278.  
  279.    usSemAction=semAccess((PTBHEADER)htbmMem,TBSEM_SET);
  280.  
  281.    if (MemReset(htbmMem)!=TBMEM_EC_NOERROR) {
  282.       semAccess((PTBHEADER)htbmMem,usSemAction);
  283.       return TBMEM_EC_ERROR;
  284.    } /* endif */
  285.  
  286.    semAccess((PTBHEADER)htbmMem,usSemAction);
  287. #ifdef _32BIT
  288.    DosCloseMutexSem(htbmMem->hsmAccess);
  289. #endif                           // #ifdef _32BIT
  290.    myFree(htbmMem);
  291.    return TBMEM_EC_NOERROR;
  292. }
  293.  
  294. TBERROR MemReset(HTBMEM htbmMem)
  295. //-------------------------------------------------------------------------
  296. // This function "resets" the memory handle specified.  That is, all
  297. // memory currently consumed is returned to the system.
  298. //
  299. // Input:  htbmMem - specifies the handle to reset
  300. // Returns:  TBMEM_EC_* constant
  301. //-------------------------------------------------------------------------
  302. {
  303.    USHORT usSemAction;
  304.    USHORT usIndex;
  305.  
  306.    if (MemQueryHandle(htbmMem)!=TBMEM_QH_HTBMEM) {
  307.       return TBMEM_EC_BADHANDLE;
  308.    } /* endif */
  309.  
  310.    usSemAction=semAccess((PTBHEADER)htbmMem,TBSEM_SET);
  311.  
  312.    for (usIndex=0; usIndex<htbmMem->tbmiInfo.usNumHeaps; usIndex++) {
  313.       if (htbmMem->atbhHeaps[usIndex].pvHeap!=NULL) {
  314.          myFree(htbmMem->atbhHeaps[usIndex].pvHeap);
  315.          htbmMem->atbhHeaps[usIndex].ulRef=0;
  316.          htbmMem->atbhHeaps[usIndex].pvHeap=NULL;
  317.       } /* endif */
  318.    } /* endfor */
  319.  
  320.    semAccess((PTBHEADER)htbmMem,usSemAction);
  321.    return TBMEM_EC_NOERROR;
  322. }
  323.  
  324. TBERROR MemAllocMem(HTBMEM htbmMem,ULONG ulSzBuf,PVOID *ppvBuf)
  325. //-------------------------------------------------------------------------
  326. // This function allocates a buffer of the size requested from the
  327. // specified memory handle.
  328. //
  329. // Input:  htbmMem - specifies the memory handle to allocate from
  330. //         ulSzBuf - specifies the size of the buffer
  331. //         ppvBuf - pointer to the variable which receives the result.  On
  332. //                  return, this contains a pointer to the allocated
  333. //                  memory
  334. // Returns:  TBMEM_EC_* constant
  335. //-------------------------------------------------------------------------
  336. {
  337.    USHORT usSemAction;
  338.    ULONG ulSzActual;
  339.    USHORT usFirstNull;
  340.    USHORT usIndex;
  341.    PTBHEAPINFO ptbhiInfo;
  342.    PTBHEAP ptbhHeap;
  343.  
  344.    if (MemQueryHandle(htbmMem)!=TBMEM_QH_HTBMEM) {
  345.       return TBMEM_EC_BADHANDLE;
  346.    } /* endif */
  347.  
  348.    usSemAction=semAccess((PTBHEADER)htbmMem,TBSEM_SET);
  349.    *ppvBuf=NULL;
  350.  
  351.    ulSzActual=SZACTUAL(ulSzBuf);
  352.  
  353.    if (ulSzActual>htbmMem->tbmiInfo.ulSzHeap-64) {
  354.       semAccess((PTBHEADER)htbmMem,usSemAction);
  355.       return TBMEM_EC_SIZETOOLARGE;
  356.    } /* endif */
  357.  
  358.    usFirstNull=htbmMem->tbmiInfo.usNumHeaps;
  359.  
  360.    for (usIndex=0; usIndex<htbmMem->tbmiInfo.usNumHeaps; usIndex++) {
  361.       if (htbmMem->atbhHeaps[usIndex].pvHeap!=NULL) {
  362. #ifdef _32BIT
  363.          if (!DosSubAllocMem(htbmMem->atbhHeaps[usIndex].pvHeap,
  364.                              (PVOID)&ptbhiInfo,
  365.                              ulSzActual)) {
  366. #else
  367.          if (!DosSubAlloc(SELECTOROF(htbmMem->atbhHeaps[usIndex].pvHeap),
  368.                           &OFFSETOF(ptbhiInfo),
  369.                           (USHORT)ulSzActual)) {
  370.  
  371. SELECTOROF(ptbhiInfo)=SELECTOROF(htbmMem->atbhHeaps[usIndex].pvHeap);
  372. #endif
  373.             htbmMem->atbhHeaps[usIndex].ulRef++;
  374.  
  375.             ptbhiInfo->ulSzRequested=ulSzBuf;
  376.  
  377.             *ppvBuf=(PVOID)(ptbhiInfo+1);
  378.             semAccess((PTBHEADER)htbmMem,usSemAction);
  379.             return TBMEM_EC_NOERROR;
  380.          } /* endif */
  381.       } else
  382.       if (usFirstNull==htbmMem->tbmiInfo.usNumHeaps) {
  383.          usFirstNull=usIndex;
  384.       } /* endif */
  385.    } /* endfor */
  386.  
  387.    if (usFirstNull==htbmMem->tbmiInfo.usNumHeaps) {
  388.       semAccess((PTBHEADER)htbmMem,usSemAction);
  389.       return TBMEM_EC_NOMEMORY;
  390.    } /* endif */
  391.  
  392.    ptbhHeap=&htbmMem->atbhHeaps[usFirstNull];
  393.    ptbhHeap->ulRef=0;
  394.  
  395.    ptbhHeap->pvHeap=myMalloc(htbmMem->tbmiInfo.ulSzHeap);
  396.    if (ptbhHeap->pvHeap==NULL) {
  397.       semAccess((PTBHEADER)htbmMem,usSemAction);
  398.       return TBMEM_EC_NOMEMORY;
  399.    } /* endif */
  400.  
  401. #ifdef _32BIT
  402.    if (DosSubSetMem(ptbhHeap->pvHeap,
  403.                     DOSSUB_INIT,
  404.                     htbmMem->tbmiInfo.ulSzHeap)) {
  405.       myFree(ptbhHeap->pvHeap);
  406.       semAccess((PTBHEADER)htbmMem,usSemAction);
  407.       return TBMEM_EC_NOMEMORY;
  408.    } /* endif */
  409.  
  410.    if (!DosSubAllocMem(ptbhHeap->pvHeap,
  411.                        (PVOID)&ptbhiInfo,
  412.                        ulSzActual)) {
  413. #else
  414.    if (DosSubSet(SELECTOROF(ptbhHeap->pvHeap),
  415.                  TRUE,
  416.                  (USHORT)htbmMem->tbmiInfo.ulSzHeap)) {
  417.       myFree(ptbhHeap->pvHeap);
  418.       semAccess((PTBHEADER)htbmMem,usSemAction);
  419.       return TBMEM_EC_NOMEMORY;
  420.    } /* endif */
  421.  
  422.    if (!DosSubAlloc(SELECTOROF(ptbhHeap->pvHeap),
  423.                     &OFFSETOF(ptbhiInfo),
  424.                     (USHORT)ulSzActual)) {
  425.       SELECTOROF(ptbhiInfo)=SELECTOROF(ptbhHeap->pvHeap);
  426. #endif
  427.       ptbhHeap->ulRef++;
  428.  
  429.       ptbhiInfo->ulSzRequested=ulSzBuf;
  430.  
  431.       *ppvBuf=(PVOID)(ptbhiInfo+1);
  432.       semAccess((PTBHEADER)htbmMem,usSemAction);
  433.       return TBMEM_EC_NOERROR;
  434.    } else {
  435.       semAccess((PTBHEADER)htbmMem,usSemAction);
  436.       return TBMEM_EC_NOMEMORY;
  437.    } /* endif */
  438. }
  439.  
  440. TBERROR MemFreeMem(HTBMEM htbmMem,PVOID pvBuf)
  441. //-------------------------------------------------------------------------
  442. // This function returns the memory to the specified memory handle.  It
  443. // assumes the memory was allocated using MemAllocMem().
  444. //
  445. // Input:  htbmMem - specifies the memory handle to return the memory
  446. //                   to
  447. //         pvBuf - pointer to the memory to free
  448. // Returns:  TBMEM_EC_* constant
  449. //-------------------------------------------------------------------------
  450. {
  451.    USHORT usSemAction;
  452.    USHORT usIndex;
  453.    PTBHEAPINFO ptbhiInfo;
  454.  
  455.    if (MemQueryHandle(htbmMem)!=TBMEM_QH_HTBMEM) {
  456.       return TBMEM_EC_BADHANDLE;
  457.    } /* endif */
  458.  
  459.    usSemAction=semAccess((PTBHEADER)htbmMem,TBSEM_SET);
  460.  
  461.    for (usIndex=0; usIndex<htbmMem->tbmiInfo.usNumHeaps; usIndex++) {
  462.       if (SELECTOROF(htbmMem->atbhHeaps[usIndex].pvHeap)==SELECTOROF(pvBuf)) {
  463.          ptbhiInfo=((PTBHEAPINFO)pvBuf)-1;
  464.  
  465. #ifdef _32BIT
  466.          if (DosSubFreeMem(htbmMem->atbhHeaps[usIndex].pvHeap,
  467.                            ptbhiInfo,
  468.                            SZACTUAL(ptbhiInfo->ulSzRequested))) {
  469. #else
  470.          if (DosSubFree(SELECTOROF(ptbhiInfo),
  471.                         OFFSETOF(ptbhiInfo),
  472.                         (USHORT)SZACTUAL(ptbhiInfo->ulSzRequested))) {
  473. #endif
  474.             semAccess((PTBHEADER)htbmMem,usSemAction);
  475.             return TBMEM_EC_ERROR;
  476.          } /* endif */
  477.  
  478.          htbmMem->atbhHeaps[usIndex].ulRef--;
  479.  
  480.          if (htbmMem->atbhHeaps[usIndex].ulRef==0) {
  481.             myFree(htbmMem->atbhHeaps[usIndex].pvHeap);
  482.             htbmMem->atbhHeaps[usIndex].pvHeap=NULL;
  483.          } /* endif */
  484.  
  485.          semAccess((PTBHEADER)htbmMem,usSemAction);
  486.          return TBMEM_EC_NOERROR;
  487.       } /* endif */
  488.    } /* endfor */
  489.  
  490.    semAccess((PTBHEADER)htbmMem,usSemAction);
  491.    return TBMEM_EC_BADPOINTER;
  492. }
  493.  
  494. ULONG MemQueryMemSize(PVOID pvBuf)
  495. //-------------------------------------------------------------------------
  496. // This function returns the size of the specified buffer.
  497. //
  498. // Input:  pvBuf - pointer to the buffer to query
  499. // Returns:  the size of the buffer
  500. //-------------------------------------------------------------------------
  501. {
  502.    PTBHEAPINFO ptbhiInfo;
  503.  
  504.    ptbhiInfo=((PTBHEAPINFO)pvBuf)-1;
  505.    return ptbhiInfo->ulSzRequested;
  506. }
  507.  
  508. USHORT MemQueryHandle(PVOID pvHandle)
  509. //-------------------------------------------------------------------------
  510. // This function returns the type of the specified handle, if known.
  511. //
  512. // Input:  pvHandle - pointer to the handle to query
  513. // Returns:  TBMEM_QH_* constant
  514. //-------------------------------------------------------------------------
  515. {
  516.    ULONG ulSig;
  517.  
  518.    if (pvHandle==NULL) {
  519.       return TBMEM_QH_ERROR;
  520.    } /* endif */
  521.  
  522.    ulSig=*((PULONG)pvHandle);
  523.  
  524.    if (ulSig==TBSIG_HTBMEM) {
  525.       return TBMEM_QH_HTBMEM;
  526.    } else {
  527.       return TBMEM_QH_ERROR;
  528.    } /* endif */
  529. }
  530.  
  531. TBERROR MemQueryHandleInfo(PVOID pvHandle,PVOID pvInfo)
  532. //-------------------------------------------------------------------------
  533. // This function returns information about the specified memory handle.
  534. //
  535. // Input:  pvHandle - specifies the memory handle to query
  536. //         pvInfo - pointer to a TBMEMINFO structure.  On return, this
  537. //                  contains the attributes of the memory handle
  538. // Returns:  TBMEM_EC_* constant
  539. //-------------------------------------------------------------------------
  540. {
  541.    switch (MemQueryHandle(pvHandle)) {
  542.    case TBMEM_QH_HTBMEM:
  543.       *((PTBMEMINFO)pvInfo)=((HTBMEM)pvHandle)->tbmiInfo;
  544.       break;
  545.    default:
  546.       return TBMEM_EC_BADHANDLE;
  547.    } /* endif */
  548.  
  549.    return TBMEM_EC_NOERROR;
  550. }
  551.  
  552. ---------------------------------------------------------
  553.  
  554. //-------------------------------------------------------------------------
  555. // Program name:  TBDEFS.H       Title:  Common toolbox header file
  556. // OS/2 Developer Magazine       Issue:  Spring '93, page 127
  557. //
  558. // Article:  "Writing Memory Allocation Functions With DosSubAllocMem"
  559. // Author:  Larry Salomon, Jr.
  560. // Phone:  n/a                   Fax:  n/a
  561. //
  562. // Description:  The following is a component of the complete source to the
  563. // above article in the specified issue of OS/2 Developer Magazine.  This
  564. // source is provided AS-IS without any implied or expressed warranty.  The
  565. // author can be contacted via the Internet at the email address
  566. // "os2man@panix.com".
  567. //
  568. // This component contains common definitions needed by the toolbox
  569. // described in this article and any toolboxes described in future
  570. // articles.
  571. //
  572. // Program requirements:  IBM C-Set/2 for 32-bit compilation, Microsoft
  573. // C 6.0 (or better) for 16-bit compilation.
  574. //-------------------------------------------------------------------------
  575. #ifndef TBDEFS_INCLUDED
  576. #define TBDEFS_INCLUDED
  577.  
  578. #ifndef OS2_INCLUDED
  579.  
  580. #ifdef _32BIT
  581. #define PASCAL
  582. #define FAR
  583. #else
  584. #define PASCAL pascal
  585. #define FAR far
  586. #endif                           /* #ifdef _32BIT */
  587.  
  588. #define APIENTRY PASCAL FAR
  589. #define EXPENTRY PASCAL FAR _loadds
  590. #define NULL 0L
  591.  
  592. typedef unsigned short BOOL;
  593. typedef unsigned char BYTE;
  594. typedef char CHAR;
  595. typedef short int SHORT;
  596. typedef long int LONG;
  597.  
  598. typedef unsigned char UCHAR;
  599. typedef unsigned short USHORT;
  600. typedef unsigned long ULONG;
  601.  
  602. typedef BOOL FAR *PBOOL;
  603. typedef BYTE FAR *PBYTE;
  604. typedef CHAR FAR *PCHAR;
  605. typedef SHORT FAR *PSHORT;
  606. typedef LONG FAR *PLONG;
  607.  
  608. typedef UCHAR  FAR *PUCHAR;
  609. typedef USHORT FAR *PUSHORT;
  610. typedef ULONG  FAR *PULONG;
  611.  
  612. #define VOID void
  613. typedef VOID FAR *PVOID;
  614. typedef VOID FAR *LHANDLE;
  615.  
  616. #endif                           /* #ifndef APIENTRY */
  617.  
  618. typedef ULONG TBERROR;
  619.  
  620. #endif                           /* #ifndef TBDEFS_INCLUDED */
  621.  
  622. ---------------------------------------------------------
  623.  
  624. //-------------------------------------------------------------------------
  625. // Program name:  TBMEM.H        Title:  Memory toolbox header file
  626. // OS/2 Developer Magazine       Issue:  Spring '93, page 127
  627. //
  628. // Article:  "Writing Memory Allocation Functions With DosSubAllocMem"
  629. // Author:  Larry Salomon, Jr.
  630. // Phone:  n/a                   Fax:  n/a
  631. //
  632. // Description:  The following is a component of the complete source to the
  633. // above article in the specified issue of OS/2 Developer Magazine.  This
  634. // source is provided AS-IS without any implied or expressed warranty.  The
  635. // author can be contacted via the Internet at the email address
  636. // "os2man@panix.com".
  637. //
  638. // This component contains definitions needed by the toolbox described
  639. // described in this article.  All data definitions are exposed, so a
  640. // separate, non-exposing header file should be used for applications
  641. // linking with the toolbox.
  642. //
  643. // Program requirements:  IBM C-Set/2 for 32-bit compilation, Microsoft
  644. // C 6.0 (or better) for 16-bit compilation.
  645. //-------------------------------------------------------------------------
  646. #include <tbdefs.h>
  647.  
  648. #define TBMEM_EC_NOERROR         (TBERROR)0
  649. #define TBMEM_EC_ERROR           (TBERROR)1
  650. #define TBMEM_EC_BADHANDLE       (TBERROR)2
  651. #define TBMEM_EC_NOMEMORY        (TBERROR)3
  652. #define TBMEM_EC_SIZETOOLARGE    (TBERROR)4
  653. #define TBMEM_EC_BADPOINTER      (TBERROR)5
  654. #define TBMEM_EC_INITFAILED      (TBERROR)6
  655.  
  656. typedef struct _TBMEMINFO {
  657.    USHORT usNumHeaps;
  658.    ULONG ulSzHeap;
  659. } TBMEMINFO, FAR *PTBMEMINFO;
  660.  
  661. typedef struct _TBHEAPINFO {
  662.    ULONG ulSzRequested;
  663. } TBHEAPINFO, FAR *PTBHEAPINFO;
  664.  
  665. typedef struct _TBHEAP {
  666.    ULONG ulRef;
  667.    PVOID pvHeap;
  668. } TBHEAP, FAR *PTBHEAP;
  669.  
  670. typedef struct _TBMEM {
  671.    ULONG ulSig;
  672.    ULONG ulStatus;
  673.    ULONG hsmAccess;
  674.    TBMEMINFO tbmiInfo;
  675.    TBHEAP atbhHeaps[1];
  676. } TBMEM, FAR *HTBMEM;
  677. typedef HTBMEM FAR *PHTBMEM;
  678.  
  679. TBERROR MemInitialize(PTBMEMINFO ptbmiInfo,PHTBMEM phtbmMem);
  680. TBERROR MemTerminate(HTBMEM htbmMem);
  681. TBERROR MemReset(HTBMEM htbmMem);
  682. TBERROR MemAllocMem(HTBMEM htbmMem,ULONG ulSzBuf,PVOID *ppvBuf);
  683. TBERROR MemFreeMem(HTBMEM htbmMem,PVOID pvBuf);
  684. ULONG MemQueryMemSize(PVOID pvBuf);
  685.  
  686. #define TBMEM_QH_ERROR           (USHORT)0
  687. #define TBMEM_QH_HTBMEM          (USHORT)1
  688.  
  689. USHORT MemQueryHandle(PVOID pvHandle);
  690. TBERROR MemQueryHandleInfo(PVOID pvHandle,PVOID pvInfo);
  691.  
  692. ---------------------------------------------------------
  693.  
  694. .*-------------------------------------------------------------------------
  695. .* Program name:  TBMEM.IPF      Title:  Memory toolbox programming
  696. .*                                       reference source
  697. .* OS/2 Developer Magazine       Issue:  Spring '93, page 127
  698. .*
  699. .* Article:  "Writing Memory Allocation Functions With DosSubAllocMem"
  700. .* Author:  Larry Salomon, Jr.
  701. .* Phone:  n/a                   Fax:  n/a
  702. .*
  703. .* Description:  The following is a component of the complete source to the
  704. .* above article in the specified issue of OS/2 Developer Magazine.  This
  705. .* source is provided AS-IS without any implied or expressed warranty.  The
  706. .* author can be contacted via the Internet at the email address
  707. .* "os2man@panix.com".
  708. .*
  709. .* This component contains the source - in .IPF format - for the programming
  710. .* reference.
  711. .*
  712. .* Program requirements:  IPFC from either the 1.3 or 2.0 toolkit
  713. .*-------------------------------------------------------------------------
  714. :userdoc.
  715. :title.Memory Toolbox Programming Reference
  716. :body.
  717. :h1.Introduction
  718. :p.The :hp2.Memory Toolbox:ehp2. (referred to as :hp2.TBMEM:ehp2.) is a
  719. collection of routines that provide memory-related functions for an OS/2
  720. application.  In addition to the standard allocation and free functions, other
  721. API are included which perform other tasks.  Although the API set is not
  722. &odq.standardized&cdq. or as complete as the C run-time library, there are a
  723. few reasons that you should consider when deciding which to use&colon.
  724. :ul compact.
  725. :li.It is completely thread reentrant.  No longer do you have to fumble with
  726. two sets of include files and libraries.
  727. :li.It is as fast as, or faster than, the C run-time library.
  728. :li.It reads better that the C run-time calls, which makes for easier program
  729. maintenance.
  730. :eul.
  731. :p.Granted, these are not convincing arguments that compel you to switch to
  732. the toolbox, but I believe they are sufficient to warrant further
  733. investigation.
  734. :p.:hp2.Using the Toolbox:ehp2.
  735. :p.To enable your application to use the toolbox, include the
  736. :hp2.TBMEM.H:ehp2. header file in the appropriate source file(s) and link with
  737. the :hp2.TBMEM16.LIB:ehp2. library that is also provided.
  738. :h1.API Reference
  739. :p.The following sections describe each of the following API in detail.  To
  740. view a particular section, double click on the corresponding API listed
  741. below.
  742. :ul compact.
  743. :li.:link reftype=hd refid=MAM.MemAllocMem:elink.
  744. :li.:link reftype=hd refid=MFM.MemFreeMem:elink.
  745. :li.:link reftype=hd refid=MI.MemInitialize:elink.
  746. :li.:link reftype=hd refid=MQH.MemQueryHandle:elink.
  747. :li.:link reftype=hd refid=MQHI.MemQueryHandleInfo:elink.
  748. :li.:link reftype=hd refid=MQMS.MemQueryMemSize:elink.
  749. :li.:link reftype=hd refid=MR.MemReset:elink.
  750. :li.:link reftype=hd refid=MT.MemTerminate:elink.
  751. :eul.
  752. :h2 id=MAM.MemAllocMem
  753. :p.Allocates a block of memory of a specified size.
  754. :xmp.
  755. (TBERROR)MemAllocMem(HTBMEM htbmMem,ULONG ulSzBuf,PVOID *ppvBuf);
  756. :exmp.
  757. :dl tsize=30 compact.
  758. :dt.htbmMem (Input)
  759. :dd.TBMEM instance handle
  760. :dt.ulSzBuf (Input)
  761. :dd.Size of the memory block requested
  762. :dt.ppvBuf (Output)
  763. :dd.Points to the resulting memory block that was allocated
  764. :edl.
  765. :p.:hp2.MemAllocMem:ehp2. returns one of the following values&colon.
  766. :sl compact.
  767. :li.TBMEM_EC_NOERROR
  768. :li.TBMEM_EC_BADHANDLE
  769. :li.TBMEM_EC_NOMEMORY
  770. :li.TBMEM_EC_SIZETOOLARGE
  771. :esl.
  772. :p.:hp2.Notes:ehp2.
  773. :p.The algorithm used by the toolbox is to attempt to allocate the specified
  774. amount of memory from those heaps which already are associated with a memory
  775. selector.  If the request cannot be satisfied :hp2.and:ehp2. there is at
  776. least one heap that is not in use, then a new selector is allocated by the
  777. toolbox and the memory requested is allocated from that.
  778. :h2 id=MFM.MemFreeMem
  779. :p.Frees a block of memory previously allocated with MemAllocMem.
  780. :xmp.
  781. (TBERROR)MemFreeMem(HTBMEM htbmMem,PVOID pvBuf);
  782. :exmp.
  783. :dl tsize=30 compact.
  784. :dt.htbmMem (Input)
  785. :dd.TBMEM instance handle
  786. :dt.pvBuf (Output)
  787. :dd.Pointer to the memory block to return to the system
  788. :edl.
  789. :p.:hp2.MemFreeMem:ehp2. returns one of the following values&colon.
  790. :sl compact.
  791. :li.TBMEM_EC_NOERROR
  792. :li.TBMEM_EC_BADHANDLE
  793. :li.TBMEM_EC_BADPOINTER
  794. :li.TBMEM_EC_ERROR
  795. :esl.
  796. :p.:hp2.Notes:ehp2.
  797. :p.Because of the toolbox&apos.s dynamic committal strategy, a reference count
  798. is maintained for each heap that is in use and it is updated whenever either
  799. :hp2.MemAllocMem:ehp2. or :hp2.MemFreeMem:ehp2. is called.  When this function
  800. determines that the reference count is zero, it returns the memory back to the
  801. system.
  802. :h2 id=MI.MemInitialize
  803. :p.Initializes an instance of the Memory Toolbox.
  804. :xmp.
  805. (TBERROR)MemInitialize(PTBMEMINFO ptbmiInfo,PHTBMEM phtbmMem);
  806. :exmp.
  807. :dl tsize=30 compact.
  808. :dt.ptbmiInfo (Input)
  809. :dd.Pointer to a :hp2.TBMEMINFO:ehp2. structure which describes the
  810. desired characteristics of the instance to be created.  If :hp2.NULL:ehp2.,
  811. the defaults are used.
  812. :dt.phtbmMem (Output)
  813. :dd.Points to the resulting instance that was created.
  814. :edl.
  815. :p.:hp2.MemInitialize:ehp2. returns one of the following values&colon.
  816. :sl compact.
  817. :li.TBMEM_EC_NOERROR
  818. :li.TBMEM_EC_NOMEMORY
  819. :esl.
  820. :p.:hp2.Notes:ehp2.
  821. :p.The :hp2.TBMEMINFO:ehp2. structure is described below&colon.
  822. :xmp.
  823. typedef struct _TBMEMINFO &lbrc.
  824.    USHORT usNumHeaps;
  825.    ULONG ulSzHeap;
  826. &rbrc. TBMEMINFO, FAR *PTBMEMINFO;
  827. :exmp.
  828. :dl tsize=20 compact.
  829. :dt.usNumHeaps
  830. :dd.Contains the number of internal heaps to be used by the toolkit.  The
  831. default for the 16-bit version of the toolbox is 256.
  832. :dt.ulSzHeaps
  833. :dd.Contains the size of each heap.  The default for the 16-bit version of the
  834. toolbox is 61440.
  835. :edl.
  836. :p.The heaps are subdivided (via calls to :hp2.MemAllocMem:ehp2. and
  837. :hp2.MemFreeMem:ehp2.) using the :hp2.DosSubAlloc:ehp2. and
  838. :hp2.DosSubFree:ehp2. API.  Allowing for housekeeping data kept by both the
  839. system and the toolbox, the amount of allocatable memory will be less than the
  840. value of :hp1.ulSzHeaps:ehp1. (how much less depends on the number of
  841. allocations have been made from a particular heap).
  842. :h2 id=MQH.MemQueryHandle
  843. :p.Returns the type of the specified handle.
  844. :xmp.
  845. (USHORT)MemQueryHandle(LHANDLE lhHandle);
  846. :exmp.
  847. :dl tsize=30 compact.
  848. :dt.lhHandle (Input)
  849. :dd.Specifies the handle to check
  850. :edl.
  851. :p.:hp2.MemQueryHandle:ehp2. returns one of the following values&colon.
  852. :sl compact.
  853. :li.TBMEM_QH_HTBMEM
  854. :li.TBMEM_QH_ERROR
  855. :esl.
  856. :p.:hp2.Notes:ehp2.
  857. :p.This function does not validate the accessability of the memory pointed to
  858. by :hp1.lhHandle:ehp1..  Thus, a value that contains an invalid selector will
  859. cause the application to trap.
  860. :h2 id=MQHI.MemQueryHandleInfo
  861. :p.Returns information about the specified handle.
  862. :xmp.
  863. (TBERROR)MemQueryHandleInfo(LHANDLE lhHandle,PVOID pvInfo);
  864. :exmp.
  865. :dl tsize=30 compact.
  866. :dt.lhHandle (Input)
  867. :dd.Specifies the handle to check
  868. :dt.pvInfo (Input/Output)
  869. :dd.On entry, points to a handle-specific structure to be initialized.  On
  870. exit, points to the initialized structure.
  871. :edl.
  872. :p.:hp2.MemQueryHandleInfo:ehp2. returns one of the following values&colon.
  873. :sl compact.
  874. :li.TBMEM_EC_NOERROR
  875. :li.TBMEM_EC_BADHANDLE
  876. :esl.
  877. :p.:hp2.Notes:ehp2.
  878. :p.What :hp1.pvInfo:ehp1. points to depends on the type of the handle
  879. specified.  Although in this toolbox there is only one handle type, there
  880. might be other toolboxes which contain several handle types; thus, this
  881. convention for obtaining handle information is established now to avoid
  882. problems in the future.
  883. :dl tsize=30 compact.
  884. :dthd.Handle type
  885. :ddhd.Info buffer type
  886. :dt.HTBMEM
  887. :dd.pvInfo should point to a TBMEMINFO structure
  888. :edl.
  889. :h2 id=MQMS.MemQueryMemSize
  890. :p.Returns the size of the specified memory block
  891. :xmp.
  892. (ULONG)MemQueryMemSize(PVOID pvBuf);
  893. :exmp.
  894. :dl tsize=30 compact.
  895. :dt.pvBuf (Input)
  896. :dd.Points to a memory block previously allocated by :hp2.MemAllocMem:ehp2.
  897. :edl.
  898. :p.:hp2.MemQueryMemSize:ehp2. returns the size of the memory block specified.
  899. :p.:hp2.Notes:ehp2.
  900. :p.This function does no validity checks to insure that :hp1.pvBuf:ehp1. was
  901. indeed allocated with :hp2.MemAllocMem:ehp2..
  902. :h2 id=MR.MemReset
  903. :p.Resets the specified instance of the Memory Toolbox to its starting state.
  904. :xmp.
  905. (TBERROR)MemReset(HTBMEM htbmMem);
  906. :exmp.
  907. :dl tsize=30 compact.
  908. :dt.htbmMem (Input)
  909. :dd.TBMEM instance handle
  910. :edl.
  911. :p.:hp2.MemReset:ehp2. returns one of the following values&colon.
  912. :sl compact.
  913. :li.TBMEM_EC_NOERROR
  914. :li.TBMEM_EC_BADHANDLE
  915. :esl.
  916. :p.:hp2.Notes:ehp2.
  917. :p.This function returns :hp2.all:ehp2. memory to the system and reinitializes
  918. all of the internal heaps to their stating state.
  919. :h2 id=MT.MemTerminate
  920. :p.Terminates the specified instance of the Memory Toolbox.
  921. :xmp.
  922. (TBERROR)MemTerminate(HTBMEM htbmMem);
  923. :exmp.
  924. :dl tsize=30 compact.
  925. :dt.htbmMem (Input)
  926. :dd.TBMEM instance handle
  927. :edl.
  928. :p.:hp2.MemTerminate:ehp2. returns one of the following values&colon.
  929. :sl compact.
  930. :li.TBMEM_EC_NOERROR
  931. :li.TBMEM_EC_BADHANDLE
  932. :li.TBMEM_EC_ERROR
  933. :esl.
  934. :p.:hp2.Notes:ehp2.
  935. :p.This function first calls :hp2.MemReset:ehp2. to return all allocated
  936. memory to the system.
  937. :euserdoc.
  938.  
  939. ---------------------------------------------------------
  940.  
  941. #--------------------------------------------------------------------------
  942. # Program name:  TEST.MAK       Title:  Memory toolbox make file
  943. # OS/2 Developer Magazine       Issue:  Spring '93, page 127
  944. #
  945. # Article:  "Writing Memory Allocation Functions With DosSubAllocMem"
  946. # Author:  Larry Salomon, Jr.
  947. # Phone:  n/a                   Fax:  n/a
  948. #
  949. # Description:  The following is a component of the complete source to the
  950. # above article in the specified issue of OS/2 Developer Magazine.  This
  951. # source is provided AS-IS without any implied or expressed warranty.  The
  952. # author can be contacted via the Internet at the email address
  953. # "os2man@panix.com".
  954. #
  955. # This component contains the make file needed to build the memory
  956. # toolbox test file. To build the 32-bit version, type "nmake 32bit TEST=MEM"
  957. # on any OS/2 command line.  To build the 16-bit version, type
  958. # "nmake 16bit TEST=MEM" on any OS/2 command line.
  959. #
  960. # Program requirements:  IBM C-Set/2 for 32-bit compilation, Microsoft
  961. # C 6.0 (or better) for 16-bit compilation.
  962. #--------------------------------------------------------------------------
  963.  
  964. !IFNDEF TEST
  965. !ERROR You must define TEST!
  966. !ENDIF
  967.  
  968. 32BIT:
  969.         NMAKE SUFFIX=32 $(TEST)32.EXE
  970.  
  971. 16BIT:
  972.         NMAKE SUFFIX=16 $(TEST)16.EXE
  973.  
  974. !IF "$(SUFFIX)"=="32"
  975. CLOPTS=-C+ -Kb+ -Ss+ -W3 -D_32BIT
  976. LINKOPTS=/MAP
  977.  
  978. !IFDEF DEBUG
  979. CLOPTS=$(CLOPTS) -Ti+
  980. LINKOPTS=$(LINKOPTS) /CO
  981. !ENDIF
  982.  
  983. CLEXE=ICC
  984. LINKEXE=LINK386
  985. OS2LIB=OS2386
  986. !ELSE
  987. CLOPTS=-c -AL -W4 -G2 -D_16BIT
  988. LINKOPTS=/MAP
  989.  
  990. !IFDEF DEBUG
  991. CLOPTS=$(CLOPTS) -Zipde -Od
  992. LINKOPTS=$(LINKOPTS) /CO
  993. !ELSE
  994. CLOPTS=$(CLOPTS) -Zpe -Ol
  995. !ENDIF
  996.  
  997. CLEXE=CL
  998. LINKEXE=LINK
  999. OS2LIB=OS2
  1000. !ENDIF
  1001.  
  1002. $(TEST)$(SUFFIX).EXE:           $(TEST)$(SUFFIX).OBJ
  1003.         ECHO NAME $(TEST)$(SUFFIX) > TEST.DEF
  1004.         TYPE TESTEND.DEF >> TEST.DEF
  1005.         $(LINKEXE) $(LINKOPTS) @<<
  1006. $(TEST)$(SUFFIX)
  1007. $(TEST)$(SUFFIX)
  1008. $(TEST)$(SUFFIX)
  1009. $(OS2LIB)+TBMEM$(SUFFIX)
  1010. TEST
  1011. <<
  1012.  
  1013. $(TEST)$(SUFFIX).OBJ:           $(TEST).C
  1014.         $(CLEXE) $(CLOPTS) -Fo$(TEST)$(SUFFIX) $(TEST).C
  1015.  
  1016. ---------------------------------------------------------
  1017.  
  1018. //-------------------------------------------------------------------------
  1019. // Program name:  MEM.C          Title:  Memory toolbox test application
  1020. // OS/2 Developer Magazine       Issue:  Spring '93, page 127
  1021. //
  1022. // Article:  "Writing Memory Allocation Functions With DosSubAllocMem"
  1023. // Author:  Larry Salomon, Jr.
  1024. // Phone:  n/a                   Fax:  n/a
  1025. //
  1026. // Description:  The following is a component of the complete source to the
  1027. // above article in the specified issue of OS/2 Developer Magazine.  This
  1028. // source is provided AS-IS without any implied or expressed warranty.  The
  1029. // author can be contacted via the Internet at the email address
  1030. // "os2man@panix.com".
  1031. //
  1032. // This component contains a program written to test the TBMEM library.
  1033. // It iterates 200 times through a loop which picks a random number and,
  1034. // if the pointer stored at that index in an array is NULL, allocates a
  1035. // 30000 byte block of memory.  If the pointer stored is not NULL, it
  1036. // calls MemQueryMemSize() and compares the result with the size stored
  1037. // on the allocation call.  It then calls MemFree().
  1038. //
  1039. // Program requirements:  IBM C-Set/2 for 32-bit compilation, Microsoft
  1040. // C 6.0 (or better) for 16-bit compilation.
  1041. //-------------------------------------------------------------------------
  1042. #include <tbmem.h>
  1043. #include <stdio.h>
  1044. #include <string.h>
  1045. #include <stdlib.h>
  1046.  
  1047. #define MAX_INFO                 100
  1048.  
  1049. typedef struct {
  1050.    ULONG ulSzBuf;
  1051.    PVOID pvBuf;
  1052. } MEMINFO, FAR *PMEMINFO;
  1053.  
  1054. MEMINFO amiInfo[MAX_INFO];
  1055.  
  1056. VOID main(USHORT usArgs,PCHAR apchArgs[])
  1057. {
  1058.    HTBMEM htbmMem;
  1059.    USHORT usSeed;
  1060.    USHORT usIndex;
  1061.  
  1062.    if (usArgs==1) {
  1063.       puts("Syntax: MEM1 seed");
  1064.       return;
  1065.    } /* endif */
  1066.  
  1067.    memset(amiInfo,0,sizeof(amiInfo));
  1068.    srand(atoi(apchArgs[1]));
  1069.    usSeed=rand()%MAX_INFO;
  1070.  
  1071.    if (MemInitialize(NULL,&htbmMem)!=TBMEM_EC_NOERROR) {
  1072.       printf("\nInitialize error.\n");
  1073.       return;
  1074.    } /* endif */
  1075.  
  1076.    printf("Testing memory allocation/free.  Using starting slot %d.\n\n",
  1077.           usSeed);
  1078.  
  1079.    for (usIndex=0; usIndex<200; usIndex++) {
  1080.       printf("Slot=%3d, ",usSeed);
  1081.  
  1082.       if (amiInfo[usSeed].pvBuf==NULL) {
  1083.          amiInfo[usSeed].ulSzBuf=30000;
  1084.  
  1085.          if (MemAllocMem(htbmMem,
  1086.                          amiInfo[usSeed].ulSzBuf,
  1087.                          &amiInfo[usSeed].pvBuf)!=TBMEM_EC_NOERROR) {
  1088.             printf("allocation error.\n");
  1089.          } else {
  1090.             printf("allocation successful.\n");
  1091.          } /* endif */
  1092.       } else {
  1093.          if (MemQueryMemSize(amiInfo[usSeed].pvBuf)!=amiInfo[usSeed].ulSzBuf) {
  1094.             printf("verify error.\n");
  1095.          } else
  1096.          if (MemFreeMem(htbmMem,amiInfo[usSeed].pvBuf)!=TBMEM_EC_NOERROR) {
  1097.             printf("free error.\n");
  1098.          } else {
  1099.             amiInfo[usSeed].pvBuf=NULL;
  1100.             printf("verify and free successful.\n");
  1101.          } /* endif */
  1102.       } /* endif */
  1103.  
  1104.       usSeed=rand()%MAX_INFO;
  1105.    } /* endfor */
  1106.  
  1107.    if (MemTerminate(htbmMem)!=TBMEM_EC_NOERROR) {
  1108.       printf("\nTermination error.\n");
  1109.    } /* endif */
  1110. }
  1111.  
  1112. ---------------------------------------------------------
  1113.  
  1114. ;--------------------------------------------------------------------------
  1115. ; Program name:  TESTEND.DEF    Title:  Memory toolbox test application
  1116. ; OS/2 Developer Magazine       Issue:  Spring '93, page 127
  1117. ;
  1118. ; Article:  "Writing Memory Allocation Functions With DosSubAllocMem"
  1119. ; Author:  Larry Salomon, Jr.
  1120. ; Phone:  n/a                   Fax:  n/a
  1121. ;
  1122. ; Description:  The following is a component of the complete source to the
  1123. ; above article in the specified issue of OS/2 Developer Magazine.  This
  1124. ; source is provided AS-IS without any implied or expressed warranty.  The
  1125. ; author can be contacted via the Internet at the email address
  1126. ; "os2man@panix.com".
  1127. ;
  1128. ; This component contains the tail of the module definition file used
  1129. ; by the toolbox test programs.  The NAME statement is prepended by the
  1130. ; TEST.MAK makefile.
  1131. ;
  1132. ; Program requirements:  IBM C-Set/2 for 32-bit compilation, Microsoft
  1133. ; C 6.0 (or better) for 16-bit compilation.
  1134. ;--------------------------------------------------------------------------
  1135. DESCRIPTION 'Test program for a toolbox component
  1136. Written by Larry Salomon, Jr.
  1137. All rights reserved.'
  1138.  
  1139. PROTMODE
  1140. STACKSIZE 0x8000
  1141.