Annotation of mstools/samples/rpc/mandel/remote.c, revision 1.1.1.3

1.1       root        1: /*
                      2:  *  REMOTE.C --
                      3:  *
                      4:  *  Code to do the remote calculations for the Windows Mandelbrot Set
                      5:  *  distributed drawing program.
                      6:  *
1.1.1.2   root        7:  *  Copyright (C) 1990, 1992 Microsoft Corporation.
1.1       root        8:  *
                      9:  *  Information coming into this module (via API calls) is based on
                     10:  *  upper-left being (0,0) (the Windows standard). We translate that
1.1.1.2   root       11:  *  to lower-left is (0,0) before we ship it out onto
1.1       root       12:  *  the net, and we do reverse translations accordingly.
                     13:  *
                     14:  *  The iteration data is passed back to the main window procedure
                     15:  *  (by means of a WM_PAINTLINE message) which draws the picture.
                     16:  *
                     17:  *  A word about the shared buffer: multiple buffers could be used, but
                     18:  *  a single one is used. The buffer is requested in this code, and
                     19:  *  then released after the data has been drawn (in PaintLine() in
                     20:  *  mandel.c). So long as the painting is done quickly, this is efficient.
                     21:  *
                     22:  *  This code sample is provided for demonstration purposes only.
                     23:  *  Microsoft makes no warranty, either express or implied,
                     24:  *  as to its usability in any given situation.
                     25:  */
                     26: 
                     27: 
                     28: #include <string.h>
                     29: #include <stdio.h>
                     30: #include <fcntl.h>
                     31: #include <sys\types.h>
                     32: #include <sys\stat.h>
                     33: #include <share.h>
                     34: #include <io.h>
                     35: #include <malloc.h>
                     36: 
                     37: #include <windows.h>
                     38: 
                     39: #ifdef RPC
                     40: #include <rpc.h>
                     41: #include "mdlrpc.h"
                     42: #endif
                     43: #include "mandel.h"
