+ return gActivePeriodicSmiLibraryHandler;\r
+}\r
+\r
+/**\r
+ Internal worker function that moves the specified periodic SMI handler from the\r
+ list of managed periodic SMI handlers to the list of free periodic SMI handlers.\r
+\r
+ @param[in] PeriodicSmiLibraryHandler Pointer to the periodic SMI handler to be reclaimed.\r
+**/\r
+VOID\r
+ReclaimPeriodicSmiLibraryHandler (\r
+ PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT *PeriodicSmiLibraryHandler\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+\r
+ ASSERT (PeriodicSmiLibraryHandler->DispatchHandle == NULL);\r
+ if (PeriodicSmiLibraryHandler->Stack != NULL) {\r
+ FreePages (\r
+ PeriodicSmiLibraryHandler->Stack,\r
+ EFI_SIZE_TO_PAGES (PeriodicSmiLibraryHandler->StackSize)\r
+ );\r
+ PeriodicSmiLibraryHandler->Stack = NULL;\r
+ }\r
+ RemoveEntryList (&PeriodicSmiLibraryHandler->Link);\r
+ //\r
+ // Insert to gFreePeriodicSmiLibraryHandlers in the reverse order of the address of PeriodicSmiLibraryHandler\r
+ //\r
+ for ( Link = GetFirstNode (&gFreePeriodicSmiLibraryHandlers)\r
+ ; !IsNull (&gFreePeriodicSmiLibraryHandlers, Link)\r
+ ; Link = GetNextNode (&gFreePeriodicSmiLibraryHandlers, Link)\r
+ ) {\r
+ if (Link < &PeriodicSmiLibraryHandler->Link) {\r
+ break;\r
+ }\r
+ }\r
+ InsertTailList (Link, &PeriodicSmiLibraryHandler->Link);\r
+}\r
+\r
+/**\r
+ Add the additional entries to the list of free periodic SMI handlers.\r
+ The function is assumed to be called only when the list of free periodic SMI\r
+ handlers is empty.\r
+\r
+ @retval TRUE The additional entries were added.\r
+ @retval FALSE There was no available resource for the additional entries.\r
+**/\r
+BOOLEAN\r
+EnlargeFreePeriodicSmiLibraryHandlerList (\r
+ VOID\r
+ )\r
+{\r
+ UINTN Index;\r
+ PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT *PeriodicSmiLibraryHandlers;\r
+\r
+ //\r
+ // The function is assumed to be called only when the list of free periodic SMI library\r
+ // handlers is empty.\r
+ //\r
+ ASSERT (IsListEmpty (&gFreePeriodicSmiLibraryHandlers));\r
+\r
+ PeriodicSmiLibraryHandlers = AllocatePool (\r
+ PERIODIC_SMI_LIBRARY_ALLOCATE_SIZE * sizeof (PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT)\r
+ );\r
+ if (PeriodicSmiLibraryHandlers == NULL) {\r
+ return FALSE;\r
+ }\r
+ \r
+ //\r
+ // Add the entries to the list in the reverse order of the their memory address\r
+ //\r
+ for (Index = 0; Index < PERIODIC_SMI_LIBRARY_ALLOCATE_SIZE; Index++) {\r
+ PeriodicSmiLibraryHandlers[Index].Signature = PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT_SIGNATURE;\r
+ InsertHeadList (&gFreePeriodicSmiLibraryHandlers, &PeriodicSmiLibraryHandlers[Index].Link);\r
+ }\r
+\r
+ return TRUE;\r