home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / S12405.ZIP / HUGE.C next >
C/C++ Source or Header  |  1989-08-29  |  9KB  |  232 lines

  1. /*
  2.  * 
  3.  *  HUGE.C -- demonstrate OS/2 huge memory usage
  4.  *  
  5.  *  This example illustrates allocating a huge segment, addressing
  6.  *  the segment (it accesses each selector in the huge segment), and
  7.  *  how to manually determine the huge segment shift factor. The
  8.  *  following OS/2 APIs are illustrated here:
  9.  *  
  10.  *      DosGetInfoSeg()
  11.  *      DosGetHugeShift()
  12.  *      DosAllocHuge()
  13.  *      DosFreeSeg()
  14.  *  
  15.  *  This example allocates a huge segment. It writes a value to all
  16.  *  bytes in all segments of the huge segment. Then it checks if all
  17.  *  bytes in all segments contain the value that was written
  18.  *  previously. It then frees the huge segment and exits. This
  19.  *  example is intended to show how to manage and access huge
  20.  *  segments - it doesn't perform any useful function.
  21.  *  
  22.  *  If macro USE_HUGE_KEYWORD is #defined, then the Microsoft
  23.  *  C compiler 5.1's "huge" keyword will be used to tell the C
  24.  *  compiler to generate code to calculate "jumps" between the huge
  25.  *  segments. This will simplify the applications's code required
  26.  *  (and the compiler will generate the code at a lower level). If
  27.  *  this macro is not #defined, then the code will not use this code
  28.  *  generation ability of the language and will instead manually
  29.  *  calculate the jumps.
  30.  *  
  31.  *  Note that the "huge" keyword, while supported by some other DOS 
  32.  *  and OS/2 C compilers, is not standard C language keyword. Also,
  33.  *  for informative use only, this code uses Microsoft C #pragmas, 
  34.  *  which may not be implemented on other C compilers.
  35.  *  
  36.  *  To compile this program, type:  cl /W3 /AL /Lp /G2 huge.c
  37.  *  
  38.  *  Copyright (C) 1989 Microsoft Corporation 
  39.  *  
  40.  *  This software is provided for demonstration purposes only.
  41.  *  Microsoft makes no warranty, either express or implied as 
  42.  *  to its usability in any given situation.
  43.  *  
  44.  */
  45.  
  46. /* ------------------------------------------------------------------------ */
  47.  
  48. /* compile-time build options */
  49.  
  50. /* allow C to use 'huge' keyword */
  51. /* #define USE_HUGE_KEYWORD */
  52.  
  53. /* let the builder know how the sources are being compiled */
  54.  
  55. #ifdef USE_HUGE_KEYWORD
  56.     #pragma message("fyi: compiling WITH support for C 'huge' keyword")
  57. #else
  58.     #pragma message("fyi: compiling withOUT support for C 'huge' keyword")
  59. #endif
  60.  
  61. /* ------------------------------------------------------------------------ */
  62.  
  63. /* include files */
  64.  
  65. #define INCL_DOS
  66. #define INCL_DOSMEMMGR
  67. #include <os2.h>
  68.  
  69. #include <stdio.h>           /* for printf() */
  70. #include <stdlib.h>          /* for exit() */
  71.  
  72. /* ------------------------------------------------------------------------ */
  73.  
  74. /* function prototypes */
  75.  
  76. INT main(void);
  77. void TestError(USHORT usError, PSZ pszApiName);
  78.  
  79. /* ------------------------------------------------------------------------ */
  80.  
  81. /* constants */
  82.  
  83. #define MAX_SEGS     3       /* maximum number of huge segments (arbitrary) */
  84. #define TEST_DATA   42       /* byte-sized data for test (arbitrary) */
  85. #define PART_SEG     0       /* no partial segment */
  86. #define MAX_SEGSIZE  0xFFFF  /* max size of an OS/2 1.XX segment (65KB) */
  87.  
  88. /* ------------------------------------------------------------------------ */
  89.  
  90. /* the main program */
  91.  
  92. INT main(void)
  93. {
  94.  
  95.     SEL sel;                 /* selector */
  96.     USHORT usError;          /* API return code */
  97. #ifdef USE_HUGE_KEYWORD
  98.     CHAR huge *fpchBuffer;   /* pointer to a huge segment */
  99.     CHAR huge *fpchFirstSeg; /* pointer to the first huge segment selector */
  100.     LONG j;                  /* segment offset loop index */
  101. #else
  102.     USHORT usHugeShift;      /* huge memory model shift count */
  103.     USHORT usAltHugeShift;   /* huge shift count from GINFOSEG */
  104.     USHORT usHugeIncrement;  /* the huge segment increment value */
  105.     SEL selGlobalSeg;        /* GDT selector */
  106.     SEL selLocalSeg;         /* LDT selector */
  107.     GINFOSEG FAR *pgis;      /* far pointer to GINFOSEG structure */
  108.     CHAR far *fpchBuffer;    /* pointer to a huge segment */
  109.     CHAR far *fpchFirstSeg;  /* pointer to the first huge segment selector */
  110.     INT i;                   /* huge segment loop index */
  111.     INT j;                   /* segment offset loop index */
  112. #endif /* USE_HUGE_KEYWORD */
  113.  
  114. #ifndef USE_HUGE_KEYWORD
  115.     /* get and display the huge shift count (DosGetHugeShift method) */
  116.     printf("computing huge shift count value...\n");
  117.     usError = DosGetHugeShift(&usHugeShift);
  118.     TestError(usError, "DosGetHugeShift");
  119.     printf("DosGetHugeShift() reports huge shift count = %d\n", usHugeShift);
  120.  
  121.     /* get and display the huge shift count (GINFOSEG.cHugeShift method) */
  122.     usError = DosGetInfoSeg(&selGlobalSeg, &selLocalSeg);
  123.     TestError(usError, "DosGetInfoSeg");
  124.     pgis = MAKEPGINFOSEG(selGlobalSeg);
  125.     usAltHugeShift = pgis->cHugeShift;
  126.  
  127.     /* verify that both huge shift counts are the same */
  128.     if (usAltHugeShift != usAltHugeShift)
  129.     {
  130.         printf("DosGetInfoSeg() reports huge shift count = %d\n", 
  131.             usAltHugeShift);
  132.         printf("error: the shift counts from both methods don't agree!\n");
  133.         exit(1);
  134.     }
  135. #endif /* USE_HUGE_KEYWORD */
  136.  
  137.     /* allocate a huge segment */
  138.     printf("allocating huge segment (%d selectors)...\n", MAX_SEGS);
  139.     usError = DosAllocHuge(MAX_SEGS, PART_SEG, &sel, MAX_SEGS, SEG_NONSHARED);
  140.     TestError(usError, "DosAllocHuge");
  141.  
  142.     /* compute the address to the first huge segment */
  143.     printf("computing address to the first huge segment...\n");
  144.     fpchFirstSeg = MAKEP(sel, 0);
  145.     fpchBuffer = MAKEP(sel, 0);
  146.     printf("pointer to first segment = %04X\n", fpchFirstSeg);
  147.  
  148. #ifndef USE_HUGE_KEYWORD
  149.     /* compute the huge segment shift value */
  150.     usHugeIncrement = 1 << usHugeShift;
  151.     printf("the huge segment increment value is %d\n", usHugeIncrement);
  152. #endif /* USE_HUGE_KEYWORD */
  153.  
  154.     /* data write verification test */
  155.     printf("writing test data to segments...\n");
  156. #ifdef USE_HUGE_KEYWORD
  157.     /* loop through each byte in meta-huge segment */
  158.     printf("loop through %lu bytes...\n", (LONG)(MAX_SEGS * MAX_SEGSIZE));
  159.     for (j = 0L; j < (LONG)(MAX_SEGS * MAX_SEGSIZE); j++)
  160.     {
  161.         fpchBuffer[j] = TEST_DATA; /* test writing to segment */
  162.     }
  163.     printf("%lu bytes written\n", (LONG)(MAX_SEGS * MAX_SEGSIZE));
  164. #else
  165.     /* loop through each selector in huge segment */
  166.     for (fpchBuffer = fpchFirstSeg, i = 0; i < MAX_SEGS; i++)
  167.     {
  168.         fpchBuffer += usHugeIncrement;
  169.         printf("writing to selector #%d (%04Xh)...\n", i, fpchBuffer);
  170.         /* loop through each byte in current selector */
  171.         for (j = 0; j < MAX_SEGSIZE; j++)
  172.         {
  173.             fpchBuffer[j] = TEST_DATA; /* test writing to segment */
  174.         }
  175.     }
  176. #endif /* USE_HUGE_KEYWORD */
  177.  
  178.     /* data read verification test */
  179.     printf("reading test data back from the segments...\n");
  180. #ifdef USE_HUGE_KEYWORD
  181.     /* loop through each byte in meta-huge segment */
  182.     for (j = 0L; j < (LONG)(MAX_SEGS * MAX_SEGSIZE); j++)
  183.     {
  184.         if (fpchBuffer[j] != TEST_DATA) /* test reading from segment */
  185.         {
  186.             printf("error: unexpected value in huge segment!\n");
  187.         }
  188.     }
  189.     printf("%lu bytes read\n", (LONG)(MAX_SEGS * MAX_SEGSIZE));
  190. #else
  191.     /* loop through each selector in huge segment */
  192.     for (fpchBuffer = fpchFirstSeg, i = 0; i < MAX_SEGS; i++)
  193.     {
  194.         fpchBuffer += usHugeIncrement;
  195.         printf("reading from selector #%d (%04Xh)...\n", i, fpchBuffer);
  196.         /* loop through each byte in current selector */
  197.         for (j = 0; j < MAX_SEGSIZE; j++)
  198.         {
  199.             if (fpchBuffer[j] != TEST_DATA) /* test reading from segment */
  200.             {
  201.                 printf("error: unexpected value in huge segment!\n");
  202.             }
  203.         }
  204.     }
  205. #endif /* USE_HUGE_KEYWORD */
  206.  
  207.     /* free the huge segment */
  208.     usError = DosFreeSeg(sel);
  209.     TestError(usError, "DosFreeSeg");
  210.  
  211.     exit(0);
  212.     return (0);
  213.  
  214. } /* main */
  215.  
  216. /* ------------------------------------------------------------------------ */
  217.  
  218. /* test an OS/2 API return code; choke and die if unsuccessful */
  219.  
  220. void TestError(USHORT usError, PSZ pszApi)
  221. {
  222.  
  223.     if (usError)
  224.     {
  225.         printf("error: %s() returned error code %u!\n", pszApi, usError);
  226.         exit(1);
  227.     }
  228.  
  229. } /* TestError */
  230.  
  231. /* ------------------------------------------------------------------------ */
  232.