]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EmulatorPkg/Unix/Host/Pthreads.c
EmulatorPkg: Apply uncrustify changes
[mirror_edk2.git] / EmulatorPkg / Unix / Host / Pthreads.c
index c60c298099e5f4e49e9b421d18f70be0600bfd00..ec3a38e573c4522c91b208bb0c61fa7ac7c081ec 100644 (file)
-/*++ @file
- POSIX Pthreads to emulate APs and implement threads
-
-Copyright (c) 2011, Apple Inc. All rights reserved.
-Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
-
-This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution.  The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-
-**/
-
-#include "Host.h"
-#include <pthread.h>
-
-
-UINTN
-EFIAPI
-PthreadMutexLock (
-  IN VOID *Mutex
-  )
-{
-  return (UINTN)pthread_mutex_lock ((pthread_mutex_t *)Mutex);
-}
-
-
-
-UINTN
-EFIAPI
-PthreadMutexUnLock (
-  IN VOID *Mutex
-  )
-{
-  return (UINTN)pthread_mutex_unlock ((pthread_mutex_t *)Mutex);
-}
-
-
-UINTN
-EFIAPI
-PthreadMutexTryLock (
-  IN VOID *Mutex
-  )
-{
-  return (UINTN)pthread_mutex_trylock ((pthread_mutex_t *)Mutex);
-}
-
-
-VOID *
-PthreadMutexInit (
-  IN VOID
-  )
-{
-  pthread_mutex_t *Mutex;
-  int             err;
-
-  Mutex = malloc (sizeof (pthread_mutex_t));
-  err = pthread_mutex_init (Mutex, NULL);
-  if (err == 0) {
-    return Mutex;
-  }
-
-  return NULL;
-}
-
-
-UINTN
-PthreadMutexDestroy (
-  IN VOID *Mutex
-  )
-{
-  if (Mutex != NULL) {
-    return pthread_mutex_destroy ((pthread_mutex_t *)Mutex);
-  }
-
-  return -1;
-}
-
-// Can't store this data on PthreadCreate stack so we need a global
-typedef struct {
-  pthread_mutex_t             Mutex;
-  THREAD_THUNK_THREAD_ENTRY   Start;
-} THREAD_MANGLE;
-
-THREAD_MANGLE mThreadMangle = {
-  PTHREAD_MUTEX_INITIALIZER,
-  NULL
-};
-
-VOID *
-SecFakePthreadStart (
-  VOID  *Context
-  )
-{
-  THREAD_THUNK_THREAD_ENTRY Start;
-  sigset_t                  SigMask;
-
-  // Save global on the stack before we unlock
-  Start   = mThreadMangle.Start;
-  pthread_mutex_unlock (&mThreadMangle.Mutex);
-
-  // Mask all signals to the APs
-  sigfillset (&SigMask);
-  pthread_sigmask (SIG_BLOCK, &SigMask, NULL);
-
-  //
-  // We have to start the thread in SEC as we need to follow
-  // OS X calling conventions. We can then call back into
-  // to the callers Start.
-  //
-  // This is a great example of how all problems in computer
-  // science can be solved by adding another level of indirection
-  //
- return  (VOID *)ReverseGasketUint64 ((CALL_BACK)Start, (UINTN)Context);
-}
-
-UINTN
-PthreadCreate (
-  IN  VOID                      *Thread,
-  IN  VOID                      *Attribute,
-  IN  THREAD_THUNK_THREAD_ENTRY Start,
-  IN  VOID                      *Context
-  )
-{
-  int         err;
-  BOOLEAN     EnabledOnEntry;
-
-  //
-  // Threads inherit interrupt state so disable interrupts before we start thread
-  //
-  if (SecInterruptEanbled ()) {
-    SecDisableInterrupt ();
-    EnabledOnEntry = TRUE;
-  } else {
-    EnabledOnEntry = FALSE;
-  }
-
-  // Aquire lock for global, SecFakePthreadStart runs in a different thread.
-  pthread_mutex_lock (&mThreadMangle.Mutex);
-  mThreadMangle.Start   = Start;
-
-  err = pthread_create (Thread, Attribute, SecFakePthreadStart, Context);
-  if (err != 0) {
-    // Thread failed to launch so release the lock;
-    pthread_mutex_unlock (&mThreadMangle.Mutex);
-  }
-
-  if (EnabledOnEntry) {
-    // Restore interrupt state
-    SecEnableInterrupt ();
-  }
-
-  return err;
-}
-
-
-VOID
-PthreadExit (
-  IN VOID *ValuePtr
-  )
-{
-  pthread_exit (ValuePtr);
-  return;
-}
-
-
-UINTN
-PthreadSelf (
-  VOID
-  )
-{
-  // POSIX currently allows pthread_t to be a structure or arithmetic type.
-  // Check out sys/types.h to make sure this will work if you are porting.
-  // On OS X (Darwin) pthread_t is a pointer to a structure so this code works.
-  return (UINTN)pthread_self ();
-}
-
-
-EMU_THREAD_THUNK_PROTOCOL gPthreadThunk = {
-  GasketPthreadMutexLock,
-  GasketPthreadMutexUnLock,
-  GasketPthreadMutexTryLock,
-  GasketPthreadMutexInit,
-  GasketPthreadMutexDestroy,
-  GasketPthreadCreate,
-  GasketPthreadExit,
-  GasketPthreadSelf
-};
-
-
-EFI_STATUS
-PthreadOpen (
-  IN  EMU_IO_THUNK_PROTOCOL   *This
-  )
-{
-  if (This->Instance != 0) {
-    // Only single instance is supported
-    return EFI_NOT_FOUND;
-  }
-
-  if (This->ConfigString[0] == L'0') {
-    // If AP count is zero no need for threads
-    return EFI_NOT_FOUND;
-  }
-
-  This->Interface = &gPthreadThunk;
-
-  return EFI_SUCCESS;
-}
-
-
-EFI_STATUS
-PthreadClose (
-  IN  EMU_IO_THUNK_PROTOCOL   *This
-  )
-{
-  return EFI_SUCCESS;
-}
-
-
-EMU_IO_THUNK_PROTOCOL gPthreadThunkIo = {
-  &gEmuThreadThunkProtocolGuid,
-  NULL,
-  NULL,
-  0,
-  GasketPthreadOpen,
-  GasketPthreadClose,
-  NULL
-};
-
-
+/*++ @file\r
+ POSIX Pthreads to emulate APs and implement threads\r
+\r
+Copyright (c) 2011, Apple Inc. All rights reserved.\r
+Copyright (c) 2011 - 2019, Intel Corporation. All rights reserved.<BR>\r
+\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+\r
+**/\r
+\r
+#include "Host.h"\r
+#include <pthread.h>\r
+\r
+UINTN\r
+EFIAPI\r
+PthreadMutexLock (\r
+  IN VOID  *Mutex\r
+  )\r
+{\r
+  return (UINTN)pthread_mutex_lock ((pthread_mutex_t *)Mutex);\r
+}\r
+\r
+UINTN\r
+EFIAPI\r
+PthreadMutexUnLock (\r
+  IN VOID  *Mutex\r
+  )\r
+{\r
+  return (UINTN)pthread_mutex_unlock ((pthread_mutex_t *)Mutex);\r
+}\r
+\r
+UINTN\r
+EFIAPI\r
+PthreadMutexTryLock (\r
+  IN VOID  *Mutex\r
+  )\r
+{\r
+  return (UINTN)pthread_mutex_trylock ((pthread_mutex_t *)Mutex);\r
+}\r
+\r
+VOID *\r
+PthreadMutexInit (\r
+  IN VOID\r
+  )\r
+{\r
+  pthread_mutex_t  *Mutex;\r
+  int              err;\r
+\r
+  Mutex = malloc (sizeof (pthread_mutex_t));\r
+  err   = pthread_mutex_init (Mutex, NULL);\r
+  if (err == 0) {\r
+    return Mutex;\r
+  }\r
+\r
+  return NULL;\r
+}\r
+\r
+UINTN\r
+PthreadMutexDestroy (\r
+  IN VOID  *Mutex\r
+  )\r
+{\r
+  if (Mutex != NULL) {\r
+    return pthread_mutex_destroy ((pthread_mutex_t *)Mutex);\r
+  }\r
+\r
+  return -1;\r
+}\r
+\r
+// Can't store this data on PthreadCreate stack so we need a global\r
+typedef struct {\r
+  pthread_mutex_t              Mutex;\r
+  THREAD_THUNK_THREAD_ENTRY    Start;\r
+} THREAD_MANGLE;\r
+\r
+THREAD_MANGLE  mThreadMangle = {\r
+  PTHREAD_MUTEX_INITIALIZER,\r
+  NULL\r
+};\r
+\r
+VOID *\r
+SecFakePthreadStart (\r
+  VOID  *Context\r
+  )\r
+{\r
+  THREAD_THUNK_THREAD_ENTRY  Start;\r
+  sigset_t                   SigMask;\r
+\r
+  // Save global on the stack before we unlock\r
+  Start = mThreadMangle.Start;\r
+  pthread_mutex_unlock (&mThreadMangle.Mutex);\r
+\r
+  // Mask all signals to the APs\r
+  sigfillset (&SigMask);\r
+  pthread_sigmask (SIG_BLOCK, &SigMask, NULL);\r
+\r
+  //\r
+  // We have to start the thread in SEC as we need to follow\r
+  // OS X calling conventions. We can then call back into\r
+  // to the callers Start.\r
+  //\r
+  // This is a great example of how all problems in computer\r
+  // science can be solved by adding another level of indirection\r
+  //\r
+  return (VOID *)ReverseGasketUint64 ((UINTN)Start, (UINTN)Context);\r
+}\r
+\r
+UINTN\r
+PthreadCreate (\r
+  IN  VOID                       *Thread,\r
+  IN  VOID                       *Attribute,\r
+  IN  THREAD_THUNK_THREAD_ENTRY  Start,\r
+  IN  VOID                       *Context\r
+  )\r
+{\r
+  int      err;\r
+  BOOLEAN  EnabledOnEntry;\r
+\r
+  //\r
+  // Threads inherit interrupt state so disable interrupts before we start thread\r
+  //\r
+  if (SecInterruptEanbled ()) {\r
+    SecDisableInterrupt ();\r
+    EnabledOnEntry = TRUE;\r
+  } else {\r
+    EnabledOnEntry = FALSE;\r
+  }\r
+\r
+  // Acquire lock for global, SecFakePthreadStart runs in a different thread.\r
+  pthread_mutex_lock (&mThreadMangle.Mutex);\r
+  mThreadMangle.Start = Start;\r
+\r
+  err = pthread_create (Thread, Attribute, SecFakePthreadStart, Context);\r
+  if (err != 0) {\r
+    // Thread failed to launch so release the lock;\r
+    pthread_mutex_unlock (&mThreadMangle.Mutex);\r
+  }\r
+\r
+  if (EnabledOnEntry) {\r
+    // Restore interrupt state\r
+    SecEnableInterrupt ();\r
+  }\r
+\r
+  return err;\r
+}\r
+\r
+VOID\r
+PthreadExit (\r
+  IN VOID  *ValuePtr\r
+  )\r
+{\r
+  pthread_exit (ValuePtr);\r
+  return;\r
+}\r
+\r
+UINTN\r
+PthreadSelf (\r
+  VOID\r
+  )\r
+{\r
+  // POSIX currently allows pthread_t to be a structure or arithmetic type.\r
+  // Check out sys/types.h to make sure this will work if you are porting.\r
+  // On OS X (Darwin) pthread_t is a pointer to a structure so this code works.\r
+  return (UINTN)pthread_self ();\r
+}\r
+\r
+EMU_THREAD_THUNK_PROTOCOL  gPthreadThunk = {\r
+  GasketPthreadMutexLock,\r
+  GasketPthreadMutexUnLock,\r
+  GasketPthreadMutexTryLock,\r
+  GasketPthreadMutexInit,\r
+  GasketPthreadMutexDestroy,\r
+  GasketPthreadCreate,\r
+  GasketPthreadExit,\r
+  GasketPthreadSelf\r
+};\r
+\r
+EFI_STATUS\r
+PthreadOpen (\r
+  IN  EMU_IO_THUNK_PROTOCOL  *This\r
+  )\r
+{\r
+  if (This->Instance != 0) {\r
+    // Only single instance is supported\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  if (This->ConfigString[0] == L'0') {\r
+    // If AP count is zero no need for threads\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  This->Interface = &gPthreadThunk;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PthreadClose (\r
+  IN  EMU_IO_THUNK_PROTOCOL  *This\r
+  )\r
+{\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EMU_IO_THUNK_PROTOCOL  gPthreadThunkIo = {\r
+  &gEmuThreadThunkProtocolGuid,\r
+  NULL,\r
+  NULL,\r
+  0,\r
+  GasketPthreadOpen,\r
+  GasketPthreadClose,\r
+  NULL\r
+};\r