+++ /dev/null
-/** @file \r
- setitimer and getitimer functions.\r
-\r
- Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
- This program and the accompanying materials are licensed and made available under\r
- the terms and conditions of the BSD License that accompanies this distribution.\r
- The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php.\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-**/\r
-#include <LibConfig.h>\r
-#include <sys/time.h>\r
-#include <time.h>\r
-#include <errno.h>\r
-#include <sys/signal.h>\r
-#include <signal.h>\r
-#include <unistd.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/UefiLib.h>\r
-\r
-STATIC EFI_EVENT RealTimer = NULL;\r
-STATIC EFI_EVENT VirtualTimer = NULL;\r
-STATIC EFI_EVENT ProfTimer = NULL;\r
-\r
-STATIC struct itimerval RealTimerInfo = {{0,0},{0,0}};\r
-STATIC struct itimerval VirtualTimerInfo = {{0,0},{0,0}};\r
-STATIC struct itimerval ProfTimerInfo = {{0,0},{0,0}};\r
-\r
-/**\r
- Function to queue the next iteration of the timer.\r
-\r
- This will copy the interval part of the struct into the value and (if \r
- non-zero), then queue the next timer event.\r
-\r
- @param[in] TimerInfo The timer info structure. \r
- @param[in] Event The EFI timer event.\r
-**/\r
-VOID\r
-EFIAPI\r
-SetNext (\r
- IN struct itimerval *TimerInfo,\r
- IN EFI_EVENT Event\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- CopyMem(&(TimerInfo->it_value), &(TimerInfo->it_interval), sizeof(struct timeval));\r
-\r
- //\r
- // If now zero then close and be done.\r
- //\r
- if (TimerInfo->it_value.tv_sec+TimerInfo->it_value.tv_usec == 0) {\r
- if (Event != NULL) {\r
- gBS->CloseEvent(Event);\r
- Event = NULL;\r
- }\r
- return;\r
- }\r
-\r
- //\r
- // Set up for the next loop.\r
- //\r
- Status = gBS->SetTimer (\r
- Event,\r
- TimerRelative,\r
- TimerInfo->it_value.tv_sec*10000000+TimerInfo->it_value.tv_usec*1000);\r
-\r
- if (EFI_ERROR(Status)) {\r
- gBS->CloseEvent(Event);\r
- Event = NULL;\r
- }\r
-}\r
-\r
-/**\r
- Notification function for real timer.\r
-\r
- @param[in] Event The event.\r
- @param[in] Context Ignored.\r
-**/\r
-VOID\r
-EFIAPI\r
-iTimerRealNotifyFunction (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-{\r
- raise(SIGALRM);\r
- SetNext(&RealTimerInfo, RealTimer);\r
-}\r
-\r
-/**\r
- Notification function for virtual timer.\r
-\r
- @param[in] Event The event.\r
- @param[in] Context Ignored.\r
-**/\r
-VOID\r
-EFIAPI\r
-iTimerVirtualNotifyFunction (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-{\r
- raise(SIGVTALRM);\r
- SetNext(&VirtualTimerInfo, VirtualTimer);\r
-}\r
-\r
-/**\r
- Notification function for prof timer.\r
-\r
- @param[in] Event The event.\r
- @param[in] Context Ignored.\r
-**/\r
-VOID\r
-EFIAPI\r
-iTimerProfNotifyFunction (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-{\r
- raise(SIGPROF);\r
- SetNext(&ProfTimerInfo, ProfTimer);\r
-}\r
-\r
-/**\r
- The setitimer() function sets the timer specified by which to the value \r
- specified in the structure pointed to by value, and if ovalue is not a null \r
- pointer, stores the previous value of the timer in the structure pointed to\r
- by ovalue. \r
-\r
- A timer value is defined by the itimerval structure. If it_value is non-zero,\r
- it indicates the time to the next timer expiration. If it_interval is \r
- non-zero, it specifies a value to be used in reloading it_value when the \r
- timer expires. Setting it_value to 0 disables a timer, regardless of the \r
- value of it_interval. Setting it_interval to 0 disables a timer after its \r
- next expiration (assuming it_value is non-zero). \r
-\r
- ITIMER_REAL\r
- Decrements in real time. A SIGALRM signal is delivered when this timer \r
- expires. \r
- \r
- ITIMER_VIRTUAL\r
- Decrements in process virtual time. It runs only when the process is \r
- executing. A SIGVTALRM signal is delivered when it expires. \r
-\r
- ITIMER_PROF\r
- Decrements both in process virtual time and when the system is running on \r
- behalf of the process. It is designed to be used by interpreters in \r
- statistically profiling the execution of interpreted programs. Each time \r
- the ITIMER_PROF timer expires, the SIGPROF signal is delivered. \r
-\r
- @param[in] which Which timer to set. Possible values are described above.\r
- @param[in] value The new value for this timer.\r
- @param[out] ovalue The old value for this timer.\r
-\r
- @retval 0 The operation was successful.\r
- @retval -1 The operation failed. see errno for more details.\r
-**/\r
-\r
-int setitimer(\r
- int which, \r
- const struct itimerval *value,\r
- struct itimerval *ovalue\r
- )\r
-{\r
- EFI_EVENT *EventPointer;\r
- EFI_EVENT_NOTIFY NotifyFunction;\r
- EFI_STATUS Status;\r
-\r
- if (value == NULL) {\r
- errno = EINVAL;\r
- return (-1);\r
- }\r
-\r
- if (which == ITIMER_REAL) {\r
- EventPointer = &RealTimer;\r
- NotifyFunction = iTimerRealNotifyFunction;\r
- if (ovalue != NULL) {\r
- CopyMem(ovalue, &RealTimerInfo, sizeof(struct itimerval));\r
- }\r
- CopyMem(&RealTimerInfo, value, sizeof(struct itimerval));\r
- } else if (which == ITIMER_VIRTUAL) {\r
- EventPointer = &VirtualTimer;\r
- NotifyFunction = iTimerVirtualNotifyFunction;\r
- if (ovalue != NULL) {\r
- CopyMem(ovalue, &VirtualTimerInfo, sizeof(struct itimerval));\r
- }\r
- CopyMem(&VirtualTimerInfo, value, sizeof(struct itimerval));\r
- } else if (which == ITIMER_PROF) {\r
- EventPointer = &ProfTimer;\r
- NotifyFunction = iTimerProfNotifyFunction;\r
- if (ovalue != NULL) {\r
- CopyMem(ovalue, &ProfTimerInfo, sizeof(struct itimerval));\r
- }\r
- CopyMem(&ProfTimerInfo, value, sizeof(struct itimerval));\r
- } else {\r
- errno = EINVAL;\r
- return (-1);\r
- }\r
-\r
- if (*EventPointer != NULL) {\r
- gBS->CloseEvent(*EventPointer);\r
- *EventPointer = NULL;\r
- }\r
-\r
- //\r
- // This was a 'please cancel me' request.\r
- //\r
- if (value->it_value.tv_sec+value->it_value.tv_usec == 0) {\r
- return 0;\r
- }\r
-\r
- Status = gBS->CreateEvent (\r
- EVT_TIMER|EVT_NOTIFY_SIGNAL,\r
- EfiGetCurrentTpl(),\r
- NotifyFunction,\r
- NULL, // no context\r
- EventPointer);\r
-\r
- if (EFI_ERROR(Status)) {\r
- errno = EINVAL;\r
- return (-1);\r
- }\r
-\r
- Status = gBS->SetTimer (\r
- *EventPointer,\r
- TimerRelative,\r
- value->it_value.tv_sec*10000000+value->it_value.tv_usec*1000);\r
-\r
- if (EFI_ERROR(Status)) {\r
- gBS->CloseEvent(*EventPointer);\r
- *EventPointer = NULL;\r
- errno = EINVAL;\r
- return (-1);\r
- }\r
-\r
- return 0;\r
-}\r
-\r
-/**\r
- Function to get the current state of a timer.\r
-\r
- @param[in] which The identifier of the timer to get. See setitimer for \r
- details.\r
- @param[in] value The pointer to populate. must be pre-allocated to size.\r
-\r
- @return 0 The operation was successful.\r
- @return -1 The operation failed. \r
- This means that value or which had an invalid value.\r
-**/\r
-int getitimer(\r
- int which, \r
- struct itimerval *value\r
- )\r
-{\r
-\r
- if (value == NULL) {\r
- errno = EINVAL;\r
- return (-1);\r
- }\r
-\r
- if (which == ITIMER_REAL) {\r
- CopyMem(value, &RealTimerInfo, sizeof(struct itimerval));\r
- } else if (which == ITIMER_VIRTUAL) {\r
- CopyMem(value, &VirtualTimerInfo, sizeof(struct itimerval));\r
- } else if (which == ITIMER_PROF) {\r
- CopyMem(value, &ProfTimerInfo, sizeof(struct itimerval));\r
- } else {\r
- errno = EINVAL;\r
- return (-1);\r
- }\r
-\r
- return 0;\r
-}\r