Changeset 289 for trunk/kernel
- Timestamp:
- Jul 27, 2017, 4:44:18 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/syscalls/sys_thread_create.c
r101 r289 1 1 /* 2 2 * sys_thread_create.c - creates a new user thread 3 * 3 * 4 4 * Author Alain Greiner (2016,2017) 5 5 * … … 50 50 pthread_attr_t k_attr; // copy of pthread attributes in kernel space 51 51 thread_t * parent; // pointer on thread executing the pthread_create 52 53 54 55 56 57 58 52 xptr_t parent_xp; // extended pointer on created thread 53 thread_t * child_ptr; // pointer on created child thread 54 xptr_t child_xp; // extended pointer on created thread 55 trdid_t trdid; // created thread identifier 56 process_t * process; // pointer on local process descriptor 57 paddr_t paddr; // unused, required by vmm_v2p_translate() 58 error_t error; 59 59 60 60 uint32_t tm_start; … … 63 63 tm_start = hal_get_cycles(); 64 64 65 65 // get parent thead pointer, extended pointer, and process pointer 66 66 parent = CURRENT_THREAD; 67 parent_xp = XPTR( local_cxy , parent ); 67 parent_xp = XPTR( local_cxy , parent ); 68 68 process = parent->process; 69 69 70 // check user_attr in user space 71 70 // check user_attr in user space 71 error = vmm_v2p_translate( false , user_attr , &paddr ); 72 72 73 73 if( error ) … … 75 75 printk("\n[ERROR] in %s : user_attr unmapped\n", __FUNCTION__ ); 76 76 parent->errno = EINVAL; 77 77 return -1; 78 78 } 79 79 80 // check start_func in user space 81 80 // check start_func in user space 81 error = vmm_v2p_translate( false , start_func , &paddr ); 82 82 83 83 if( error ) … … 85 85 printk("\n[ERROR] in %s : start_func unmapped\n", __FUNCTION__ ); 86 86 parent->errno = EINVAL; 87 87 return -1; 88 88 } 89 89 90 // check start_arg in user space 91 90 // check start_arg in user space 91 if( start_arg != NULL ) error = vmm_v2p_translate( false , start_arg , &paddr ); 92 92 93 93 if( error ) … … 95 95 printk("\n[ERROR] in %s : start_arg unmapped\n", __FUNCTION__ ); 96 96 parent->errno = EINVAL; 97 97 return -1; 98 98 } 99 99 100 100 // copy user_attr structure from user space to kernel space 101 101 hal_copy_from_uspace( &k_attr , user_attr , sizeof(pthread_attr_t) ); 102 102 103 104 if( k_attr.attributes & PT_ATTR_CLUSTER_DEFINED ) 105 106 107 108 109 110 111 112 } 113 114 115 116 117 103 // check/set "cxy" attribute 104 if( k_attr.attributes & PT_ATTR_CLUSTER_DEFINED ) 105 { 106 if( cluster_is_undefined( k_attr.cxy ) ) 107 { 108 printk("\n[ERROR] in %s : illegal target cluster attribute = %x\n", 109 __FUNCTION__ , k_attr.cxy ); 110 parent->errno = EINVAL; 111 return -1; 112 } 113 } 114 else 115 { 116 k_attr.cxy = dqdt_get_cluster_for_process(); 117 } 118 118 119 // create the thread, using a RPC if required 120 // this returns "error", "child", and "child_xp" 121 122 if( k_attr.cxy == local_cxy ) // target cluster is local 123 { 119 // create the thread, using a RPC if required 120 // this returns "error", "child", and "child_xp" 124 121 125 // create thread in local cluster 126 error = thread_user_create( process->pid, 127 start_func, 128 start_arg, 129 &k_attr, 130 &child_ptr ); 122 if( k_attr.cxy == local_cxy ) // target cluster is local 123 { 124 // create thread in local cluster 125 error = thread_user_create( process->pid, 126 start_func, 127 start_arg, 128 &k_attr, 129 &child_ptr ); 131 130 132 133 134 135 136 137 138 139 140 &k_attr, 141 &child_xp, 142 131 child_xp = XPTR( local_cxy , child_ptr ); 132 } 133 else // target cluster is remote 134 { 135 rpc_thread_user_create_client( k_attr.cxy, 136 process->pid, 137 start_func, 138 start_arg, 139 &k_attr, 140 &child_xp, 141 &error ); 143 142 144 145 143 child_ptr = (thread_t *)GET_PTR( child_xp ); 144 } 146 145 147 148 if( error ) 149 146 // check successful thread creation 147 if( error ) 148 { 150 149 printk("\n[ERROR] in %s : cannot create thread\n", __FUNCTION__ ); 151 152 150 return ENOMEM; 151 } 153 152 154 // returns trdid to user space 155 trdid = hal_remote_lw( XPTR( k_attr.cxy , &child_ptr->trdid ) ); 153 // returns trdid to user space 154 trdid = hal_remote_lw( XPTR( k_attr.cxy , &child_ptr->trdid ) ); 156 155 hal_copy_to_uspace( new_thread , &trdid , sizeof(pthread_t) ); 157 158 159 if( (k_attr.attributes & PT_ATTR_DETACH) == 0 ) 160 156 157 // register new-thread in parent-thread children list if required 158 if( (k_attr.attributes & PT_ATTR_DETACH) == 0 ) 159 thread_child_parent_link( parent_xp , child_xp ); 161 160 162 161 tm_end = hal_get_cycles(); 163 162 164 163 thread_dmsg("\n[INFO] %s created thread %x for process %x in cluster %x\n" 165 166 164 " start_cycle = %d / end_cycle = %d\n", 165 trdid , process->pid , k_attr.cxy , tm_start , tm_end ); 167 166 return 0; 167 } 168 168 169 } // end sys_thread_create()170 171
Note: See TracChangeset
for help on using the changeset viewer.