1.1.1.2   root       44: 
1.1       root       45: /*
1.1.1.2   root       46:  * Tuning parameters
1.1       root       47:  */
                     48: #define SVR_TABLE_SZ        20
                     49: #define MAX_PIPENAME_SZ     CCHMAXPATH
                     50: 
                     51: 
                     52: /*
                     53:  * Manifests, to keep everything neat.
                     54:  */
                     55: 
                     56: extern int errno;           // errno from c runtime
                     57: 
                     58: /*
                     59:  * Data structures
                     60:  */
                     61: extern svr_table    SvrTable[]; // the table
                     62: extern int          SvrTableSz;         // # of objects in it
                     63: char pszFail[255];
                     64: 
                     65: 
                     66: // Do we do local work?
                     67: BOOL    fLocalWork = TRUE;
                     68: BOOL    fRemoteWork = FALSE;
                     69: 
                     70: static int fDisplay = TRUE; /* display a message box for debug */
                     71: 
                     72: // Picture information
                     73: 
                     74:        int      cPictureID = 0;     // picture id, in case we reset in the middle
                     75: static CPOINT   cptLL;              // upper-left
                     76: static double   dPrecision;         // precision of draw
                     77: static LONGRECT    rclPicture;        // rectangle defining client window
                     78: static DWORD    dwCurrentLine;      // next line to be drawn
                     79: static DWORD    dwThreshold;        // threshold for iterations
                     80: 
                     81: 
                     82: static char szLocal[] = "Local machine";
                     83: #ifdef RPC
                     84: RPC_STATUS status;            // returned by RPC API function
                     85: #endif
                     86: /*
                     87:  * function prototypes for local procs
                     88:  */
                     89: 
                     90: DWORD CalcThreshold( double );
                     91: 
                     92: 
                     93: 
                     94: /*
                     95:  *  InitRemote --
                     96:  *
                     97:  *  This function initializes everything for our remote connections.
                     98:  *  It gets the local wksta name (making sure the wksta is started)
                     99:  *  and it creates the mailslot with which to collect replies to our poll.
                    100:  *
                    101:  *  RETURNS
                    102:  *
                    103:  *      TRUE        - initialization succeeded
                    104:  *      FALSE       - initialization failed, can't go on
                    105:  */
                    106: 
                    107: 
                    108: BOOL
                    109: InitRemote( HWND hWnd )
                    110: {
1.1.1.2   root      111: 
1.1       root      112: #ifndef RPC
                    113:     UNREFERENCED_PARAMETER(hWnd);
                    114: #endif
                    115: 
                    116:     // set up our local entry
                    117:     SvrTableSz++;
                    118:     strcpy(SvrTable[0].name, szLocal);
                    119:     SvrTable[0].iStatus = SS_LOCAL;
                    120: 
                    121: 
                    122:     // good, we succeeded
                    123:     return TRUE;
                    124: }
                    125: 
                    126: 
                    127: /*
                    128:  *  CheckDrawStatus --
                    129:  *
                    130:  *  This function does a check of all buffers being drawn.
                    131:  *
                    132:  *  If it finds an idle pipe, and there is work to be done, it assigns
                    133:  *      a line, and writes out the request.
                    134:  *  If it finds a read-pending pipe, it checks if the read has completed.
                    135:  *      If it has, it is read and a message is sent so the read data can
                    136:  *      be processed.
                    137:  *
                    138:  *  RETURNS
                    139:  *      TRUE        - we did a piece of work
                    140:  *      FALSE       - we could not find any work to do.
                    141:  */
                    142: 
                    143: BOOL CheckDrawStatus( HWND hwnd)
                    144: {
                    145: 
                    146:     static int  iWork = 0;
                    147:     int         iLast;
                    148:     CALCBUF     cb;
                    149:     PDWORD  pbBuf;
                    150: 
                    151:     // If no pipes, forget it
                    152:     if (SvrTableSz == 0)
                    153:         return FALSE;
                    154: 
                    155:     // Move on from where we left off
                    156: 
                    157:     iLast = iWork;
                    158: 
                    159:     while ( TRUE )
                    160:     {
                    161:       iWork++;
                    162: 
                    163:         if (iWork == SvrTableSz)
                    164:             iWork = 0;
                    165: 
                    166:         // Check the status
                    167:         switch(SvrTable[iWork].iStatus) {
                    168: 
                    169:         case SS_PAINTING:
                    170:             break;
                    171: 
                    172:         case SS_IDLE:
                    173:             // Idle; assign it a piece of work
                    174:             if ((long)dwCurrentLine > rclPicture.xRight)
                    175:                 break;
                    176: 
                    177:             if (!fRemoteWork)
                    178:                 break;
                    179:             // cb is of type CALCBUF;
                    180:             // rectangle, precision, threshold and complex point
                    181:             cb.rclDraw.xLeft = dwCurrentLine;
                    182:             cb.rclDraw.xRight = dwCurrentLine + iLines - 1;
                    183:             cb.rclDraw.yTop = rclPicture.yTop;
                    184:             cb.rclDraw.yBottom = rclPicture.yBottom;
                    185:             cb.dblPrecision = dPrecision;
                    186:             cb.dwThreshold = dwThreshold;
                    187:             cb.cptLL = cptLL;
                    188: 
                    189:             SvrTable[iWork].dwLine = dwCurrentLine;
                    190:             dwCurrentLine += iLines;
                    191:             SvrTable[iWork].iStatus = SS_READPENDING;
                    192:             SvrTable[iWork].cPicture = cPictureID;
                    193:             SvrTable[iWork].cLines = iLines;
                    194: 
                    195:             return TRUE;
                    196: 
                    197:         case SS_LOCAL:
1.1.1.3 ! root      198:            // Do a chunk of work locally
        !           199: #ifdef RPC
        !           200:            if (fBound == FALSE)
        !           201:                break;
        !           202: #endif
1.1       root      203: 
                    204:             if ((long)dwCurrentLine > rclPicture.xRight) {
                    205:                 if (fContinueZoom == TRUE) {
                    206:                      if ((fZoomIn == TRUE) && (dPrec < (double)MINPREC))
                    207:                         fZoomIn = FALSE;  // start zooming out
                    208:                      if ((fZoomIn == FALSE) && (dPrec > (double)MAXPREC))
                    209:                         fZoomIn = TRUE;
                    210:                      if (fZoomIn) {
                    211:                          CountHistogram();
                    212:                          rcZoom.top    = iHistMaxJ * (WIDTH/4);
                    213:                          rcZoom.bottom = rcZoom.top + (WIDTH/4) - 1;
                    214:                          rcZoom.left   = iHistMaxI * (HEIGHT/4);
                    215:                          rcZoom.right  = rcZoom.left + (HEIGHT/4) - 1;
                    216:                          fRectDefined = TRUE;
                    217:                          PostMessage(hwnd, WM_COMMAND, IDM_ZOOMIN, 0L);
                    218:                      }
                    219:                      else
                    220:                          PostMessage(hwnd, WM_COMMAND, IDM_ZOOMOUT, 0L);
                    221:                 }
                    222:                 break;
                    223:             }
                    224: 
                    225:             if (!TakeDrawBuffer())
                    226:                 break;
                    227: 
                    228:             pbBuf = GetDrawBuffer();
                    229: 
                    230:             cb.rclDraw.xLeft = dwCurrentLine;
                    231:             cb.rclDraw.xRight = dwCurrentLine+ iLines-1;
                    232:             cb.rclDraw.yTop = rclPicture.yTop;
                    233:             cb.rclDraw.yBottom = rclPicture.yBottom;
                    234: 
                    235: 
                    236:             MandelCalc(&cptLL,
                    237:                        &(cb.rclDraw),
                    238:                        dPrecision,
                    239:                        dwThreshold,
                    240:                        (PLINEBUF)pbBuf);
                    241: 
                    242:             FreeDrawBuffer();
                    243: 
                    244:             SvrTable[iWork].cPicture = cPictureID;
                    245:             SvrTable[iWork].dwLine = dwCurrentLine;
                    246:             SvrTable[iWork].cLines = iLines;
                    247: 
                    248:             PostMessage(hwnd, WM_PAINTLINE,
                    249:                             (UINT)iWork,
                    250:                         0L);
                    251:             dwCurrentLine += iLines;
                    252:             return TRUE;
                    253: 
                    254:         }
                    255: 
                    256: 
                    257:         // If we made the full loop, we're done
                    258:         if (iWork == iLast)
                    259:             return FALSE;
                    260:     }
                    261: }
                    262: 
                    263: 
                    264: /*
                    265:  *  SetNewCalc --
                    266:  *
                    267:  *  This sets up new information for a drawing and
                    268:  *  updates the drawing ID so any calculations in progress will not
                    269:  *  be mixed in.
                    270:  */
                    271: 
                    272: void SetNewCalc( CPOINT cptUL, double dPrec, RECT rc)
                    273: {
                    274: 
                    275:     /*
                    276:      *  First, the base point. We need to translate from upper left to
                    277:      *  lower left.
                    278:      */
                    279: 
                    280:     cptLL.real = cptUL.real;
                    281:     cptLL.imag = cptUL.imag - (dPrec * (rc.bottom - rc.top));
                    282: 
                    283:     // Now the precision
                    284:     dPrecision = dPrec;
                    285: 
                    286:     // The rectangle. Once again, translate.
                    287:     rclPicture.xLeft = (long) rc.left;
                    288:     rclPicture.xRight = (long) rc.right;
                    289:     rclPicture.yBottom = (long) rc.top;
                    290:     rclPicture.yTop = (long) rc.bottom;
                    291: 
                    292:     // Current line, start of drawing
                    293:     dwCurrentLine = rclPicture.xLeft;
                    294: 
                    295:     dwThreshold = CalcThreshold(dPrecision);
                    296: 
                    297: 
                    298: }
                    299: 
                    300: void IncPictureID(void)
                    301: {
                    302:     cPictureID++;
                    303: }
                    304: 
                    305: /*
                    306:  *  CheckDrawing --
                    307:  *
                    308:  *  Just a sanity check here -- a function to check to make sure that we're
                    309:  *  on the right drawing
                    310:  */
                    311: 
                    312: BOOL
                    313: CheckDrawingID( int id)
                    314: {
                    315:     return (id == cPictureID) ? TRUE : FALSE;
                    316: }
                    317: 
                    318: 
                    319: /*
                    320:  *  TakeDrawBuffer/ GetDrawBuffer/ FreeDrawBuffer / ReturnDrawBuffer
                    321:  *
                    322:  *  These functions hide a handle to a buffer of memory.
                    323:  *
                    324:  *  TakeDrawBuffer ensures only one pipe read at a time.
                    325:  *  GetDrawBuffer locks the handle and returns a pointer.
                    326:  *  FreeDrawBuffer unlocks the handle.
                    327:  *  ReturnDrawBuffer unlocks the handle and lets another pipe read go.
                    328:  */
                    329: 
                    330: static BOOL fBufferTaken = FALSE;
