1 /* 2 * Copyright (c) 2020 Intel Corporation. 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #include <stdbool.h> 8 #include <kernel.h> 9 #include <sys/atomic.h> 10 #include <timing/timing.h> 11 12 static bool has_inited; 13 static atomic_val_t started_ref; 14 timing_init(void)15void timing_init(void) 16 { 17 if (has_inited) { 18 return; 19 } 20 21 #if defined(CONFIG_BOARD_HAS_TIMING_FUNCTIONS) 22 board_timing_init(); 23 #elif defined(CONFIG_SOC_HAS_TIMING_FUNCTIONS) 24 soc_timing_init(); 25 #else 26 arch_timing_init(); 27 #endif 28 29 has_inited = true; 30 } 31 timing_start(void)32void timing_start(void) 33 { 34 if (atomic_inc(&started_ref) != 0) { 35 return; 36 } 37 38 #if defined(CONFIG_BOARD_HAS_TIMING_FUNCTIONS) 39 board_timing_start(); 40 #elif defined(CONFIG_SOC_HAS_TIMING_FUNCTIONS) 41 soc_timing_start(); 42 #else 43 arch_timing_start(); 44 #endif 45 } 46 timing_stop(void)47void timing_stop(void) 48 { 49 atomic_t old_value, new_value; 50 51 /* Make sure this does decrement past zero. */ 52 do { 53 old_value = atomic_get(&started_ref); 54 if (old_value <= 0) { 55 break; 56 } 57 58 new_value = old_value - 1; 59 } while (atomic_cas(&started_ref, old_value, new_value) == 0); 60 61 /* 62 * new_value may be uninitialized, so use old_value here. 63 */ 64 if (old_value > 1) { 65 return; 66 } 67 68 #if defined(CONFIG_BOARD_HAS_TIMING_FUNCTIONS) 69 board_timing_stop(); 70 #elif defined(CONFIG_SOC_HAS_TIMING_FUNCTIONS) 71 soc_timing_stop(); 72 #else 73 arch_timing_stop(); 74 #endif 75 } 76