Changeset 457 for trunk/kernel/syscalls/sys_sem.c
- Timestamp:
- Aug 2, 2018, 11:47:13 AM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/syscalls/sys_sem.c
r440 r457 22 22 */ 23 23 24 #include <hal_ types.h>24 #include <hal_kernel_types.h> 25 25 #include <hal_uspace.h> 26 #include <shared_semaphore.h> 26 27 #include <errno.h> 27 28 #include <thread.h> … … 31 32 #include <syscalls.h> 32 33 34 #if DEBUG_SYS_SEM 35 ////////////////////////////////////////////////// 36 static char * sys_sem_op_str( uint32_t operation ) 37 { 38 if ( operation == SEM_INIT ) return "INIT"; 39 else if( operation == SEM_WAIT ) return "WAIT"; 40 else if( operation == SEM_POST ) return "POST"; 41 else if( operation == SEM_GETVALUE ) return "GETVALUE"; 42 else if( operation == SEM_DESTROY ) return "DESTROY"; 43 else return "undefined"; 44 } 45 #endif 46 33 47 ////////////////////////////////// 34 int sys_sem( void * vaddr, // semaphore virtual address 35 uint32_t operation, // requested operation type 36 uint32_t * value ) // pointer on in/out argument 48 int sys_sem( void * vaddr, // semaphore virtual address 49 uint32_t operation, // requested operation type 50 uint32_t init_value, // initial value 51 uint32_t * current_value ) // pointer on current value buffer 37 52 { 38 uint32_t data;39 53 vseg_t * vseg; 40 54 error_t error; 55 uint32_t current; // semaphore current value 56 xptr_t sem_xp; // extended pointer on semaphore 41 57 42 58 thread_t * this = CURRENT_THREAD; 43 59 process_t * process = this->process; 60 61 #if DEBUG_SYS_SEM 62 uint64_t tm_start; 63 uint64_t tm_end; 64 tm_start = hal_get_cycles(); 65 if( DEBUG_SYS_SEM < tm_start ) 66 printk("\n[DBG] %s : thread %x in process %x enter for %s / cycle %d\n", 67 __FUNCTION__, this->trdid, process->pid, sys_sem_op_str( operation ), (uint32_t)tm_start ); 68 #endif 44 69 45 70 // check vaddr in user vspace … … 49 74 50 75 #if DEBUG_SYSCALLS_ERROR 51 printk("\n[ERROR] in %s : unmapped semaphore %x / thread %x / process %x\n", 52 __FUNCTION__ , (intptr_t)vaddr, this->trdid, process->pid ); 53 vmm_display( process , false ); 54 #endif 55 this->errno = EINVAL; 56 return -1; 57 } 58 59 // check value in user vspace 60 error = vmm_get_vseg( process , (intptr_t)value , &vseg ); 61 if( error ) 62 { 63 64 #if DEBUG_SYSCALLS_ERROR 65 printk("\n[ERROR] in %s : unmapped value %x / thread %x / process %x\n", 76 printk("\n[ERROR] in %s : unmapped semaphore pointer %x / thread %x in process %x\n", 66 77 __FUNCTION__ , (intptr_t)vaddr, this->trdid, process->pid ); 67 78 vmm_display( process , false ); … … 77 88 case SEM_INIT: 78 89 { 79 // get argument 80 hal_copy_from_uspace( &data , value , sizeof(uint32_t) ); 81 82 // call init function 83 error = remote_sem_create( (intptr_t)vaddr , data ); 90 // call relevant kernel function to initialize semaphore 91 error = remote_sem_create( (intptr_t)vaddr , 92 init_value, 93 XPTR( local_cxy , &sem_xp ) ); 84 94 85 95 if ( error ) 86 96 { 87 printk("\n[ERROR] in %s : cannot create semaphore = %x\n", 88 __FUNCTION__ , (intptr_t)value ); 89 this->errno = error; 90 return -1; 91 } 97 98 #if DEBUG_SYSCALLS_ERROR 99 printk("\n[ERROR] in %s : cannot create semaphore / thread %x in process %x\n", 100 __FUNCTION__, this->trdid, process->pid ); 101 #endif 102 this->errno = ENOMEM; 103 return -1; 104 } 105 92 106 break; 93 107 } … … 95 109 case SEM_GETVALUE: 96 110 { 97 // get extended pointer on remote semaphore 98 xptr_t sem_xp = remote_sem_from_vaddr( (intptr_t)vaddr ); 99 100 if( sem_xp == XPTR_NULL ) // user error 101 { 102 103 #if DEBUG_SYSCALLS_ERROR 104 printk("\n[ERROR] in %s : semaphore %x not registered / thread %x / process %x\n", 105 __FUNCTION__ , (intptr_t)value, this->trdid, process->pid ); 106 #endif 107 this->errno = EINVAL; 108 return -1; 109 } 110 else // success 111 { 112 // get semaphore current value 113 remote_sem_get_value( sem_xp , &data ); 111 // check current_value buffer in user vspace 112 error = vmm_get_vseg( process , (intptr_t)current_value , &vseg ); 113 if( error ) 114 { 115 116 #if DEBUG_SYSCALLS_ERROR 117 printk("\n[ERROR] in %s : unmapped buffer for current value %x / thread %x in process %x\n", 118 __FUNCTION__ , (intptr_t)current_value, this->trdid, process->pid ); 119 vmm_display( process , false ); 120 #endif 121 this->errno = EINVAL; 122 return -1; 123 } 124 125 // get extended pointer on remote semaphore 126 sem_xp = remote_sem_from_vaddr( (intptr_t)vaddr ); 127 128 // check semaphore registered 129 if( sem_xp == XPTR_NULL ) 130 { 131 132 #if DEBUG_SYSCALLS_ERROR 133 printk("\n[ERROR] in %s : semaphore %x not registered / thread %x in process %x\n", 134 __FUNCTION__ , (intptr_t)vaddr, this->trdid, process->pid ); 135 #endif 136 this->errno = EINVAL; 137 return -1; 138 } 139 140 // call relevant kernel function to get semaphore current value 141 remote_sem_get_value( sem_xp , ¤t ); 114 142 115 116 hal_copy_to_uspace( value , &data, sizeof(uint32_t) );117 } 143 // return value to user 144 hal_copy_to_uspace( current_value , ¤t , sizeof(uint32_t) ); 145 118 146 break; 119 147 } … … 122 150 { 123 151 // get extended pointer on remote semaphore 124 xptr_tsem_xp = remote_sem_from_vaddr( (intptr_t)vaddr );125 126 if( sem_xp == XPTR_NULL ) // user error127 {128 129 #if DEBUG_SYSCALLS_ERROR 130 printk("\n[ERROR] in %s : semaphore %x not registered / thread %x / process %x\n", 131 __FUNCTION__ , (intptr_t)value, this->trdid, process->pid ); 132 #endif 133 this->errno = EINVAL; 134 return -1;135 }136 else // success137 { 138 //wait semaphore available139 140 }152 sem_xp = remote_sem_from_vaddr( (intptr_t)vaddr ); 153 154 // check semaphore registered 155 if( sem_xp == XPTR_NULL ) 156 { 157 158 #if DEBUG_SYSCALLS_ERROR 159 printk("\n[ERROR] in %s : semaphore %x not registered / thread %x in process %x\n", 160 __FUNCTION__ , (intptr_t)vaddr, this->trdid, process->pid ); 161 #endif 162 this->errno = EINVAL; 163 return -1; 164 } 165 166 // call relevant kernel function to wait semaphore available 167 remote_sem_wait( sem_xp ); 168 141 169 break; 142 170 } … … 145 173 { 146 174 // get extended pointer on remote semaphore 147 xptr_tsem_xp = remote_sem_from_vaddr( (intptr_t)vaddr );148 149 if( sem_xp == XPTR_NULL ) // user error150 {151 152 #if DEBUG_SYSCALLS_ERROR 153 printk("\n[ERROR] in %s : semaphore %x not registered / thread %x / process %x\n", 154 __FUNCTION__ , (intptr_t)value, this->trdid, process->pid ); 155 #endif 156 this->errno = EINVAL; 157 return -1;158 }159 else // success160 { 161 //release semaphore162 163 } 175 sem_xp = remote_sem_from_vaddr( (intptr_t)vaddr ); 176 177 // check semaphore registered 178 if( sem_xp == XPTR_NULL ) 179 { 180 181 #if DEBUG_SYSCALLS_ERROR 182 printk("\n[ERROR] in %s : semaphore %x not registered / thread %x in process %x\n", 183 __FUNCTION__ , (intptr_t)vaddr, this->trdid, process->pid ); 184 #endif 185 this->errno = EINVAL; 186 return -1; 187 } 188 189 // call relevant kernel function to release semaphore 190 remote_sem_post( sem_xp ); 191 164 192 break; 165 193 } … … 168 196 { 169 197 // get extended pointer on remote semaphore 170 xptr_tsem_xp = remote_sem_from_vaddr( (intptr_t)vaddr );171 172 if( sem_xp == XPTR_NULL ) // user error173 {174 175 #if DEBUG_SYSCALLS_ERROR 176 printk("\n[ERROR] in %s : semaphore %x not registered / thread %x / process %x\n", 177 __FUNCTION__ , (intptr_t)value, this->trdid, process->pid ); 178 #endif 179 this->errno = EINVAL; 180 return -1;181 }182 else // success183 { 184 185 186 } 198 sem_xp = remote_sem_from_vaddr( (intptr_t)vaddr ); 199 200 // check semaphore registered 201 if( sem_xp == XPTR_NULL ) 202 { 203 204 #if DEBUG_SYSCALLS_ERROR 205 printk("\n[ERROR] in %s : semaphore %x not registered / thread %x in process %x\n", 206 __FUNCTION__ , (intptr_t)vaddr, this->trdid, process->pid ); 207 #endif 208 this->errno = EINVAL; 209 return -1; 210 } 211 212 // destroy semaphore 213 remote_sem_destroy( sem_xp ); 214 187 215 break; 188 216 } … … 190 218 default: // undefined operation 191 219 { 192 printk("\n[PANIC] in %s : illegal operation type\n", __FUNCTION__ ); 193 hal_core_sleep(); 220 221 #if DEBUG_SYSCALLS_ERROR 222 printk("\n[ERROR] in %s : undefined operation type %d / thread %x in process %x\n", 223 __FUNCTION__ , operation, this->trdid, process->pid ); 224 #endif 225 this->errno = EINVAL; 226 return -1; 194 227 } 195 228 } 196 229 230 hal_fence(); 231 232 #if DEBUG_SYS_SEM 233 tm_end = hal_get_cycles(); 234 if( DEBUG_SYS_SEM < tm_end ) 235 { 236 cxy_t sem_cxy = GET_CXY( sem_xp ); 237 remote_sem_t * sem_ptr = GET_PTR( sem_xp ); 238 uint32_t value = hal_remote_lw( XPTR( sem_cxy , &sem_ptr->count ) ); 239 printk("\n[DBG] %s : thread %x in process %x exit for %s / value %d / cost = %d / cycle %d\n", 240 __FUNCTION__, this->trdid, process->pid, sys_sem_op_str( operation ), value, 241 (uint32_t)(tm_end - tm_start), (uint32_t)tm_end ); 242 } 243 #endif 244 197 245 return 0; 198 246
Note: See TracChangeset
for help on using the changeset viewer.