Skip to content

Commit

Permalink
Merge pull request #887 from jphickey/fix-886-library-table
Browse files Browse the repository at this point in the history
Fix #886, library table id management
  • Loading branch information
yammajamma authored Sep 17, 2020
2 parents c879bb4 + 16e2c0e commit 36695e9
Show file tree
Hide file tree
Showing 6 changed files with 302 additions and 131 deletions.
37 changes: 37 additions & 0 deletions fsw/cfe-core/src/es/cfe_es_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -1685,6 +1685,25 @@ int32 CFE_ES_AppID_ToIndex(uint32 AppId, uint32 *Idx)
return CFE_SUCCESS;
}

/*
* A conversion function to obtain an index value correlating to a LibID
* This is a zero based value that can be used for indexing into a table.
*/
int32 CFE_ES_LibID_ToIndex(uint32 LibId, uint32 *Idx)
{
if (LibId >= CFE_PLATFORM_ES_MAX_LIBRARIES)
{
return CFE_ES_BAD_ARGUMENT; /* these do not have a dedicated error */
}

/*
* Currently this is a direct/simple pass through.
* Will evolve in a future rev to make it more safe.
*/
*Idx = LibId;
return CFE_SUCCESS;
}

/*
* A conversion function to obtain an index value correlating to an TaskID
* This is a zero based value that can be used for indexing into a table.
Expand Down Expand Up @@ -1777,6 +1796,24 @@ CFE_ES_AppRecord_t *CFE_ES_LocateAppRecordByID(uint32 AppID)
return AppRecPtr;
}

extern CFE_ES_LibRecord_t* CFE_ES_LocateLibRecordByID(uint32 LibID)
{
CFE_ES_LibRecord_t *LibRecPtr;
uint32 Idx;

if (CFE_ES_LibID_ToIndex(LibID, &Idx) == CFE_SUCCESS)
{
LibRecPtr = &CFE_ES_Global.LibTable[Idx];
}
else
{
LibRecPtr = NULL;
}

return LibRecPtr;
}


/*
* Note - this gets the table entry pointer but does not dereference or
* otherwise check/validate said pointer, as that would have to be done while
Expand Down
33 changes: 20 additions & 13 deletions fsw/cfe-core/src/es/cfe_es_apps.c
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,8 @@ int32 CFE_ES_LoadLibrary(uint32 *LibraryIdPtr,
CFE_ES_LibRecord_t * LibSlotPtr;
size_t StringLength;
int32 Status;
uint32 CheckSlot;
uint32 LibIndex;
uint32 PendingLibId;
osal_id_t ModuleId;
bool IsModuleLoaded;

Expand All @@ -576,7 +577,7 @@ int32 CFE_ES_LoadLibrary(uint32 *LibraryIdPtr,
* (currently sized to OS_MAX_API_NAME, but not assuming that will always be)
*/
StringLength = strlen(LibName);
if (StringLength >= sizeof(CFE_ES_Global.LibTable[0].LibName))
if (StringLength >= sizeof(LibSlotPtr->LibName))
{
return CFE_ES_BAD_ARGUMENT;
}
Expand All @@ -585,16 +586,17 @@ int32 CFE_ES_LoadLibrary(uint32 *LibraryIdPtr,
** Allocate an ES_LibTable entry
*/
IsModuleLoaded = false;
LibSlotPtr = NULL;
FunctionPointer = NULL;
ModuleId = OS_OBJECT_ID_UNDEFINED;
PendingLibId = 0xFFFFFFFF;
Status = CFE_ES_ERR_LOAD_LIB; /* error that will be returned if no slots found */
CFE_ES_LockSharedData(__func__,__LINE__);
for ( CheckSlot = 0; CheckSlot < CFE_PLATFORM_ES_MAX_LIBRARIES; CheckSlot++ )
LibSlotPtr = CFE_ES_Global.LibTable;
for ( LibIndex = 0; LibIndex < CFE_PLATFORM_ES_MAX_LIBRARIES; ++LibIndex )
{
if (CFE_ES_Global.LibTable[CheckSlot].RecordUsed)
if (CFE_ES_LibRecordIsUsed(LibSlotPtr))
{
if (strcmp(CFE_ES_Global.LibTable[CheckSlot].LibName, LibName) == 0)
if (strcmp(LibSlotPtr->LibName, LibName) == 0)
{
/*
* Indicate to caller that the library is already loaded.
Expand All @@ -603,29 +605,34 @@ int32 CFE_ES_LoadLibrary(uint32 *LibraryIdPtr,
* Do nothing more; not logging this event as it may or may
* not be an error.
*/
*LibraryIdPtr = CheckSlot;
*LibraryIdPtr = CFE_ES_LibRecordGetID(LibSlotPtr);
Status = CFE_ES_LIB_ALREADY_LOADED;
break;
}
}
else if (LibSlotPtr == NULL)
else if (PendingLibId == 0xFFFFFFFF)
{
/* Remember list position as possible place for new entry. */
LibSlotPtr = &CFE_ES_Global.LibTable[CheckSlot];
*LibraryIdPtr = CheckSlot;
PendingLibId = LibIndex;
Status = CFE_SUCCESS;
}
else
{
/* No action */
}

++LibSlotPtr;
}

if (Status == CFE_SUCCESS)
{
/* reset back to the saved index that was free */
LibSlotPtr = CFE_ES_LocateLibRecordByID(PendingLibId);

/* reserve the slot while still under lock */
strcpy(LibSlotPtr->LibName, LibName);
LibSlotPtr->RecordUsed = true;
CFE_ES_LibRecordSetUsed(LibSlotPtr, PendingLibId);
*LibraryIdPtr = PendingLibId;
}

CFE_ES_UnlockSharedData(__func__,__LINE__);
Expand Down Expand Up @@ -761,8 +768,8 @@ int32 CFE_ES_LoadLibrary(uint32 *LibraryIdPtr,
OS_ModuleUnload( ModuleId );
}

/* Release Slot - No need to lock as it is resetting just a single bool value */
LibSlotPtr->RecordUsed = false;
/* Release Slot - No need to lock as it is resetting just a single value */
CFE_ES_LibRecordSetFree(LibSlotPtr);
}

