LCOV - code coverage report
Current view: top level - source/lib - module_init.cpp (source / functions) Hit Total Coverage
Test: 0 A.D. test coverage report Lines: 11 29 37.9 %
Date: 2023-01-19 00:18:29 Functions: 3 4 75.0 %

          Line data    Source code
       1             : /* Copyright (C) 2010 Wildfire Games.
       2             :  *
       3             :  * Permission is hereby granted, free of charge, to any person obtaining
       4             :  * a copy of this software and associated documentation files (the
       5             :  * "Software"), to deal in the Software without restriction, including
       6             :  * without limitation the rights to use, copy, modify, merge, publish,
       7             :  * distribute, sublicense, and/or sell copies of the Software, and to
       8             :  * permit persons to whom the Software is furnished to do so, subject to
       9             :  * the following conditions:
      10             :  *
      11             :  * The above copyright notice and this permission notice shall be included
      12             :  * in all copies or substantial portions of the Software.
      13             :  *
      14             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
      15             :  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
      16             :  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
      17             :  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
      18             :  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
      19             :  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
      20             :  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
      21             :  */
      22             : 
      23             : /*
      24             :  * helpers for module initialization/shutdown.
      25             :  */
      26             : 
      27             : #include "precompiled.h"
      28             : #include "lib/module_init.h"
      29             : 
      30             : #include "lib/sysdep/cpu.h"   // cpu_CAS
      31             : 
      32             : // not yet initialized, or already shutdown
      33             : static const ModuleInitState UNINITIALIZED = 0; // value documented in header
      34             : // running user callback - concurrent ModuleInit callers must spin
      35             : static const ModuleInitState BUSY = ERR::AGAIN; // never returned
      36             : // init succeeded; allow shutdown
      37             : static const ModuleInitState INITIALIZED = INFO::SKIPPED;
      38             : 
      39             : 
      40          18 : Status ModuleInit(volatile ModuleInitState* initState, Status (*init)())
      41             : {
      42             :     for(;;)
      43             :     {
      44          18 :         if(cpu_CAS(initState, UNINITIALIZED, BUSY))
      45             :         {
      46           3 :             Status ret = init();
      47           3 :             *initState = (ret == INFO::OK)? INITIALIZED : ret;
      48           3 :             COMPILER_FENCE;
      49           3 :             return ret;
      50             :         }
      51             : 
      52          15 :         const ModuleInitState latchedInitState = *initState;
      53          15 :         if(latchedInitState == UNINITIALIZED || latchedInitState == BUSY)
      54             :         {
      55           0 :             cpu_Pause();
      56           0 :             continue;
      57             :         }
      58             : 
      59          15 :         ENSURE(latchedInitState == INITIALIZED || latchedInitState < 0);
      60          15 :         return (Status)latchedInitState;
      61           0 :     }
      62             : }
      63             : 
      64             : 
      65           0 : Status ModuleShutdown(volatile ModuleInitState* initState, void (*shutdown)())
      66             : {
      67             :     for(;;)
      68             :     {
      69           0 :         if(cpu_CAS(initState, INITIALIZED, BUSY))
      70             :         {
      71           0 :             shutdown();
      72           0 :             *initState = UNINITIALIZED;
      73           0 :             COMPILER_FENCE;
      74           0 :             return INFO::OK;
      75             :         }
      76             : 
      77           0 :         const ModuleInitState latchedInitState = *initState;
      78           0 :         if(latchedInitState == INITIALIZED || latchedInitState == BUSY)
      79             :         {
      80           0 :             cpu_Pause();
      81           0 :             continue;
      82             :         }
      83             : 
      84           0 :         if(latchedInitState == UNINITIALIZED)
      85           0 :             return INFO::SKIPPED;
      86             : 
      87           0 :         ENSURE(latchedInitState < 0);
      88           0 :         return (Status)latchedInitState;
      89           0 :     }
      90           3 : }

Generated by: LCOV version 1.13