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