return(Status);
Expand Down
90 changes: 90 additions & 0 deletions fsw/cfe-core/src/es/cfe_es_global.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,17 @@ extern CFE_ES_ResetData_t *CFE_ES_ResetDataPtr;
*/
extern CFE_ES_AppRecord_t* CFE_ES_LocateAppRecordByID(uint32 AppID);

/**
* @brief Locate the Library table entry correlating with a given Lib ID.
*
* This only returns a pointer to the table entry and does _not_
* otherwise check/validate the entry.
*
* @param[in] LibID the Lib ID to locate
* @return pointer to Library Table entry for the given Lib ID
*/
extern CFE_ES_LibRecord_t* CFE_ES_LocateLibRecordByID(uint32 LibID);

/**
* @brief Locate the task table entry correlating with a given task ID.
*
Expand Down Expand Up @@ -273,6 +284,85 @@ static inline bool CFE_ES_AppRecordIsMatch(const CFE_ES_AppRecord_t *AppRecPtr,
CFE_ES_AppRecordGetID(AppRecPtr) == AppID);
}

/**
* @brief Check if a Library record is in use or free/empty
*
* This routine checks if the Lib table entry is in use or if it is free
*
* As this dereferences fields within the record, global data must be
* locked prior to invoking this function.
*
* @param[in] LibRecPtr pointer to Lib table entry
* @returns true if the entry is in use/configured, or false if it is free/empty
*/
static inline bool CFE_ES_LibRecordIsUsed(const CFE_ES_LibRecord_t *LibRecPtr)
{
return (LibRecPtr->RecordUsed);
}

/**
* @brief Get the ID value from a Library table entry
*
* This routine converts the table entry back to an abstract ID.
*
* @param[in] LibRecPtr pointer to Lib table entry
* @returns LibID of entry
*/
static inline uint32 CFE_ES_LibRecordGetID(const CFE_ES_LibRecord_t *LibRecPtr)
{
/*
* The initial implementation does not store the ID in the entry;
* the ID is simply the zero-based index into the table.
*/
return (LibRecPtr - CFE_ES_Global.LibTable);
}

/**
* @brief Marks a Library table entry as used (not free)
*
* This sets the internal field(s) within this entry, and marks
* it as being associated with the given Lib ID.
*
* @param[in] LibRecPtr pointer to Lib table entry
* @param[in] LibID the Lib ID of this entry
*/
static inline void CFE_ES_LibRecordSetUsed(CFE_ES_LibRecord_t *LibRecPtr, uint32 LibID)
{
LibRecPtr->RecordUsed = true;
}

/**
* @brief Set a Library record table entry free (not used)
*
* This clears the internal field(s) within this entry, and allows the
* memory to be re-used in the future.
*
* @param[in] LibRecPtr pointer to Lib table entry
*/
static inline void CFE_ES_LibRecordSetFree(CFE_ES_LibRecord_t *LibRecPtr)
{
LibRecPtr->RecordUsed = false;
}

/**
* @brief Check if a Library record is a match for the given LibID
*
* This routine confirms that the previously-located record is valid
* and matches the expected Lib ID.
*
* As this dereferences fields within the record, global data must be
* locked prior to invoking this function.
*
* @param[in] LibRecPtr pointer to Lib table entry
* @param[in] LibID expected Lib ID
* @returns true if the entry matches the given Lib ID
*/
static inline bool CFE_ES_LibRecordIsMatch(const CFE_ES_LibRecord_t *LibRecPtr, uint32 LibID)
{
return (LibRecPtr != NULL && CFE_ES_LibRecordIsUsed(LibRecPtr) &&
CFE_ES_LibRecordGetID(LibRecPtr) == LibID);
}

/**
* @brief Get the ID value from an Task table entry
*
Expand Down
24 changes: 24 additions & 0 deletions fsw/cfe-core/src/inc/cfe_es.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,30 @@ static inline uint32 CFE_ES_ResourceID_FromInteger(unsigned long Value)
*/
int32 CFE_ES_AppID_ToIndex(uint32 AppID, uint32 *Idx);

/**
* @brief Obtain an index value correlating to an ES Library ID
*
* This calculates a zero based integer value that may be used for indexing
* into a local resource table/array.
*
* Index values are only guaranteed to be unique for resources of the same
* type. For instance, the indices corresponding to two [valid] Library
* IDs will never overlap, but the index of an Library and a library ID
* may be the same. Furthermore, indices may be reused if a resource is
* deleted and re-created.
*
* @note There is no inverse of this function - indices cannot be converted
* back to the original LibID value. The caller should retain the original ID
* for future use.
*
* @param[in] LibID Library ID to convert
* @param[out] Idx Buffer where the calculated index will be stored
*
* @return Execution status, see @ref CFEReturnCodes
* @retval #CFE_SUCCESS @copybrief CFE_SUCCESS
*/
int32 CFE_ES_LibID_ToIndex(uint32 LibID, uint32 *Idx);

/**
* @brief Obtain an index value correlating to an ES Task ID
*
Expand Down
Loading

0 comments on commit 36695e9

Please sign in to comment.