| #ifndef PLATFORM_LIBS_H | |
| #define PLATFORM_LIBS_H | |
| /** | |
| * Copyright (c) 2019, The Linux Foundation. All rights reserved. | |
| * | |
| * Redistribution and use in source and binary forms, with or without | |
| * modification, are permitted provided that the following conditions are | |
| * met: | |
| * * Redistributions of source code must retain the above copyright | |
| * notice, this list of conditions and the following disclaimer. | |
| * * Redistributions in binary form must reproduce the above | |
| * copyright notice, this list of conditions and the following | |
| * disclaimer in the documentation and/or other materials provided | |
| * with the distribution. | |
| * * Neither the name of The Linux Foundation nor the names of its | |
| * contributors may be used to endorse or promote products derived | |
| * from this software without specific prior written permission. | |
| * | |
| * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED | |
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT | |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS | |
| * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | |
| * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |
| * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | |
| * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | |
| * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| */ | |
| /* | |
| Platfrom Library Loader | |
| ----------------------- | |
| proj/platform_libs is a library to help manage interdependencies between | |
| other libraries. | |
| to use you will need to add | |
| incs = { 'proj/platform_libs' } | |
| in source of the library implementation define the entry point | |
| #include "platform_libs.h" | |
| PL_DEFINE(svfs, svfs_init, svfs_deinit); | |
| Platfrom Library List | |
| --------------------- | |
| This list contains top level libraries to be initialized at boot. To make | |
| sure that this library is loaded you would need to call PLRegister or | |
| PLRegisterDefault in your scons build command. | |
| Handling Interdependencies and Order | |
| ------------------------------------ | |
| To make sure that library A is loaded before library B, library B's | |
| constructor and destructor should initialize and cleanup libraryB. | |
| #include "platform_libs.h" | |
| PL_DEP(libraryB) | |
| void libraryA_deinit(void) { | |
| PL_DEINIT(libraryB); | |
| } | |
| int libraryA_init(void) { | |
| int nErr = 0; | |
| // my init code | |
| VERIFY(0 == PL_INIT(libraryB)); | |
| bail: | |
| if(nErr) { libraryA_deinit() } | |
| return nErr; | |
| } | |
| libraryB does not need to appear in the platform library list. | |
| */ | |
| #include <stdint.h> | |
| struct platform_lib { | |
| const char* name; | |
| uint32_t uRefs; | |
| int nErr; | |
| int (*init)(void); | |
| void (*deinit)(void); | |
| }; | |
| /** | |
| * use this macro to pull in external dependencies | |
| */ | |
| #ifdef __cplusplus | |
| #define PL_DEP(name)\ | |
| extern "C" {\ | |
| extern struct platform_lib* _pl_##name(void); \ | |
| } | |
| #else | |
| #define PL_DEP(name)\ | |
| extern struct platform_lib* _pl_##name(void); | |
| #endif /* __cplusplus */ | |
| /** | |
| * should be declared in source in the library | |
| * if constructor fails, destructor is not called | |
| */ | |
| #ifdef __cplusplus | |
| #define PL_DEFINE(name, init, deinit) \ | |
| extern "C" {\ | |
| struct platform_lib* _pl_##name(void) {\ | |
| static struct platform_lib _gpl_##name = { #name, 0, -1, init, deinit };\ | |
| return &_gpl_##name;\ | |
| }\ | |
| } | |
| #else | |
| #define PL_DEFINE(name, init, deinit) \ | |
| struct platform_lib* _pl_##name(void) {\ | |
| static struct platform_lib _gpl_##name = { #name, 0, -1, init, deinit };\ | |
| return &_gpl_##name;\ | |
| } | |
| #endif /* __cplusplus */ | |
| /** | |
| * should be added to platform_libs_list.c pl_list table | |
| * for all top level modules | |
| */ | |
| #define PL_ENTRY(name) _pl_##name | |
| /** | |
| * should be called within a constructor to ensure that a | |
| * dependency has been initialized. so if foo depends on bar | |
| * | |
| * #include "bar.h" | |
| * int foo_init() { | |
| * return PL_INIT(bar); | |
| * } | |
| */ | |
| #define PL_INIT(name) pl_lib_init(PL_ENTRY(name)) | |
| /** | |
| * should be called within a destructor to ensure that a | |
| * dependency has been cleaned up | |
| */ | |
| #define PL_DEINIT(name) pl_lib_deinit(PL_ENTRY(name)) | |
| #ifdef __cplusplus | |
| extern "C" { | |
| #endif /* __cplusplus */ | |
| /** | |
| * initalize the static list of library constructors and destructors | |
| * should be called from main() | |
| * | |
| * see platform_libs_list.h to add high level libraries | |
| * | |
| */ | |
| int pl_init(void); | |
| /** | |
| * calls all the destructors. | |
| */ | |
| void pl_deinit(void); | |
| /** | |
| * initialize a single library. called via PL_INIT | |
| */ | |
| int pl_lib_init(struct platform_lib* (*pl)(void)); | |
| /** | |
| * deinitialize a single library called via PL_DEINIT | |
| */ | |
| void pl_lib_deinit(struct platform_lib* (*pl)(void)); | |
| #ifdef __cplusplus | |
| } | |
| #endif | |
| #endif //PLATFORM_LIBS |