Annotation of os232sdk/toolkt20/c/samples/semaph/semaph.c, revision 1.1.1.1

1.1       root        1: /*==============================================================*\
                      2:  *  Semaph.c - routines for demonstrating semaphore API.        *
                      3:  *                                                              *
                      4:  *      Created 1990, Microsoft, IBM Corp.                      *
                      5:  *--------------------------------------------------------------*
                      6:  *  This module contains code to demonstrate the use of         *
                      7:  *  semaphores to control access to a resource shared by        *
                      8:  *  multiple threads. Event semaphores are used to signal a     *
                      9:  *  thread is to give up a resource. A Mutex semaphore is used  *
                     10:  *  to provide exclusive access to the resource. A mux          *
                     11:  *  semaphore provides a method to check multiple event         *
                     12:  *  semaphores.                                                 *
                     13:  *                                                              *
                     14:  *                                                              *
                     15:  *--------------------------------------------------------------*
                     16:  *                                                              *
                     17:  *  This source file contains the following functions:          *
                     18:  *                                                              *
                     19:  *        VOID SemError(PSZ,USHORT);                            *
                     20:  *        USHORT CreateAllSems(VOID);                           *
                     21:  *        VOID StartSemExample(VOID);                           *
                     22:  *        VOID ThreadConsumer(ULONG);                           *
                     23:  *        VOID SignalUserEvent(PUSHORT pfAutoMode);             *
                     24:  *        USHORT SetAutoMode(VOID);                             *
                     25:  *        VOID RunAuto(VOID);                                   *
                     26:  *        VOID StopSemaphore(VOID);                             *
                     27:  *                                                              *
                     28:  *                                                              *
                     29: \*==============================================================*/
                     30: 
                     31: /*--------------------------------------------------------------*\
                     32:  *  Include files, macros, defined constants, and externs       *
                     33: \*--------------------------------------------------------------*/
                     34: 
                     35: #define  LINT_ARGS
                     36: #define  INCL_PM
                     37: #define INCL_BASE
                     38: 
                     39: #include <os2.h>
                     40: #include <stdio.h>
                     41: #include <string.h>
                     42: #include <stdlib.h>
                     43: #include <dos.h>
                     44: #include "sem_pnt.h"
                     45: #include "semaph.h"
                     46: #include "sem_main.h"
                     47: #include "sem_dlg.h"
                     48: #include "sem_xtrn.h"
                     49: 
                     50: #define STACKSIZE 0X10000L
                     51: #define TIMEOUTPERIOD 33L
                     52: #define EVENTSEM 0
                     53: #define STOPSEM -1
                     54: #define BASETEN 10
                     55: 
                     56: /*--------------------------------------------------------------*\
                     57:  *  Global variables                                            *
                     58: \*--------------------------------------------------------------*/
                     59: 
                     60: 
                     61: /* Global variables for semaphore handles.  Used only in this file. */
                     62: 
                     63: HEV  hevStop, hevStopAuto, hevItem;
                     64: HMTX hmtxOwnResource;
                     65: HMUX hmuxResource;  //, hmuxReady;
                     66: 
                     67: /* Global variables for number of consumer threads & thread ID's */
                     68: 
                     69: USHORT usConsumerThreadsCreated;
                     70: TID tidAutoThread;
                     71: THRDATA thrConsumers[MAXUSERS];
                     72: ULONG ulTimeout = TIMEOUTPERIOD;
                     73: 
                     74: static VOID MyMove (USHORT usMyID, ULONG ulUser);
                     75: 
                     76: /****************************************************************\
                     77:  * Procedure to print error messages to screen in a Message Box.*
                     78:  *--------------------------------------------------------------*
                     79:  *                                                              *
                     80:  *  Name:    SemError(pszAPIName,usErrorCode)                   *
                     81:  *                                                              *
                     82:  *  Purpose: Used to print name of API and error number when   *
                     83:  *           a return code other than 0 is returned from an     *
                     84:  *           API call.                                          *
                     85:  *                                                              *
                     86:  *  Usage:   Called by all procedures in this file whenever     *
                     87:  *           an API call fails.                                 *
                     88:  *                                                              *        
                     89:  *  Method:  The error number is converted to a string.  String * 
                     90:  *           functions are used to build the error message.     *
                     91:  *           The message is printed in a Message Box.           *
                     92:  *                                                              *
                     93:  *  NOTE:    This function is called by multiple threads,       *
                     94:  *           therefore, only re-entrant functions can be used.  *
                     95:  *           Note that string is build according to American    *
                     96:  *           English conventions using hard-coded strings, and  *
                     97:  *           so portability to other languages would require a  *
                     98:  *           more flexible approach.                            *
                     99:  *                                                              *
                    100:  *  Returns: none.                                              *
                    101:  *                                                              *
                    102: \****************************************************************/
                    103: 
                    104: 
                    105: VOID SemError(PSZ pszAPIName,USHORT usErrorCode)
                    106: {
                    107:     char acMessage[100],acErrorNumber[10];
                    108: 
                    109:     itoa(usErrorCode,acErrorNumber,BASETEN);
                    110:     strcpy(acMessage,pszAPIName);
                    111:     strcat(acMessage,": error # ");
                    112:     strcat(acMessage,acErrorNumber);
                    113: 
                    114:     WinMessageBox(HWND_DESKTOP,
                    115:                  hwndMain,
                    116:                  acMessage,
                    117:                  szAppName,
                    118:                  1,
                    119:                  MB_OK);
                    120: }
                    121: 
                    122: 
                    123: /****************************************************************\
                    124:  * Routine to create  semaphores used in this file.             *
                    125:  *--------------------------------------------------------------*
                    126:  *                                                              *
                    127:  *  Name:    CreateAllSems(VOID)                                *
                    128:  *                                                              *
                    129:  *  Purpose: Create semaphores needed by the consumer threads.  *
                    130:  *           Checks return codes from semaphore creation.       *
                    131:  *                                                              *
                    132:  *  Usage:   Called by StartSemExample.                         *
                    133:  *                                                              *
                    134:  *  Method:  Semaphores are all anonymous private semaphores    *
                    135:  *           since the semaphores are used by threads in the    *
                    136:  *           same process.                                      *
                    137:  *                                                              *
                    138:  *  Returns: 0 if all semaphores are created successfully.      *
                    139:  *           Otherwise returns error code for first create      *
                    140:  *           semaphore API to fail.                             *
                    141:  *                                                              *
                    142: \****************************************************************/
                    143: 
                    144: USHORT CreateAllSems(VOID)
                    145: {   
                    146:     USHORT      rc;
                    147:     SEMRECORD   asr[MAXRESOURCES];
                    148:     INT         i;
                    149: 
                    150:     rc =  DosCreateMutexSem((PSZ)NULL,&hmtxOwnResource,NULL,FALSE);
                    151:     if (rc)
                    152:     {
                    153:         SemError("DosCreateMutexSem",rc);
                    154:         return(rc);
                    155:     }
                    156:     
                    157:     for (i = 0; i < MAXRESOURCES; i++) {
                    158:         if (rc = DosCreateEventSem((PSZ)NULL, &aSquares[i].hev, NULL, FALSE))
                    159:         {
                    160:             SemError("DosCreateEventSem",rc);
                    161:             return(rc);
                    162:         }
                    163:         else
                    164:         {
                    165:             asr[i].ulUser = i;
                    166:             asr[i].hsemCur = (PVOID) aSquares[i].hev;
                    167:         }
                    168:     }
                    169: 
                    170:     /* this muxwait semaphore contains all of the event semaphores
                    171:      * created in the loop above.
                    172:      */
                    173:     if (rc = DosCreateMuxWaitSem((PSZ)NULL,&hmuxResource,MAXRESOURCES,asr,
                    174:      DCMW_WAIT_ANY))
                    175:     {
                    176:         SemError("DosCreateMuxWaitSem",rc);
                    177:         return(rc);
                    178:     }
                    179:     if (rc = DosCreateEventSem((PSZ)NULL,&hevStop,NULL,FALSE))
                    180:     {
                    181:         SemError("DosCreateEventSem",rc);
                    182:         return(rc);
                    183:     }                                
                    184:     return(rc);
                    185: }
                    186: 
                    187: /****************************************************************\
                    188:  * Routine to start semaphore example                           *
                    189:  *--------------------------------------------------------------*
                    190:  *                                                              *
                    191:  *  Name:     StartSemExample(VOID)                             *
                    192:  *                                                              *
                    193:  *  Purpose:  Calls routines to create semaphores and draw      *
                    194:  *            resources.  Creates consumer threads.             *
                    195:  *                                                              *
                    196:  *  Usage:    Called in file usercmd.c when the user selects    *
                    197:  *            start from the semaphore menu.                    *
                    198:  *                                                              *
                    199:  *  Method:   Uses routines in paint.c to draw consumers and    *
                    200:  *            resources.  This is done by creating a paint      *
                    201:  *            message, not calling the draw routines directly.  *
                    202:  *                                                              *
                    203:  *  Returns:  TRUE if start succeeds, FALSE if start fails      *
                    204:  *                                                              *
                    205: \****************************************************************/
                    206: 
                    207: INT   StartSemExample(VOID)
                    208: {
                    209:     TID tid;
                    210:     USHORT rc;
                    211:     INT i;
                    212:     FONTMETRICS fntmet;
                    213:     HPS         hps;
                    214:     SWP         swp;
                    215: 
                    216:     InitSemaphExample();
                    217: 
                    218:     rc = CreateAllSems();
                    219: 
                    220:     if (rc)
                    221:         return FALSE;
                    222:     
                    223:     /* Create consumer threads. Note that values can be passed to 
                    224:      * threads in OS/2 2.0. We pass the ordinal number of the child
                    225:      * to each child.
                    226:      */
                    227: 
                    228:     for (usConsumerThreadsCreated = 0;
                    229:      usConsumerThreadsCreated < cNumUsers; usConsumerThreadsCreated++)
                    230:     {
                    231:         rc = DosCreateThread(&tid,ThreadConsumer,usConsumerThreadsCreated,1,
                    232:                              STACKSIZE);
                    233:         if (rc)
                    234:         {
                    235:             SemError("DosCreateThread",rc);
                    236:             return FALSE;
                    237:         }
                    238:         else
                    239:         {
                    240:             thrConsumers[usConsumerThreadsCreated].tid = tid;
                    241:             thrConsumers[usConsumerThreadsCreated].lHits = 0L;
                    242:         }
                    243:     }
                    244:     
                    245:     for (i = 0; i < cNumUsers; i++) {
                    246:         DosResumeThread (thrConsumers[i].tid);
                    247:     }
                    248:     
                    249:     if (hps = WinGetPS (hwndMain))
                    250:     {
                    251:         GpiQueryFontMetrics (hps, (LONG) sizeof fntmet, &fntmet);
                    252:         WinQueryWindowPos (hwndMain, &swp);
                    253:         SetRectPositions((SHORT)swp.cx, (SHORT)swp.cy, (SHORT) fntmet.lMaxBaselineExt, (SHORT) fntmet.lMaxDescender);
                    254:         DrawRects (hps);
                    255:         WinReleasePS (hps);
                    256:     }
                    257:     return TRUE;
                    258: }
                    259:                           
                    260: 
                    261: /****************************************************************\
                    262:  * Routine to signal consumer to release resource.              *
                    263:  *--------------------------------------------------------------*
                    264:  *                                                              *
                    265:  *  Name:     SignalUserEvent(pfAutoMode)                       *
                    266:  *                                                              *
                    267:  *  Purpose:  Posts user event semaphore to signal thread to    *
                    268:  *            release resource.  Also posts event to stop       *
                    269:  *            Auto mode if *pfAutoMode is true.                 *
                    270:  *                                                              *
                    271:  *  Usage:    Called in file usercmd.c when the user selects    *
                    272:  *            Event from the semaphore menu.                    *
                    273:  *                                                              *
                    274:  *  Method:   Turns off Auto mode, if present by posting auto   *
                    275:  *            semaphore.  User event is then posted.            *
                    276:  *                                                              *
                    277:  *  Returns:                                                    *
                    278:  *                                                              *
                    279: \****************************************************************/
                    280: 
                    281: VOID SignalUserEvent(PUSHORT pfAutoMode)
                    282: {
                    283:   USHORT rc;
                    284:          
                    285:   /* If sample is in auto mode turn auto mode off. */
                    286: 
                    287:   if (*pfAutoMode)
                    288:   {
                    289:       rc = DosPostEventSem(hevStopAuto);
                    290:       if (rc)
                    291:       {
                    292:          SemError("DosPostEventSem Stop Auto",rc);
                    293:       }
                    294:       /* Wait for auto mode thread to die, so we don't end up with multiple *
                    295:        * copies of it later.    */
                    296: 
                    297:       rc = DosWaitThread(&tidAutoThread,0L);
                    298:       if (rc)
                    299:       {
                    300:          SemError("DosWaitThread",rc);
                    301:       }
                    302:       *pfAutoMode = FALSE;
                    303:       DosCloseEventSem (hevStopAuto);
                    304:   }
                    305: 
                    306:   /* If Auto mode haas already posted the event this is OK
                    307:      so we will not check error codes here. */
                    308: 
                    309:   DosPostEventSem(aSquares[rand() % MAXRESOURCES].hev);
                    310: }
                    311: 
                    312: 
                    313: /****************************************************************\
                    314:  * Routine to start Auto mode.                                  *
                    315:  *--------------------------------------------------------------*
                    316:  *                                                              *
                    317:  *  Name:     SetAutoMode(VOID)                                 *
                    318:  *                                                              *
                    319:  *  Purpose:  Creates thread and semaphore needed to run auto   *
                    320:  *            mode.                                            *
                    321:  *                                                              *
                    322:  *  Usage:    Called in file usercmd.c when the user selects    *
                    323:  *            Auto from the semaphore menu.                     *
                    324:  *                                                              *
                    325:  *  Returns:  NO_ERROR on success, else error from api call.    *
                    326:  *                                                              *
                    327: \****************************************************************/
                    328: 
                    329: USHORT SetAutoMode()
                    330: {
                    331:     USHORT rc;
                    332: 
                    333:     rc = DosCreateEventSem((PSZ)NULL,&hevStopAuto,NULL,FALSE);
                    334:     if (rc)
                    335:     {
                    336:         SemError("DosCreateEventSem",rc);
                    337:         return(rc);
                    338:     }
                    339: 
                    340:     rc = DosCreateThread(&tidAutoThread,RunAuto,0L,0L,STACKSIZE);
                    341:     if (rc)
                    342:     {
                    343:         DosCloseEventSem (hevStopAuto); /* close semaphore created above */
                    344:         SemError("DosCreateThread",rc);
                    345:         return(rc);
                    346:     }
                    347:     
                    348:     return(NO_ERROR);
                    349: }
                    350: 
                    351: 
                    352: /****************************************************************\
                    353:  * Routine to run  Auto mode.                                   *
                    354:  *--------------------------------------------------------------*
                    355:  *                                                              *
                    356:  *  Name:     RunAuto(VOID)                                     *
                    357:  *                                                              *
                    358:  *  Purpose:  Posts user event at fixed time interval to signal *
                    359:  *            consumers to release resource.                    *
                    360:  *                                                              *
                    361:  *  Usage:    Thread created by SetAutoMode.                    *
                    362:  *                                                              *
                    363:  *  Method:   Kills itself when StopAutoMode semaphore is       *
                    364:  *            posted.                                           *
                    365:  *                                                              *
                    366:  *  Returns:                                                    *
                    367:  *                                                              *
                    368: \****************************************************************/
                    369: 
                    370: VOID RunAuto(VOID)
                    371: {
                    372:     USHORT rcWait;
                    373:     HAB habLocal;
                    374:     HMQ hmqLocal;
                    375:     INT i;
                    376: 
                    377:     /* Need a message queue for any thread that wants to print messages. */
                    378: 
                    379:     habLocal = WinInitialize(NULL);
                    380:     hmqLocal = WinCreateMsgQueue(habLocal,NULL);
                    381: 
                    382:     /* while stop auto semaphore not posted, post user event semaphore. */
                    383: 
                    384:     /* Don't check return code from DosPostEventSem(hevUserEvent)
                    385:        since we just want the resource to change hands.  We don't
                    386:        care if it changes hands exactly every time it goes through
                    387:        the loop.
                    388: 
                    389:        The event may already be posted if the system is busy and
                    390:        the resource threads don't finish with it fast enough.
                    391:        This is not a problem in this case.
                    392:      */
                    393: 
                    394:     do {
                    395:         /* if ulTimeout is zero, still waitevent for 1 msec to
                    396:          * force yielding of CPU.
                    397:          */
                    398:         rcWait = DosWaitEventSem(hevStopAuto, max (ulTimeout, 1));
                    399:         if (rcWait == ERROR_TIMEOUT) {
                    400:             i = rand () % MAXRESOURCES;      /* generate it */
                    401:             DosPostEventSem (aSquares[i].hev); 
                    402:         }
                    403:     } while (rcWait == ERROR_TIMEOUT);
                    404: 
                    405:     /* If there was an error, print a message */
                    406: 
                    407:     if (rcWait) {
                    408:        SemError("DosWaitEventSem",rcWait);
                    409:     }
                    410: 
                    411:     WinDestroyMsgQueue (hmqLocal);
                    412:     WinTerminate (habLocal);
                    413:     DosExit(EXIT_THREAD,0);
                    414: }
                    415: 
                    416: 
                    417: /****************************************************************
                    418:  * Routine to stop semaphore example.                           
                    419:  *---------------------------------------------------------------
                    420:  *                                                              
                    421:  *  Name:     BeginStop(pfAutoMode)                         
                    422:  *                                                              
                    423:  *  Purpose:  Posts stop event semaphore to signal threads to   
                    424:  *            die.  Also posts event to stop Auto mode if       
                    425:  *            necessary. Then waits for threads to complete,
                    426:  *            Creates thread StopSemaphore which posts stop event
                    427:  *            and waits for child threads.
                    428:  *
                    429:  *  Usage:    Called in file usercmd.c when the user selects    
                    430:  *            Stop from the semaphore menu.                     
                    431:  *                                                              
                    432:  *  Method:   Execs thread to do waits so that message thread
                    433:  *            doesn't hang.
                    434:  *  Returns:                                                    
                    435:  *                                                              
                    436: \****************************************************************/
                    437: VOID
                    438: BeginStop (PUSHORT pfAutoMode)
                    439: {
                    440:     USHORT rc;
                    441:     TID tidLocal;
                    442: 
                    443:     rc = DosPostEventSem(hevStop);
                    444:     if (rc)
                    445:     {
                    446:         SemError("DosPostEventSem",rc);
                    447:         return;
                    448:     }
                    449: 
                    450:     if (*pfAutoMode)
                    451:     {
                    452:         rc = DosPostEventSem(hevStopAuto);
                    453:         if (rc)
                    454:         {
                    455:            SemError("DosPostEventSem",rc);
                    456:         }
                    457:     }
                    458: 
                    459:     rc = DosCreateThread(&tidLocal,StopSemaphore,(LONG)pfAutoMode,0,STACKSIZE);
                    460:     if (rc)
                    461:     {
                    462:         SemError("DosCreateThread",rc);
                    463:     }
                    464: }
                    465: 
                    466: /****************************************************************
                    467:  * Routine to really stop semaphore example.                           
                    468:  *---------------------------------------------------------------
                    469:  *                                                              
                    470:  *  Name:     StopSemaphore(pfAutoMode)                         
                    471:  *                                                              
                    472:  *  Purpose:  Waits for threads to complete,
                    473:  *            Sends message to message thread to indicate this
                    474:  *            has occurred, and exits.
                    475:  *                                                              
                    476:  *  Usage:    Exec'd from BeginStop when user selects Stop from
                    477:  *            Semaphore menu.
                    478:  *                                                              
                    479:  *  Method:   Turns off Auto mode, if present by posting auto   
                    480:  *            semaphore.  Then stop event is posted.  Waits     
                    481:  *            for threads to die.                               
                    482:  *  Returns:                                                    
                    483:  *                                                              
                    484: \****************************************************************/
                    485: 
                    486: 
                    487: VOID StopSemaphore(PUSHORT pfAutoMode)
                    488: {
                    489:     USHORT rc,usCount, i;
                    490: 
                    491: 
                    492:     if (*pfAutoMode)
                    493:     {
                    494:         rc = DosWaitThread(&tidAutoThread,0L);
                    495:         if (rc && (rc != ERROR_INVALID_THREADID))
                    496:         {
                    497:            SemError("DosWaitThread",rc);
                    498:         }
                    499:         *pfAutoMode = FALSE;
                    500:     }
                    501: 
                    502:     
                    503:     /* Wait for usConsumer threads to die.  Order of death not important. */
                    504: 
                    505:     for (usCount = 0; usCount < usConsumerThreadsCreated; usCount++)
                    506:     {
                    507:         rc = DosWaitThread(&thrConsumers[usCount].tid,0L);
                    508: 
                    509:         /* rc is ERROR_INVALID_THREADID the thread is already dead. This *\
                    510:         \* is OK and not a error.                                   */
                    511: 
                    512:         if (rc && (rc != ERROR_INVALID_THREADID))
                    513:         {
                    514:             SemError("DosWaitThread",rc);
                    515:         }
                    516:     }
                    517: 
                    518:     /* Threads dead so we don't need semaphores any more.  */
                    519: 
                    520:     DosCloseEventSem(hevStopAuto);
                    521:     DosCloseEventSem(hevStop);
                    522:     DosCloseMutexSem(hmtxOwnResource);
                    523:     for (i = 0; i < MAXRESOURCES; i++) {
                    524:         DosCloseEventSem(aSquares[i].hev);
                    525:     }
                    526:     DosCloseMuxWaitSem (hmuxResource );
                    527:     WinPostMsg (hwndMain, WM_COMMAND, (MPARAM)IDM_STOPFINISHED, (MPARAM)NULL);
                    528:     DosExit (EXIT_THREAD, 0);
                    529: }
                    530: 
                    531: /****************************************************************\
                    532:  * Routine for consumer threads.                                *
                    533:  *--------------------------------------------------------------*
                    534:  *                                                              *
                    535:  *  Name:     ThreadConsumer(ULONG)                             *
                    536:  *                                                              *
                    537:  *  Purpose:  There are NUMUSERS copies of this thread to act   *
                    538:  *            as consumers of the resource. The thread waits   *
                    539:  *            for exclusive access to the resource and colors it*
                    540:  *                                                              *
                    541:  *  Usage:    Threads created by StartSemExample.               *
                    542:  *                                                              *
                    543:  *  Method:   Waits for mutex to gain ownership of resource.    *
                    544:  *            Releases resource when user event. Dies when      *
                    545:  *            Stop event.                                       *
                    546:  *  Returns:                                                    *
                    547:  *                                                              *
                    548: \****************************************************************/
                    549: 
                    550: VOID  ThreadConsumer(USHORT usMyID)
                    551: {
                    552:     ULONG ulPostCnt;
                    553:     ULONG ulUser;
                    554:     USHORT rc;
                    555:     HAB hab;
                    556:     HMQ  hmq;
                    557: 
                    558:     /* Need a message queue for any thread that wants to print messages. */
                    559:     hab = WinInitialize(NULL);
                    560:     hmq = WinCreateMsgQueue(hab,NULL);
                    561:     
                    562:     /* while the user has not selected stop ... */
                    563:     while ((DosWaitEventSem(hevStop,SEM_IMMEDIATE_RETURN)) == ERROR_TIMEOUT) {
                    564:         /* Wait for exclusive ownership of resource */
                    565: 
                    566:         DosRequestMutexSem(hmtxOwnResource,SEM_INDEFINITE_WAIT);
                    567: 
                    568:         /* the following check is necessary because the stop semaphore
                    569:          * may have been posted  while we were waiting on the mutex
                    570:          */
                    571:         if (DosWaitEventSem(hevStop, SEM_IMMEDIATE_RETURN) == ERROR_TIMEOUT) {
                    572:             /* an item is ready, which one?
                    573:              * don't wait forever because there is
                    574:              * a possibility that the stop semaphore
                    575:              * was posted and that no more resource
                    576:              * is forthcoming. we wait twice as long
                    577:              * as we think is necessary.
                    578:              */
                    579:             if (!DosWaitMuxWaitSem (hmuxResource, max (ulTimeout << 1, TIMEOUTPERIOD), &ulUser)) {
                    580:                 MyMove (usMyID, ulUser);
                    581:                 DosResetEventSem(aSquares[ulUser].hev, &ulPostCnt);
                    582:             }
                    583:         }
                    584: 
                    585:         /*Let some other thread have resource. */
                    586:         if (rc = DosReleaseMutexSem(hmtxOwnResource)) {
                    587:               SemError("DosReleaseMutexSem",rc);
                    588:         }
                    589:     }
                    590:   
                    591:     /* hevStop was posted, kill this thread */
                    592:     WinDestroyMsgQueue (hmq);
                    593:     WinTerminate (hab);
                    594:     DosExit(EXIT_THREAD,0);
                    595: }
                    596: 
                    597: 
                    598: /****************************************************************\
                    599:  *  called from ThreadConsumer to make and register move
                    600:  *--------------------------------------------------------------
                    601:  *
                    602:  *  Name: MyMove (usMyID, ulUser)
                    603:  *        USHORT    usMyID;     id of caller
                    604:  *        ULONG     ulUser;     number of the square to "hit"
                    605:  *
                    606:  *  Purpose: color a square on the game board 'my' color.
                    607:  *           update display of number of hits for 'my' thread.
                    608:  *
                    609:  *  Usage: called only from ThreadConsumer
                    610:  *
                    611:  *  Method:
                    612:  *
                    613:  *  Returns: none
                    614:  *
                    615: \****************************************************************/
                    616: static VOID
                    617: MyMove (USHORT usMyID, ULONG ulUser)
                    618: {
                    619:     if (aSquares [ulUser].usOwner != usMyID) {
                    620:         aSquares[ulUser].usOwner = usMyID;
                    621:         thrConsumers[usMyID].lHits++;
                    622:         DrawResource (&aSquares[ulUser].rcl, colors [usMyID]);
                    623:         DrawStats (usMyID);
                    624:     }
                    625: }
                    626: 
                    627: 
                    628: /****************************************************************\
                    629:  * Routine to init game board                                   *
                    630:  *--------------------------------------------------------------*
                    631:  *                                                              *
                    632:  *  Name:     InitSemaphExample(VOID)                           *
                    633:  *                                                              *
                    634:  *  Purpose:  Initializes game board unowned, sets semaphores   *
                    635:  *            to 0.                                             *
                    636:  *  Usage:    Called from StartSemExample in semaph.c when      *
                    637:  *            user selects start from the semaphore menu.       *
                    638:  *  Method:                                                     *
                    639:  *                                                              *
                    640:  *  Returns:  none                                              *
                    641:  *                                                              *
                    642: \****************************************************************/
                    643: VOID InitSemaphExample(VOID)
                    644: {
                    645:     int i;
                    646:     
                    647:     for (i = 0; i < MAXRESOURCES; i++) {
                    648:         aSquares[i].hev = 0;
                    649:         aSquares[i].usOwner = UNOWNED;
                    650:     }
                    651:     hevStopAuto = 0L;
                    652:     hevStop = 0L;
                    653:     hmtxOwnResource = 0L;
                    654:     hmuxResource  = 0L;
                    655: }
                    656: 

unix.superglobalmegacorp.com

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