Changeset 23 for trunk/kernel/syscalls/sys_condvar.c
- Timestamp:
- Jun 18, 2017, 10:06:41 PM (7 years ago)
- File:
-
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/syscalls/sys_condvar.c
r15 r23 1 1 /* 2 * sys_cond _var: interface to access condition vraibles service2 * sys_condvar.c - Access a POSIX condvar. 3 3 * 4 * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless 5 * Copyright (c) 2011,2012 UPMC Sorbonne Universites 4 * Author Alain Greiner (2016,2017) 6 5 * 7 * This file is part of ALMOS-kernel.6 * Copyright (c) UPMC Sorbonne Universites 8 7 * 9 * ALMOS-kernel is free software; you can redistribute it and/or modify it 8 * This file is part of ALMOS-MKH. 9 * 10 * ALMOS-MKH is free software; you can redistribute it and/or modify it 10 11 * under the terms of the GNU General Public License as published by 11 12 * the Free Software Foundation; version 2.0 of the License. 12 13 * 13 * ALMOS- kernelis distributed in the hope that it will be useful, but14 * ALMOS-MKH is distributed in the hope that it will be useful, but 14 15 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU … … 17 18 * 18 19 * You should have received a copy of the GNU General Public License 19 * along with ALMOS- kernel; if not, write to the Free Software Foundation,20 * along with ALMOS-MKH; if not, write to the Free Software Foundation, 20 21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 22 */ 22 23 23 #include <types.h> 24 #include <hal_types.h> 25 #include <hal_special.h> 24 26 #include <errno.h> 25 27 #include <thread.h> 26 #include <kmem.h> 27 #include <task.h> 28 #include <printk.h> 28 29 #include <vmm.h> 29 #include <kmagics.h> 30 #include <semaphore.h> 31 #include <cond_var.h> 30 #include <syscalls.h> 31 #include <remote_condvar.h> 32 32 33 static inline bool_t isBadSem(struct semaphore_s *sem) 34 { 35 return vmm_check_object(sem, struct semaphore_s, SEMAPHORE_ID); 36 } 33 //////////////////////////////////////// 34 int sys_condvar( void * condvar, 35 uint32_t operation, 36 void * mutex ) 37 { 38 error_t error; 39 paddr_t paddr; 40 41 thread_t * this = CURRENT_THREAD; 37 42 38 static inline bool_t isBadCV(struct cv_s *cv) 39 { 40 return vmm_check_object(cv, struct cv_s, COND_VAR_ID); 41 } 43 // check condvar in user vspace 44 error = vmm_v2p_translate( false , condvar , &paddr ); 45 if( error ) 46 { 47 printk("\n[ERROR] in %s : illegal condvar virtual address = %x\n", 48 __FUNCTION__ , (intptr_t)condvar ); 49 this->errno = error; 50 return -1; 51 } 42 52 43 int sys_cond_var(struct cv_s **cv, uint_t operation, struct semaphore_s **sem) 44 { 45 kmem_req_t req; 46 struct cv_s *icv; 47 struct semaphore_s *isem; 48 error_t err = EINVAL; 49 50 if((err = vmm_check_address("usr cv ptr", current_task,cv,sizeof(struct cv_s*)))) 51 goto SYS_COND_END; 53 // execute requested operation 54 switch( operation ) 55 { 56 ////////////////// 57 case CONDVAR_INIT: 58 { 59 error = remote_condvar_create( (intptr_t)condvar ); 60 61 if( error ) 62 { 63 printk("\n[ERROR] in %s : cannot create condvar = %x\n", 64 __FUNCTION__ , (intptr_t)condvar ); 65 this->errno = error; 66 return -1; 67 } 68 break; 69 } 70 ////////////////// 71 case CONDVAR_WAIT: 72 { 73 // check mutex in user vspace 74 error = vmm_v2p_translate( false , mutex , &paddr ); 52 75 53 if((err = cpu_copy_from_uspace(&icv, cv, sizeof(struct cv_s *)))) 54 goto SYS_COND_END; 76 if( error ) 77 { 78 printk("\n[ERROR] in %s : illegal condvar virtual address = %x\n", 79 __FUNCTION__ , (intptr_t)condvar ); 80 this->errno = error; 81 return -1; 82 } 55 83 56 switch(operation) 57 { 58 case CV_INIT: 59 req.type = KMEM_CV; 60 req.size = sizeof(*icv); 61 req.flags = AF_USER; 84 xptr_t condvar_xp = remote_condvar_from_ident( (intptr_t)condvar ); 85 86 if( condvar_xp == XPTR_NULL ) // user error 87 { 88 printk("\n[ERROR] in %s : condvar %x not registered\n", 89 __FUNCTION__ , (intptr_t)condvar ); 90 this->errno = EINVAL; 91 return -1; 92 } 62 93 63 if((icv = kmem_alloc(&req)) == NULL) 64 { 65 err = ENOMEM; 66 break; 94 xptr_t mutex_xp = remote_condvar_from_ident( (intptr_t)condvar ); 95 if( mutex_xp == XPTR_NULL ) // user error 96 { 97 printk("\n[ERROR] in %s : mutex %x not registered\n", 98 __FUNCTION__ , (intptr_t)condvar ); 99 this->errno = EINVAL; 100 return -1; 101 } 102 103 remote_condvar_wait( condvar_xp , mutex_xp ); 104 105 break; 106 } 107 //////////////////// 108 case CONDVAR_SIGNAL: 109 { 110 xptr_t condvar_xp = remote_condvar_from_ident( (intptr_t)condvar ); 111 112 if( condvar_xp == XPTR_NULL ) // user error 113 { 114 printk("\n[ERROR] in %s : condvar %x not registered\n", 115 __FUNCTION__ , (intptr_t)condvar ); 116 this->errno = EINVAL; 117 return -1; 118 } 119 120 remote_condvar_signal( condvar_xp ); 121 122 break; 123 } 124 /////////////////////// 125 case CONDVAR_BROADCAST: 126 { 127 xptr_t condvar_xp = remote_condvar_from_ident( (intptr_t)condvar ); 128 129 if( condvar_xp == XPTR_NULL ) // user error 130 { 131 printk("\n[ERROR] in %s : condvar %x not registered\n", 132 __FUNCTION__ , (intptr_t)condvar ); 133 this->errno = EINVAL; 134 return -1; 135 } 136 137 remote_condvar_broadcast( condvar_xp ); 138 139 break; 140 } 141 ///////////////////// 142 case CONDVAR_DESTROY: 143 { 144 xptr_t condvar_xp = remote_condvar_from_ident( (intptr_t)condvar ); 145 146 if( condvar_xp == XPTR_NULL ) // user error 147 { 148 printk("\n[ERROR] in %s : condvar %x not registered\n", 149 __FUNCTION__ , (intptr_t)condvar ); 150 this->errno = EINVAL; 151 return -1; 152 } 153 154 remote_condvar_destroy( condvar_xp ); 155 156 break; 67 157 } 68 69 if((err = cv_init(icv))) 70 break; 71 72 if((err = cpu_copy_to_uspace(cv, &icv, sizeof(struct cv_s *)))) 73 { 74 req.ptr = icv; 75 kmem_free(&req); 76 } 158 ///////// 159 default: 160 { 161 printk("\n[PANIC] in %s : illegal operation type\n", __FUNCTION__ ); 162 hal_core_sleep(); 163 } 164 } // end switch 77 165 78 break;166 return 0; 79 167 80 case CV_WAIT: 81 err = vmm_check_address("usr sem ptr", 82 current_task, 83 sem, sizeof(struct semaphore_s*)); 168 } // enc sys_condvar() 84 169 85 if(err) break;86 87 if((err = cpu_copy_from_uspace(&isem, sem, sizeof(struct semaphore_s *))))88 break;89 90 if(isBadSem(isem))91 break;92 93 if(isBadCV(icv))94 break;95 96 return cv_wait(icv, isem);97 98 case CV_SIGNAL:99 if(isBadCV(icv))100 break;101 102 return cv_signal(icv);103 104 case CV_BROADCAST:105 if(isBadCV(icv))106 break;107 108 return cv_broadcast(icv);109 110 case CV_DESTROY:111 if(isBadCV(icv))112 break;113 114 if((err = cv_destroy(icv)))115 break;116 117 req.type = KMEM_CV;118 req.ptr = icv;119 kmem_free(&req);120 return 0;121 122 default:123 err = EINVAL;124 }125 126 SYS_COND_END:127 current_thread->info.errno = err;128 return err;129 }130 131 KMEM_OBJATTR_INIT(cv_kmem_init)132 {133 attr->type = KMEM_CV;134 attr->name = "KCM Condition Variable";135 attr->size = sizeof(struct cv_s);136 attr->aligne = 0;137 attr->min = CONFIG_CONDTION_VAR_MIN;138 attr->max = CONFIG_CONDTION_VAR_MAX;139 attr->ctor = NULL;140 attr->dtor = NULL;141 142 return 0;143 }
Note: See TracChangeset
for help on using the changeset viewer.