xref: /rockchip-linux_mpp/osal/mpp_singleton.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1*437bfbebSnyanmisaka /* SPDX-License-Identifier: Apache-2.0 OR MIT */
2*437bfbebSnyanmisaka /*
3*437bfbebSnyanmisaka  * Copyright (c) 2024 Rockchip Electronics Co., Ltd.
4*437bfbebSnyanmisaka  */
5*437bfbebSnyanmisaka 
6*437bfbebSnyanmisaka #define  MODULE_TAG "mpp_singleton"
7*437bfbebSnyanmisaka 
8*437bfbebSnyanmisaka #include <stdio.h>
9*437bfbebSnyanmisaka #include <stdlib.h>
10*437bfbebSnyanmisaka #include <string.h>
11*437bfbebSnyanmisaka 
12*437bfbebSnyanmisaka #include "mpp_env.h"
13*437bfbebSnyanmisaka #include "mpp_time.h"
14*437bfbebSnyanmisaka #include "mpp_singleton.h"
15*437bfbebSnyanmisaka 
16*437bfbebSnyanmisaka #define sgln_dbg(fmt, ...) \
17*437bfbebSnyanmisaka     do { \
18*437bfbebSnyanmisaka         if (sgln_debug) \
19*437bfbebSnyanmisaka             printf(MODULE_TAG ": " fmt, ##__VA_ARGS__); \
20*437bfbebSnyanmisaka     } while (0)
21*437bfbebSnyanmisaka 
22*437bfbebSnyanmisaka static MppSingletonInfo sgln_info[MPP_SGLN_MAX_CNT] = {0};
23*437bfbebSnyanmisaka static rk_u32 sgln_max_name_len = 12;
24*437bfbebSnyanmisaka static rk_u64 sgln_mask = 0;
25*437bfbebSnyanmisaka static rk_u32 sgln_debug = 0;
26*437bfbebSnyanmisaka 
mpp_singleton_add(MppSingletonInfo * info,const char * caller)27*437bfbebSnyanmisaka rk_s32 mpp_singleton_add(MppSingletonInfo *info, const char *caller)
28*437bfbebSnyanmisaka {
29*437bfbebSnyanmisaka     mpp_env_get_u32("mpp_sgln_debug", &sgln_debug, 0);
30*437bfbebSnyanmisaka 
31*437bfbebSnyanmisaka     if (!info) {
32*437bfbebSnyanmisaka         sgln_dbg("can not add NULL info at %s\n", caller);
33*437bfbebSnyanmisaka         return rk_nok;
34*437bfbebSnyanmisaka     }
35*437bfbebSnyanmisaka 
36*437bfbebSnyanmisaka     if (info->id >= MPP_SGLN_MAX_CNT) {
37*437bfbebSnyanmisaka         sgln_dbg("id %d larger than max %d at %s\n", info->id, MPP_SGLN_MAX_CNT, caller);
38*437bfbebSnyanmisaka         return rk_nok;
39*437bfbebSnyanmisaka     }
40*437bfbebSnyanmisaka 
41*437bfbebSnyanmisaka     if (sgln_mask & ((rk_u64)1 << info->id)) {
42*437bfbebSnyanmisaka         sgln_dbg("info %d has been registered at %s\n", info->id, caller);
43*437bfbebSnyanmisaka         return rk_nok;
44*437bfbebSnyanmisaka     }
45*437bfbebSnyanmisaka 
46*437bfbebSnyanmisaka     sgln_info[info->id] = *info;
47*437bfbebSnyanmisaka     sgln_mask |= ((rk_u64)1 << info->id);
48*437bfbebSnyanmisaka 
49*437bfbebSnyanmisaka     {
50*437bfbebSnyanmisaka         rk_u32 name_len = strlen(info->name);
51*437bfbebSnyanmisaka 
52*437bfbebSnyanmisaka         if (name_len > sgln_max_name_len)
53*437bfbebSnyanmisaka             sgln_max_name_len = name_len;
54*437bfbebSnyanmisaka     }
55*437bfbebSnyanmisaka 
56*437bfbebSnyanmisaka     sgln_dbg("info %2d %-*s registered at %s\n", info->id,
57*437bfbebSnyanmisaka              sgln_max_name_len, info->name, caller);
58*437bfbebSnyanmisaka 
59*437bfbebSnyanmisaka     return rk_ok;
60*437bfbebSnyanmisaka }
61*437bfbebSnyanmisaka 
mpp_singleton_deinit(void)62*437bfbebSnyanmisaka static void mpp_singleton_deinit(void)
63*437bfbebSnyanmisaka {
64*437bfbebSnyanmisaka     rk_s32 i;
65*437bfbebSnyanmisaka 
66*437bfbebSnyanmisaka     sgln_dbg("deinit enter\n");
67*437bfbebSnyanmisaka 
68*437bfbebSnyanmisaka     /* NOTE: revert deinit order */
69*437bfbebSnyanmisaka     for (i = MPP_SGLN_MAX_CNT - 1; i >= 0; i--) {
70*437bfbebSnyanmisaka         if (sgln_mask & ((rk_u64)1 << i)) {
71*437bfbebSnyanmisaka             MppSingletonInfo *info = &sgln_info[i];
72*437bfbebSnyanmisaka 
73*437bfbebSnyanmisaka             if (info->deinit) {
74*437bfbebSnyanmisaka                 sgln_dbg("info %2d %-*s deinit start\n", info->id,
75*437bfbebSnyanmisaka                          sgln_max_name_len, info->name);
76*437bfbebSnyanmisaka 
77*437bfbebSnyanmisaka                 info->deinit();
78*437bfbebSnyanmisaka 
79*437bfbebSnyanmisaka                 sgln_dbg("info %2d %-*s deinit finish\n", info->id,
80*437bfbebSnyanmisaka                          sgln_max_name_len, info->name);
81*437bfbebSnyanmisaka             }
82*437bfbebSnyanmisaka         }
83*437bfbebSnyanmisaka     }
84*437bfbebSnyanmisaka 
85*437bfbebSnyanmisaka     sgln_dbg("deinit leave\n");
86*437bfbebSnyanmisaka }
87*437bfbebSnyanmisaka 
mpp_singleton_init(void)88*437bfbebSnyanmisaka __attribute__((constructor(65535))) static void mpp_singleton_init(void)
89*437bfbebSnyanmisaka {
90*437bfbebSnyanmisaka     rk_s64 sum = 0;
91*437bfbebSnyanmisaka     rk_s32 i;
92*437bfbebSnyanmisaka 
93*437bfbebSnyanmisaka     sgln_dbg("init enter\n");
94*437bfbebSnyanmisaka 
95*437bfbebSnyanmisaka     /* NOTE: call atexit first to avoid init crash but not deinit */
96*437bfbebSnyanmisaka     atexit(mpp_singleton_deinit);
97*437bfbebSnyanmisaka 
98*437bfbebSnyanmisaka     for (i = 0; i < MPP_SGLN_MAX_CNT; i++) {
99*437bfbebSnyanmisaka         if (sgln_mask & ((rk_u64)1 << i)) {
100*437bfbebSnyanmisaka             MppSingletonInfo *info = &sgln_info[i];
101*437bfbebSnyanmisaka 
102*437bfbebSnyanmisaka             if (info->init) {
103*437bfbebSnyanmisaka                 rk_s64 time;
104*437bfbebSnyanmisaka 
105*437bfbebSnyanmisaka                 sgln_dbg("info %2d %-*s init start\n", info->id,
106*437bfbebSnyanmisaka                          sgln_max_name_len, info->name);
107*437bfbebSnyanmisaka 
108*437bfbebSnyanmisaka                 time = mpp_time();
109*437bfbebSnyanmisaka                 info->init();
110*437bfbebSnyanmisaka                 time = mpp_time() - time;
111*437bfbebSnyanmisaka                 sum += time;
112*437bfbebSnyanmisaka 
113*437bfbebSnyanmisaka                 sgln_dbg("info %2d %-*s init finish %lld us\n", info->id,
114*437bfbebSnyanmisaka                          sgln_max_name_len, info->name, time);
115*437bfbebSnyanmisaka             }
116*437bfbebSnyanmisaka         }
117*437bfbebSnyanmisaka     }
118*437bfbebSnyanmisaka 
119*437bfbebSnyanmisaka     sgln_dbg("init leave total %lld us\n", sum);
120*437bfbebSnyanmisaka }
121