github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/cpvmm/vmm/utils/lock.c (about)

     1  /*
     2   * Copyright (c) 2013 Intel Corporation
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *     http://www.apache.org/licenses/LICENSE-2.0
     8   * Unless required by applicable law or agreed to in writing, software
     9   * distributed under the License is distributed on an "AS IS" BASIS,
    10   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11   * See the License for the specific language governing permissions and
    12   * limitations under the License.
    13   */
    14  
    15  #include "libc.h"
    16  #include "hw_includes.h"
    17  #include "lock.h"
    18  #include "ipc.h"
    19  #include "vmm_dbg.h"
    20  #include "file_codes.h"
    21  
    22  #define VMM_DEADLOOP()                 VMM_DEADLOOP_LOG(LOCK_C)
    23  #define VMM_ASSERT(__condition)        VMM_ASSERT_LOG(LOCK_C, __condition)
    24  #define VMM_ASSERT_NOLOCK(__condition) VMM_ASSERT_NOLOCK_LOG(LOCK_C, __condition)
    25  
    26  // lock_try_acquire - returns TRUE if lock was acquired and FALSE if not
    27  BOOLEAN lock_try_acquire(VMM_LOCK* lock);
    28  
    29  
    30  void lock_acquire(VMM_LOCK* lock)
    31  {
    32      (void)lock;
    33      CPU_ID this_cpu_id = hw_cpu_id();
    34  
    35      if (! lock) {
    36          return; // error
    37      }
    38      while (FALSE == lock_try_acquire(lock)) {
    39          VMM_ASSERT_NOLOCK(lock->owner_cpu_id != this_cpu_id);
    40          hw_pause();
    41      }
    42      lock->owner_cpu_id = this_cpu_id;
    43  }
    44  
    45  void interruptible_lock_acquire(VMM_LOCK* lock)
    46  {
    47      (void)lock;
    48      CPU_ID this_cpu_id = hw_cpu_id();
    49      BOOLEAN ipc_processed = FALSE;
    50  
    51      if (!lock) {
    52          return; // error
    53      }
    54      while (FALSE == lock_try_acquire(lock)) {
    55          ipc_processed = ipc_process_one_ipc();
    56          if(FALSE == ipc_processed) {
    57              hw_pause();
    58          }
    59      }
    60      lock->owner_cpu_id = this_cpu_id;
    61  }
    62  
    63  void lock_release(VMM_LOCK* lock)
    64  {
    65      (void)lock;
    66      if (!lock) {
    67          return;  // error
    68      }
    69      lock->owner_cpu_id = (CPU_ID)-1;
    70  #if 0
    71      hw_interlocked_assign((INT32 volatile *)(&(lock->uint32_lock)), 0);
    72  #else
    73      lock->uint32_lock= 0;
    74  #endif
    75  }
    76  
    77  BOOLEAN lock_try_acquire(VMM_LOCK* lock)
    78  {
    79    (void)lock;
    80      UINT32 expected_value = 0, current_value;
    81      UINT32 new_value = 1;
    82      if (!lock) {
    83          return FALSE;  // error
    84      }
    85      current_value =
    86              hw_interlocked_compare_exchange((INT32 volatile *)(&(lock->uint32_lock)),
    87                                                expected_value, new_value);
    88      return (current_value == expected_value);
    89  }
    90  
    91  
    92  void lock_initialize(VMM_LOCK* lock)
    93  {
    94      (void)lock;
    95      lock_release( lock );
    96  }
    97  
    98  void lock_initialize_read_write_lock(VMM_READ_WRITE_LOCK* lock)
    99  {
   100      (void)lock;
   101      lock_initialize(&lock->lock);
   102      lock->readers = 0;
   103  }
   104  
   105  
   106  void lock_acquire_readlock(VMM_READ_WRITE_LOCK* lock)
   107  {
   108      (void)lock;
   109      lock_acquire(&lock->lock);
   110      hw_interlocked_increment((INT32*)(&lock->readers));
   111      lock_release(&lock->lock);
   112  }
   113  
   114  void interruptible_lock_acquire_readlock(VMM_READ_WRITE_LOCK* lock)
   115  {
   116      (void)lock;
   117      interruptible_lock_acquire(&lock->lock);
   118      hw_interlocked_increment((INT32*)(&lock->readers));
   119      lock_release(&lock->lock);
   120  }
   121  
   122  void lock_release_readlock( VMM_READ_WRITE_LOCK * lock )
   123  {
   124      (void)lock;
   125      hw_interlocked_decrement((INT32*)(&lock->readers));
   126  }
   127  
   128  
   129  void lock_acquire_writelock(VMM_READ_WRITE_LOCK * lock)
   130  {
   131      (void)lock;
   132      lock_acquire(&lock->lock);
   133      // wait until readers == 0
   134      while(lock->readers) {
   135          hw_pause();
   136      }
   137  }
   138  
   139  
   140  void interruptible_lock_acquire_writelock(VMM_READ_WRITE_LOCK * lock)
   141  {
   142      (void)lock;
   143      BOOLEAN ipc_processed = FALSE;
   144  
   145      interruptible_lock_acquire(&lock->lock);
   146      //  wait until readers == 0
   147      while(lock->readers) {
   148          ipc_processed = ipc_process_one_ipc();
   149          if(FALSE == ipc_processed) {
   150              hw_pause();
   151          }
   152      }
   153  }
   154  
   155  
   156  void lock_release_writelock(VMM_READ_WRITE_LOCK* lock)
   157  {
   158      (void)lock;
   159      lock_release(&lock->lock);
   160  }
   161  
   162  
   163  VMM_DEBUG_CODE(
   164  
   165  void lock_print( VMM_LOCK* lock )
   166  {
   167    (void)lock;
   168  #if 0  // lock print
   169      VMM_LOG(mask_anonymous, level_trace,"lock %p: value=%d, owner=%d\r\n", lock, lock->uint32_lock, lock->owner_cpu_id);
   170  #endif
   171  }
   172  
   173  )
   174  
   175