home *** CD-ROM | disk | FTP | other *** search
/ Windows Graphics Programming / Feng_Yuan_Win32_GDI_DirectX.iso / Samples / Chapt_04 / Diver / Stack.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-11  |  3.4 KB  |  160 lines

  1. //-----------------------------------------------------------------------------------//
  2. //              Windows Graphics Programming: Win32 GDI and DirectDraw               //
  3. //                             ISBN  0-13-086985-6                                   //
  4. //                                                                                   //
  5. //  Written            by  Yuan, Feng                             www.fengyuan.com   //
  6. //  Copyright (c) 2000 by  Hewlett-Packard Company                www.hp.com         //
  7. //  Published          by  Prentice Hall PTR, Prentice-Hall, Inc. www.phptr.com      //
  8. //                                                                                   //
  9. //  FileName   : stack.cpp                                                             //
  10. //  Description: Multithread-safe shared stack                                       //
  11. //  Version    : 1.00.000, May 31, 2000                                              //
  12. //-----------------------------------------------------------------------------------//
  13.  
  14. #define NOCRYPT
  15.  
  16. #include <windows.h>
  17. #include <assert.h>
  18.  
  19. #include "..\..\include\Decoder.h"
  20. #include "..\..\include\atom.h"
  21.  
  22. #include "Function.h"
  23. #include "Stack.h"
  24.  
  25.  
  26. KStack::KStack()
  27. {
  28.     int i;
  29.  
  30.     nThread    = 0;
  31.  
  32.     nFree      = MAXSTACKSIZE;
  33.     FreeCell   = 0;
  34.     InitializeCriticalSection(&cs);
  35.         
  36.     for (i=0; i<MAXSTACKSIZE; i++)
  37.         Cell[i].next = i+1;
  38.     Cell[MAXSTACKSIZE-1].next = -1;
  39.  
  40.     for (i=0; i<MAXTHREADNO; i++)
  41.     {
  42.         Depth[i] = 0;
  43.         Tos[i]   = -1;
  44.     }
  45. }
  46.  
  47.  
  48. KStack::~KStack()
  49. {
  50.     assert(nFree==MAXSTACKSIZE);
  51.  
  52.     DeleteCriticalSection(&cs);
  53. }
  54.     
  55.     
  56. int KStack::LookupThread(BOOL addifmissing)
  57. {
  58.     unsigned tid = GetCurrentThreadId();
  59.  
  60.     for (int t=0; t<nThread; t++)
  61.         if ( Thread[t] == tid )
  62.             return t;
  63.  
  64.     if (addifmissing)
  65.     {
  66.         EnterCriticalSection(&cs);
  67.         int rslt = nThread++;
  68.             
  69.         Thread[rslt] = tid;
  70.         LeaveCriticalSection(&cs);
  71.  
  72.         return rslt;
  73.     }
  74.     else
  75.     {
  76.         assert(FALSE);
  77.         return -1;
  78.     }
  79. }
  80.         
  81.  
  82. KRoutineInfo * KStack::Push(void)
  83. {
  84.     // check if stack is full
  85.     if (nFree == 0)
  86.     {
  87.         assert(FALSE);
  88.         return NULL;
  89.     }
  90.         
  91.     int t = LookupThread(TRUE);
  92.  
  93.     assert(t>=0);
  94.  
  95.     EnterCriticalSection(&cs);
  96.  
  97.     int c = FreeCell;
  98.     FreeCell = Cell[c].next;
  99.     nFree --;
  100.  
  101.     LeaveCriticalSection(&cs);
  102.  
  103.     Cell[c].next = Tos[t];
  104.     Tos[t]       = c;
  105.     Depth[t] ++;
  106.         
  107.     return & Cell[c];
  108. }
  109.     
  110.     
  111. KRoutineInfo *KStack::Lookup(int & depth)
  112. {
  113.     if ( nFree == MAXSTACKSIZE )
  114.     {
  115.         assert(FALSE);
  116.         return NULL;
  117.     }
  118.     
  119.     int t = LookupThread(FALSE);
  120.  
  121.     if (t < 0)
  122.         return NULL;
  123.  
  124.     depth = Depth[t];
  125.  
  126.     return & Cell[Tos[t]];
  127. }
  128.  
  129.  
  130. void KStack::Pop(void)
  131. {
  132.     if ( nFree == MAXSTACKSIZE )
  133.         assert(FALSE);
  134.     else
  135.     {
  136.         int t = LookupThread(FALSE);
  137.  
  138.         if (t >= 0)
  139.         {
  140.             int c = Tos[t];
  141.  
  142.             if (c >= 0)
  143.             {
  144.                 Tos[t] = Cell[c].next;
  145.                 Depth[t] --;
  146.  
  147.                 EnterCriticalSection(&cs);
  148.                 Cell[c].next = FreeCell;
  149.                 FreeCell     = c;
  150.                 nFree ++;
  151.                 LeaveCriticalSection(&cs);
  152.             }
  153.             else
  154.                 assert(FALSE);
  155.         }
  156.     }
  157. }        
  158.  
  159.  
  160.