1.1.1.3 ! root      331: static HANDLE hSharedBuf = (HANDLE)NULL;
1.1       root      332: 
                    333: 
                    334: BOOL
                    335: TakeDrawBuffer( void )
                    336: {
                    337: 
                    338:     if (fBufferTaken)
                    339:     {
                    340:         return FALSE;
                    341:     }
                    342: 
                    343:     if (hSharedBuf == NULL)
                    344:     {
1.1.1.2   root      345:        hSharedBuf = GlobalAlloc(GMEM_MOVEABLE, MAX_BUFSIZE);
1.1       root      346:         if (hSharedBuf == NULL)
                    347:             return FALSE;
                    348:     }
                    349:     fBufferTaken = TRUE;
                    350:     return TRUE;
                    351: }
                    352: 
                    353: 
                    354: 
                    355: PDWORD
                    356: GetDrawBuffer( void )
                    357: {
                    358: 
                    359:     if (hSharedBuf == NULL)
                    360:         return NULL;
                    361: 
1.1.1.2   root      362:     return (PDWORD) GlobalLock(hSharedBuf);
1.1       root      363: }
                    364: 
                    365: 
                    366: 
                    367: void
                    368: FreeDrawBuffer( void )
                    369: {
1.1.1.2   root      370:     GlobalUnlock(hSharedBuf);
1.1       root      371: }
                    372: 
                    373: 
                    374: void
                    375: ReturnDrawBuffer( void )
                    376: {
                    377:     fBufferTaken = FALSE;
                    378: }
                    379: 
                    380: 
                    381: 
                    382: /*
                    383:  *  CalcThreshold --
                    384:  *
                    385:  *  We need an iteration threshold beyond which we give up. We want it to
                    386:  *  increase the farther we zoom in. This code generates a threshold value
                    387:  *  based on the precision of drawing.
                    388:  *
                    389:  *  RETURNS
                    390:  *
                    391:  *      threshold calculated based on precision
                    392:  */
                    393: 
                    394: 
                    395: DWORD   CalcThreshold(double precision)
                    396: {
                    397:     DWORD   thres = 25;
1.1.1.2   root      398:     double  multiplier = (double) 100.0;
1.1       root      399: 
                    400:     /* for every 100, multiply by 2 */
1.1.1.2   root      401:     while ( (precision *= multiplier) < (double)1.0)
1.1       root      402:         thres *= 2;
                    403: 
                    404:     return thres;
                    405: }
                    406: 
                    407: 
                    408: 
                    409: /*
                    410:  *  QueryThreshold --
                    411:  *
                    412:  *  Callback for finding out what the current drawing's threshold is.
                    413:  */
                    414: 
                    415: DWORD QueryThreshold( void )
                    416: {
                    417:     return dwThreshold;
                    418: }
                    419: 
                    420: 
                    421: /*
                    422:  *
                    423:  *  GetServerCount --
                    424:  *
                    425:  *  Returns the number of servers in the table.
                    426:  */
                    427: 
                    428: int
                    429: GetServerCount( void )
                    430: {
                    431:     return (int) SvrTableSz-1;
                    432: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.