Changeset 407 for trunk/kernel/syscalls/sys_thread_create.c
- Timestamp:
- Nov 7, 2017, 3:08:12 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/syscalls/sys_thread_create.c
r406 r407 40 40 41 41 42 ////////////////////////////////////////////////////////////////////////////////////////// 43 // This function implements the pthread_create system call 44 ////////////////////////////////////////////////////////////////////////////////////////// 45 int sys_thread_create ( thread_t * new_thread, // [out] argument 46 pthread_attr_t * user_attr, // [in] argument 47 void * start_func, // [in] argument 48 void * start_arg ) // [in] argument 42 /////////////////////////////////////////////////// 43 int sys_thread_create ( pthread_t * trdid_ptr, 44 pthread_attr_t * user_attr, 45 void * start_func, 46 void * start_arg ) 49 47 { 50 pthread_attr_t k _attr;// copy of pthread attributes in kernel space48 pthread_attr_t kern_attr; // copy of pthread attributes in kernel space 51 49 thread_t * parent; // pointer on thread executing the pthread_create 52 50 xptr_t parent_xp; // extended pointer on created thread … … 56 54 process_t * process; // pointer on local process descriptor 57 55 paddr_t paddr; // unused, required by vmm_v2p_translate() 56 cxy_t target_cxy; // target cluster identifier 58 57 error_t error; 59 58 … … 63 62 tm_start = hal_get_cycles(); 64 63 65 // get parent thead pointer, extended pointer, and process pointer64 // get parent thead pointer, extended pointer, and process 66 65 parent = CURRENT_THREAD; 67 66 parent_xp = XPTR( local_cxy , parent ); 68 67 process = parent->process; 69 68 70 // check user_attr in user space 71 error = vmm_v2p_translate( false , user_attr , &paddr ); 69 // check user_attr in user space & copy to kernel space 70 if( user_attr != NULL ) 71 { 72 error = vmm_v2p_translate( false , user_attr , &paddr ); 72 73 73 if( error ) 74 { 75 printk("\n[ERROR] in %s : user_attr unmapped\n", __FUNCTION__ ); 76 parent->errno = EINVAL; 77 return -1; 78 } 74 if( error ) 75 { 76 printk("\n[ERROR] in %s : user_attr unmapped\n", __FUNCTION__ ); 77 parent->errno = EINVAL; 78 return -1; 79 } 80 81 hal_copy_from_uspace( &kern_attr , user_attr , sizeof(pthread_attr_t) ); 82 } 79 83 80 84 // check start_func in user space … … 98 102 } 99 103 100 // copy user_attr structure from user space to kernel space 101 hal_copy_from_uspace( &k_attr , user_attr , sizeof(pthread_attr_t) ); 102 103 // check/set "cxy" attribute 104 if( k_attr.attributes & PT_ATTR_CLUSTER_DEFINED ) 104 // check / define attributes an target_cxy 105 if( user_attr != NULL ) // user defined attributes 106 { 107 // check / get target_cxy 108 if( kern_attr.attributes & PT_ATTR_CLUSTER_DEFINED ) 109 { 110 if( cluster_is_undefined( kern_attr.cxy ) ) 111 { 112 printk("\n[ERROR] in %s : illegal target cluster = %x\n", 113 __FUNCTION__ , kern_attr.cxy ); 114 parent->errno = EINVAL; 115 return -1; 116 } 117 target_cxy = kern_attr.cxy; 118 } 119 else 120 { 121 target_cxy = dqdt_get_cluster_for_process(); 122 } 123 } 124 else // set default attributes 105 125 { 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(); 126 kern_attr.attributes = PT_ATTR_DETACH | PT_ATTR_CLUSTER_DEFINED; 127 target_cxy = dqdt_get_cluster_for_process(); 117 128 } 118 129 119 130 // create the thread, using a RPC if required 120 // this returns "error", "child ", and "child_xp"131 // this returns "error", "child_ptr", and "child_xp" 121 132 122 if( k_attr.cxy == local_cxy ) // target cluster is local133 if( target_cxy == local_cxy ) // target cluster is local 123 134 { 124 135 // create thread in local cluster … … 126 137 start_func, 127 138 start_arg, 128 &k _attr,139 &kern_attr, 129 140 &child_ptr ); 130 141 … … 133 144 else // target cluster is remote 134 145 { 135 rpc_thread_user_create_client( k_attr.cxy,146 rpc_thread_user_create_client( target_cxy, 136 147 process->pid, 137 148 start_func, 138 149 start_arg, 139 &k _attr,150 &kern_attr, 140 151 &child_xp, 141 152 &error ); … … 152 163 153 164 // returns trdid to user space 154 trdid = hal_remote_lw( XPTR( k_attr.cxy , &child_ptr->trdid ) );155 hal_copy_to_uspace( new_thread, &trdid , sizeof(pthread_t) );165 trdid = hal_remote_lw( XPTR( target_cxy , &child_ptr->trdid ) ); 166 hal_copy_to_uspace( trdid_ptr , &trdid , sizeof(pthread_t) ); 156 167 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 ); 168 // register child in parent if required 169 if( user_attr != NULL ) 170 { 171 if( (kern_attr.attributes & PT_ATTR_DETACH) == 0 ) 172 thread_child_parent_link( parent_xp , child_xp ); 173 } 174 175 // activate new thread 176 thread_unblock( child_xp , THREAD_BLOCKED_GLOBAL ); 177 178 hal_fence(); 160 179 161 180 tm_end = hal_get_cycles(); 162 181 163 thread_dmsg("\n[DMSG] %s created thread %x for process %x in cluster %x\n" 164 " start_cycle = %d / end_cycle = %d\n", 165 trdid , process->pid , k_attr.cxy , tm_start , tm_end ); 182 syscall_dmsg("\n[DBG] %s : core[%x,%d] created thread %x for process %x / cycle %d\n" 183 " cluster %x / cost = %d cycles\n", 184 __FUNCTION__ , local_cxy , parent->core->lid , trdid , process->pid , tm_end , 185 target_cxy , tm_end - tm_start ); 186 166 187 return 0; 167 }168 188 189 } // end sys_thread_create() 190
Note: See TracChangeset
for help on using the changeset viewer.