REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the EmulatorPkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Ray Ni <ray.ni@intel.com>
		
			
				
	
	
		
			216 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			216 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*++ @file
 | |
|  POSIX Pthreads to emulate APs and implement threads
 | |
| 
 | |
| Copyright (c) 2011, Apple Inc. All rights reserved.
 | |
| Copyright (c) 2011 - 2019, Intel Corporation. All rights reserved.<BR>
 | |
| 
 | |
| SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| 
 | |
| 
 | |
| **/
 | |
| 
 | |
| #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 ((UINTN)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;
 | |
|   }
 | |
| 
 | |
|   // Acquire 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
 | |
| };
 |