source: trunk/kernel/kern/process.c@ 373

Last change on this file since 373 was 373, checked in by max@…, 9 years ago

Start using panic().

File size: 25.3 KB
Line 
1/*
2 * process.c - process related management
3 *
4 * Authors Ghassan Almaless (2008,2009,2010,2011,2012)
5 * Mohamed Lamine Karaoui (2015)
6 * Alain Greiner (2016,2017)
7 *
8 * Copyright (c) UPMC Sorbonne Universites
9 *
10 * This file is part of ALMOS-MKH..
11 *
12 * ALMOS-MKH is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; version 2.0 of the License.
15 *
16 * ALMOS-MKH is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
23 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26#include <kernel_config.h>
27#include <hal_types.h>
28#include <hal_remote.h>
29#include <hal_uspace.h>
30#include <errno.h>
31#include <printk.h>
32#include <memcpy.h>
33#include <bits.h>
34#include <kmem.h>
35#include <page.h>
36#include <vmm.h>
37#include <vfs.h>
38#include <core.h>
39#include <thread.h>
40#include <list.h>
41#include <scheduler.h>
42#include <remote_spinlock.h>
43#include <dqdt.h>
44#include <cluster.h>
45#include <ppm.h>
46#include <boot_info.h>
47#include <process.h>
48#include <elf.h>
49#include <syscalls.h>
50
51//////////////////////////////////////////////////////////////////////////////////////////
52// Extern global variables
53//////////////////////////////////////////////////////////////////////////////////////////
54
55extern process_t process_zero;
56
57//////////////////////////////////////////////////////////////////////////////////////////
58// Process initialisation related functions
59//////////////////////////////////////////////////////////////////////////////////////////
60
61///////////////////////////
62process_t * process_alloc()
63{
64 kmem_req_t req;
65
66 req.type = KMEM_PROCESS;
67 req.size = sizeof(process_t);
68 req.flags = AF_KERNEL;
69
70 return (process_t *)kmem_alloc( &req );
71}
72
73////////////////////////////////////////
74void process_free( process_t * process )
75{
76 kmem_req_t req;
77
78 req.type = KMEM_PROCESS;
79 req.ptr = process;
80 kmem_free( &req );
81}
82
83/////////////////////////////////////////////////
84void process_reference_init( process_t * process,
85 pid_t pid,
86 xptr_t parent_xp )
87{
88 cxy_t parent_cxy;
89 process_t * parent_ptr;
90 pid_t parent_pid;
91
92 process_dmsg("\n[INFO] %s : enters for process %x in cluster %x\n",
93 __FUNCTION__ , pid , local_cxy );
94
95 // get parent process cluster, local pointer, and pid
96 // for all processes other than process_zero
97 if( process == &process_zero )
98 {
99 assert( (pid == 0) , __FUNCTION__ , "process_zero must have PID = 0\n");
100
101 parent_cxy = 0;
102 parent_ptr = NULL;
103 parent_pid = 0; // process_zero is its own parent...
104 }
105 else
106 {
107 assert( (parent_xp != XPTR_NULL) , __FUNCTION__ , "parent_xp cannot be NULL\n");
108
109 parent_cxy = GET_CXY( parent_xp );
110 parent_ptr = (process_t *)GET_PTR( parent_xp );
111 parent_pid = hal_remote_lw( XPTR( parent_cxy , &parent_ptr->pid ) );
112 }
113
114 // initialize PID and PPID
115 process->pid = pid;
116 process->ppid = parent_pid;
117
118 // reset reference process vmm (not for kernel process)
119 if( pid ) vmm_init( process );
120
121 // reset reference process file descriptors array
122 process_fd_init( process );
123
124 // reset reference process files structures and cwd_lock
125 process->vfs_root_xp = XPTR_NULL;
126 process->vfs_bin_xp = XPTR_NULL;
127 process->vfs_cwd_xp = XPTR_NULL;
128 remote_rwlock_init( XPTR( local_cxy , &process->cwd_lock ) );
129
130 // reset children list root
131 xlist_root_init( XPTR( local_cxy , &process->children_root ) );
132 process->children_nr = 0;
133
134 // reset semaphore / mutex / barrier / condvar list roots
135 xlist_root_init( XPTR( local_cxy , &process->sem_root ) );
136 xlist_root_init( XPTR( local_cxy , &process->mutex_root ) );
137 xlist_root_init( XPTR( local_cxy , &process->barrier_root ) );
138 xlist_root_init( XPTR( local_cxy , &process->condvar_root ) );
139 remote_spinlock_init( XPTR( local_cxy , &process->sync_lock ) );
140
141 // register new process in the parent children list (not for kernel process)
142 if( pid )
143 {
144 xptr_t entry = XPTR( local_cxy , &process->brothers_list );
145 xptr_t root = XPTR( parent_cxy , &parent_ptr->children_root );
146 xlist_add_first( root , entry );
147 }
148
149 // reset th_tbl[] array as empty
150 uint32_t i;
151 for( i = 0 ; i < CONFIG_THREAD_MAX_PER_CLUSTER ; i++ )
152 {
153 process->th_tbl[i] = NULL;
154 }
155 process->th_nr = 0;
156 spinlock_init( &process->th_lock );
157
158 // set ref_xp field
159 process->ref_xp = XPTR( local_cxy , process );
160
161 // register new process descriptor in local cluster manager local_list
162 cluster_process_local_link( process );
163
164 // register new process descriptor in owner cluster manager copies_list
165 cluster_process_copies_link( process );
166
167 // initialize signal manager TODO [AG]
168
169 hal_fence();
170
171 process_dmsg("\n[INFO] %s : exit for process %x in cluster %x\n",
172 __FUNCTION__ , pid );
173
174} // process_reference init()
175
176/////////////////////////////////////////////////////
177error_t process_copy_init( process_t * local_process,
178 xptr_t reference_process_xp )
179{
180 // get reference process cluster and local pointer
181 cxy_t ref_cxy = GET_CXY( reference_process_xp );
182 process_t * ref_ptr = (process_t *)GET_PTR( reference_process_xp );
183
184 // reset local process vmm
185 vmm_init( local_process );
186
187 // reset process file descriptors array
188 process_fd_init( local_process );
189
190 // reset vfs_root_xp / vfs_bin_xp / vfs_cwd_xp fields
191 local_process->vfs_root_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->vfs_root_xp ) );
192 local_process->vfs_bin_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->vfs_bin_xp ) );
193 local_process->vfs_cwd_xp = XPTR_NULL;
194
195 // set the pid, ppid, ref_xp fields
196 local_process->pid = hal_remote_lw( XPTR( ref_cxy , &ref_ptr->pid ) );
197 local_process->ppid = hal_remote_lw( XPTR( ref_cxy , &ref_ptr->ppid ) );
198 local_process->ref_xp = reference_process_xp;
199
200 process_dmsg("\n[INFO] %s : enter for process %x in cluster %x\n",
201 __FUNCTION__ , local_process->pid );
202
203 // reset children list root (not used in a process descriptor copy)
204 xlist_root_init( XPTR( local_cxy , &local_process->children_root ) );
205 local_process->children_nr = 0;
206
207 // reset brothers list (not used in a process descriptor copy)
208 xlist_entry_init( XPTR( local_cxy , &local_process->brothers_list ) );
209
210 // reset semaphores list root (not used in a process descriptor copy)
211 xlist_root_init( XPTR( local_cxy , &local_process->sem_root ) );
212 xlist_root_init( XPTR( local_cxy , &local_process->mutex_root ) );
213 xlist_root_init( XPTR( local_cxy , &local_process->barrier_root ) );
214 xlist_root_init( XPTR( local_cxy , &local_process->condvar_root ) );
215
216 // reset th_tbl[] array as empty
217 uint32_t i;
218 for( i = 0 ; i < CONFIG_THREAD_MAX_PER_CLUSTER ; i++ )
219 {
220 local_process->th_tbl[i] = NULL;
221 }
222 local_process->th_nr = 0;
223 spinlock_init( &local_process->th_lock );
224
225 // register new process descriptor in local cluster manager local_list
226 cluster_process_local_link( local_process );
227
228 // register new process descriptor in owner cluster manager copies_list
229 cluster_process_copies_link( local_process );
230
231 // initialize signal manager TODO [AG]
232
233 hal_fence();
234
235 process_dmsg("\n[INFO] %s : exit for process %x in cluster %x\n",
236 __FUNCTION__ , local_process->pid );
237
238 return 0;
239
240} // end process_copy_init()
241
242///////////////////////////////////////////
243void process_destroy( process_t * process )
244{
245 if( process->th_nr != 0 )
246 {
247 panic("process %x in cluster %x has still active threads\n",
248 process->pid , local_cxy );
249 }
250
251 // get local process manager pointer
252 pmgr_t * pmgr = &LOCAL_CLUSTER->pmgr;
253
254 // get the lock protecting the list of local process descriptors
255 remote_spinlock_lock( XPTR( local_cxy , &pmgr->local_lock ) );
256
257 // remove the process descriptor from local_list in local cluster manager
258 xlist_unlink( XPTR( local_cxy , &process->local_list ) );
259
260 // release the lock protecting the list of local process descriptors
261 remote_spinlock_unlock( XPTR( local_cxy , &pmgr->local_lock ) );
262
263 // get extended pointer on copies_lock in owner cluster manager
264 cxy_t owner_cxy = CXY_FROM_PID( process->pid );
265 lpid_t lpid = LPID_FROM_PID( process->pid );
266 xptr_t copies_lock = XPTR( owner_cxy , &pmgr->copies_lock[lpid] );
267
268 // remove the local process descriptor from copies_list
269 remote_spinlock_lock( copies_lock );
270 xlist_unlink( XPTR( local_cxy , &process->copies_list ) );
271 remote_spinlock_unlock( copies_lock );
272
273 // synchronize memory
274 hal_fence();
275
276 // From this point, the process descriptor is unreachable
277
278 // close all open files and update dirty TODO [AG]
279
280 // release signal manager TODO [AG]
281
282 // Decrease refcount for bin file, root file and cwd file
283 if( process->vfs_bin_xp != XPTR_NULL ) vfs_file_count_down( process->vfs_bin_xp );
284 if( process->vfs_root_xp != XPTR_NULL ) vfs_file_count_down( process->vfs_root_xp );
285 if( process->vfs_cwd_xp != XPTR_NULL ) vfs_file_count_down( process->vfs_cwd_xp );
286
287 // Destroy VMM
288 vmm_destroy( process );
289
290 process_dmsg("\n[INFO] %s for pid %d / page_faults = %d\n",
291 __FUNCTION__ , process->pid, process->vmm.pgfault_nr );
292}
293
294////////////////////////////////////////
295void process_kill( process_t * process )
296{
297 thread_t * thread; // pointer on current thead descriptor
298 uint32_t ltid; // index in process th_tbl
299 uint32_t count; // thread counter
300
301 // get lock protecting th_tbl[]
302 spinlock_lock( &process->th_lock );
303
304 // first loop on threads to send the THREAD_SIG_KILL signal to all process threads
305 // we use both "ltid" and "count" indexes, because it can exist "holes" in th_tbl
306 for( ltid = 0 , count = 0 ;
307 (ltid < CONFIG_THREAD_MAX_PER_CLUSTER) && (count < process->th_nr) ;
308 ltid++ )
309 {
310 thread = process->th_tbl[ltid];
311
312 if( thread != NULL )
313 {
314 thread_kill( thread );
315 count++;
316 }
317 }
318
319 volatile uint32_t ko;
320
321 // second loop on threads to wait acknowledge from scheduler,
322 // unlink thread from process and parent thread, and release thread descriptor
323 for( ltid = 0 , count = 0 ;
324 (ltid < CONFIG_THREAD_MAX_PER_CLUSTER) && (count < process->th_nr) ;
325 ltid++ )
326 {
327 thread = process->th_tbl[ltid];
328
329 if( thread != NULL )
330 {
331 // wait scheduler acknowledge
332 do { ko = (thread->signals & THREAD_SIG_KILL); } while( ko );
333
334 // unlink thread from brothers list if required
335 if( (thread->flags & THREAD_FLAG_DETACHED) == 0 )
336 xlist_unlink( XPTR( local_cxy , &thread->brothers_list ) );
337
338 // unlink thread from process
339 process_remove_thread( thread );
340
341 // release memory for thread descriptor
342 thread_destroy( thread );
343
344 count++;
345 }
346 }
347
348 // release lock protecting th_tbl[]
349 spinlock_unlock( &process->th_lock );
350
351 // release memory allocated for process descriptor
352 process_destroy( process );
353}
354
355///////////////////////////////////////////////
356process_t * process_get_local_copy( pid_t pid )
357{
358 error_t error;
359 process_t * process_ptr; // local pointer on process
360 xptr_t process_xp; // extended pointer on process
361
362 cluster_t * cluster = LOCAL_CLUSTER;
363
364 // get lock protecting local list of processes
365 remote_spinlock_lock( XPTR( local_cxy , &cluster->pmgr.local_lock ) );
366
367 // scan the local list of process descriptors to find the process
368 xptr_t iter;
369 bool_t found = false;
370 XLIST_FOREACH( XPTR( local_cxy , &cluster->pmgr.local_root ) , iter )
371 {
372 process_xp = XLIST_ELEMENT( iter , process_t , local_list );
373 process_ptr = (process_t *)GET_PTR( process_xp );
374 if( process_ptr->pid == pid )
375 {
376 found = true;
377 break;
378 }
379 }
380
381 // release lock protecting local list of processes
382 remote_spinlock_unlock( XPTR( local_cxy , &cluster->pmgr.local_lock ) );
383
384 // allocate memory for a new local process descriptor
385 // and initialise it from reference cluster if required
386 if( !found )
387 {
388 // get extended pointer on reference process descriptor
389 xptr_t ref_xp = cluster_get_reference_process_from_pid( pid );
390
391 assert( (ref_xp != XPTR_NULL) , __FUNCTION__ , "illegal pid\n" );
392
393 // allocate memory for local process descriptor
394 process_ptr = process_alloc();
395 if( process_ptr == NULL ) return NULL;
396
397 // initialize local process descriptor copy
398 error = process_copy_init( process_ptr , ref_xp );
399 if( error ) return NULL;
400 }
401
402 return process_ptr;
403}
404
405//////////////////////////////////////////////////////////////////////////////////////////
406// File descriptor array related functions
407//////////////////////////////////////////////////////////////////////////////////////////
408
409///////////////////////////////////////////
410void process_fd_init( process_t * process )
411{
412 uint32_t fd;
413
414 remote_spinlock_init( XPTR( local_cxy , &process->fd_array.lock ) );
415
416 process->fd_array.current = 0;
417
418 // initialize array
419 for ( fd = 0 ; fd < CONFIG_PROCESS_FILE_MAX_NR ; fd++ )
420 {
421 process->fd_array.array[fd] = XPTR_NULL;
422 }
423}
424
425//////////////////////////////
426bool_t process_fd_array_full()
427{
428 // get extended pointer on reference process
429 xptr_t ref_xp = CURRENT_THREAD->process->ref_xp;
430
431 // get reference process cluster and local pointer
432 process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
433 cxy_t ref_cxy = GET_CXY( ref_xp );
434
435 // get number of open file descriptors from reference fd_array
436 uint32_t current = hal_remote_lw( XPTR( ref_cxy , &ref_ptr->fd_array.current ) );
437
438 return ( current >= CONFIG_PROCESS_FILE_MAX_NR );
439}
440
441/////////////////////////////////////////////////
442error_t process_fd_register( xptr_t file_xp,
443 uint32_t * file_id )
444{
445 bool_t found;
446 uint32_t id;
447 xptr_t xp;
448
449 // get extended pointer on reference process
450 xptr_t ref_xp = CURRENT_THREAD->process->ref_xp;
451
452 // get reference process cluster and local pointer
453 process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
454 cxy_t ref_cxy = GET_CXY( ref_xp );
455
456 // take lock protecting reference fd_array
457 remote_spinlock_lock( XPTR( ref_cxy , &ref_ptr->fd_array.lock ) );
458
459 found = false;
460
461 for ( id = 0; id < CONFIG_PROCESS_FILE_MAX_NR ; id++ )
462 {
463 xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->fd_array.array[id] ) );
464 if ( xp == XPTR_NULL )
465 {
466 found = true;
467 hal_remote_swd( XPTR( ref_cxy , &ref_ptr->fd_array.array[id] ) , file_xp );
468 hal_remote_atomic_add( XPTR( ref_cxy , &ref_ptr->fd_array.current ) , 1 );
469 *file_id = id;
470 break;
471 }
472 }
473
474 // release lock protecting reference fd_array
475 remote_spinlock_unlock( XPTR( ref_cxy , &ref_ptr->fd_array.lock ) );
476
477 if ( !found ) return EMFILE;
478 else return 0;
479}
480
481////////////////////////////////////////////////
482xptr_t process_fd_get_xptr( process_t * process,
483 uint32_t file_id )
484{
485 xptr_t file_xp;
486
487 // access local copy of process descriptor
488 file_xp = process->fd_array.array[file_id];
489
490 if( file_xp == XPTR_NULL )
491 {
492 // get reference process cluster and local pointer
493 xptr_t ref_xp = process->ref_xp;
494 cxy_t ref_cxy = GET_CXY( ref_xp );
495 process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
496
497 // access reference process descriptor
498 file_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->fd_array.array[file_id] ) );
499
500 // update local fd_array if found
501 if( file_xp != XPTR_NULL )
502 {
503 process->fd_array.array[file_id] = file_xp;
504 }
505 }
506
507 return file_xp;
508}
509
510///////////////////////////////////////////
511void process_fd_remote_copy( xptr_t dst_xp,
512 xptr_t src_xp )
513{
514 uint32_t fd;
515 xptr_t entry;
516
517 // get cluster and local pointer for src fd_array
518 cxy_t src_cxy = GET_CXY( src_xp );
519 fd_array_t * src_ptr = (fd_array_t *)GET_PTR( src_xp );
520
521 // get cluster and local pointer for dst fd_array
522 cxy_t dst_cxy = GET_CXY( dst_xp );
523 fd_array_t * dst_ptr = (fd_array_t *)GET_PTR( dst_xp );
524
525 // get the remote lock protecting the src fd_array
526 remote_spinlock_lock( XPTR( src_cxy , &src_ptr->lock ) );
527
528 // loop on all entries in source process fd_array
529 for( fd = 0 ; fd < CONFIG_PROCESS_FILE_MAX_NR ; fd++ )
530 {
531 entry = (xptr_t)hal_remote_lwd( XPTR( src_cxy , &src_ptr->array[fd] ) );
532
533 if( entry != XPTR_NULL )
534 {
535 // increment file descriptor ref count
536 vfs_file_count_up( entry );
537
538 // copy entry in destination process fd_array
539 hal_remote_swd( XPTR( dst_cxy , &dst_ptr->array[fd] ) , entry );
540 }
541 }
542
543 // release lock on source process fd_array
544 remote_spinlock_unlock( XPTR( src_cxy , &src_ptr->lock ) );
545}
546
547////////////////////////////////////////////////////////////////////////////////////
548// Thread related functions
549////////////////////////////////////////////////////////////////////////////////////
550
551/////////////////////////////////////////////////////
552error_t process_register_thread( process_t * process,
553 thread_t * thread,
554 trdid_t * trdid )
555{
556 ltid_t ltid;
557 bool_t found;
558
559 assert( (process != NULL) , __FUNCTION__ , "process argument is NULL" );
560
561 assert( (thread != NULL) , __FUNCTION__ , "thread argument is NULL" );
562
563 // search a free slot in th_tbl[]
564 found = false;
565 for( ltid = 0 ; ltid < CONFIG_THREAD_MAX_PER_CLUSTER ; ltid++ )
566 {
567 if( process->th_tbl[ltid] == NULL )
568 {
569 found = true;
570 break;
571 }
572 }
573
574 if( found )
575 {
576 // register thread in th_tbl[]
577 process->th_tbl[ltid] = thread;
578 process->th_nr++;
579
580 // returns trdid
581 *trdid = TRDID( local_cxy , ltid );
582 }
583
584 return (found) ? 0 : ENOMEM;
585
586} // end process_register_thread()
587
588///////////////////////////////////////////////
589void process_remove_thread( thread_t * thread )
590{
591 assert( (thread != NULL) , __FUNCTION__ , "thread argument is NULL" );
592
593 process_t * process = thread->process;
594
595 // get thread local index
596 ltid_t ltid = LTID_FROM_TRDID( thread->trdid );
597
598 // remove thread from th_tbl[]
599 process->th_tbl[ltid] = NULL;
600 process->th_nr--;
601
602} // process_remove_thread()
603
604/////////////////////////////////////////////////////
605error_t process_make_exec( exec_info_t * exec_info )
606{
607 char * path; // pathname to .elf file
608 process_t * process; // local pointer on new process
609 pid_t pid; // new process pid
610 xptr_t parent_xp; // extended pointer on parent process
611 cxy_t parent_cxy;
612 process_t * parent_ptr;
613 uint32_t parent_pid;
614 thread_t * thread; // pointer on new thread
615 pthread_attr_t attr; // main thread attributes
616 core_t * core; // pointer on selected core
617 lid_t lid; // selected core local index
618 error_t error;
619
620 // get parent and .elf pathname from exec_info
621 path = exec_info->path;
622 parent_xp = exec_info->parent_xp;
623
624 // get parent process cluster and local pointer
625 parent_cxy = GET_CXY( parent_xp );
626 parent_ptr = (process_t *)GET_PTR( parent_xp );
627 parent_pid = hal_remote_lw( XPTR( parent_cxy , &parent_ptr->pid ) );
628
629 exec_dmsg("\n[INFO] %s : thread %x on core[%x,‰d] enters for path = %s\n",
630 __FUNCTION__, CURRENT_THREAD->trdid, local_cxy, CURRENT_THREAD->core->lid, path );
631
632 // create new process descriptor
633 process = process_alloc();
634
635 if( process == NULL )
636 {
637 printk("\n[ERROR] in %s : no memory / cluster = %x / ppid = %x / path = %s\n",
638 __FUNCTION__ , local_cxy , parent_pid , path );
639 return ENOMEM;
640 }
641
642 // get a pid from the local cluster
643 error = cluster_pid_alloc( XPTR( local_cxy , process ) , &pid );
644
645 if( error )
646 {
647 printk("\n[ERROR] in %s : cannot get PID / cluster = %x / ppid = %x / path = %s\n",
648 __FUNCTION__ , local_cxy , parent_pid , path );
649 process_free( process );
650 return ENOMEM;
651 }
652
653 // initialize the process descriptor as the reference
654 process_reference_init( process , pid , parent_xp );
655
656 exec_dmsg("\n[INFO] %s : thread %x on core[%x,‰d] created process %x / path = %s\n",
657 __FUNCTION__, CURRENT_THREAD->trdid, local_cxy, CURRENT_THREAD->core->lid, pid, path );
658
659 // initialize vfs_root and vfs_cwd from parent process
660 xptr_t vfs_root_xp = hal_remote_lwd( XPTR( parent_cxy , &parent_ptr->vfs_root_xp ) );
661 vfs_file_count_up( vfs_root_xp );
662 process->vfs_root_xp = vfs_root_xp;
663
664 xptr_t vfs_cwd_xp = hal_remote_lwd( XPTR( parent_cxy , &parent_ptr->vfs_cwd_xp ) );
665 vfs_file_count_up( vfs_cwd_xp );
666 process->vfs_cwd_xp = vfs_cwd_xp;
667
668 // initialize embedded fd_array from parent process
669 process_fd_remote_copy( XPTR( local_cxy , &process->fd_array ),
670 XPTR( parent_cxy , &parent_ptr->fd_array) );
671
672 exec_dmsg("\n[INFO] %s : fd_array copied from process %x to process %x\n",
673 __FUNCTION__, parent_pid , pid );
674
675 // initialize signal manager TODO ??? [AG]
676 // signal_manager_init( process );
677
678 // register "code" and "data" vsegs as well as the process entry-point in VMM,
679 // using information contained in the elf file.
680 error = elf_load_process( path , process );
681
682 if( error )
683 {
684 printk("\n[ERROR] in %s : failed to access elf file for process %x / path = %s\n",
685 __FUNCTION__, pid , path );
686 process_destroy( process );
687 return error;
688 }
689
690 exec_dmsg("\n[INFO] %s : code and data vsegs registered for process %x / path = %s\n",
691 __FUNCTION__ , pid , path );
692
693 // select a core in cluster
694 lid = cluster_select_local_core();
695 core = &LOCAL_CLUSTER->core_tbl[lid];
696
697 // initialize pthread attributes for main thread
698 attr.attributes = PT_ATTR_DETACH | PT_ATTR_CLUSTER_DEFINED | PT_ATTR_CORE_DEFINED;
699 attr.cxy = local_cxy;
700 attr.lid = lid;
701
702 // create and initialize thread descriptor
703 error = thread_user_create( pid,
704 (void *)process->vmm.entry_point,
705 exec_info->args_pointers,
706 &attr,
707 &thread );
708 if( error )
709 {
710 printk("\n[ERROR] in %s : cannot create thread for process %x / path = %s\n",
711 __FUNCTION__, pid );
712 process_destroy( process );
713 return error;
714 }
715
716 exec_dmsg("\n[INFO] %s : thread created for process %x on core %d in cluster %x\n",
717 __FUNCTION__ , pid , core->lid , local_cxy );
718
719 // update children list in parent process
720 xlist_add_last( XPTR( parent_cxy , &parent_ptr->children_root ),
721 XPTR( local_cxy , &process->brothers_list ) );
722 hal_remote_atomic_add( XPTR( parent_cxy , &parent_ptr->children_nr) , 1 );
723
724 // activate new thread
725 thread_unblock( XPTR( local_cxy , thread ) , THREAD_BLOCKED_GLOBAL );
726
727 exec_dmsg("\n[INFO] %s : exit for process %x\n",
728 __FUNCTION__, process->pid );
729
730 return 0;
731
732} // end proces_make_exec()
733
734//////////////////////////
735void process_init_create()
736{
737 exec_info_t exec_info; // structure to be passed to process_make_exec()
738
739 error_t error1;
740 error_t error2;
741 error_t error3;
742 xptr_t stdin_xp;
743 xptr_t stdout_xp;
744 xptr_t stderr_xp;
745 uint32_t stdin_id;
746 uint32_t stdout_id;
747 uint32_t stderr_id;
748
749 process_dmsg("\n[INFO] %s : enters in cluster %x\n", __FUNCTION__ , local_cxy );
750
751 // open stdin / stdout / stderr pseudo-files
752 error1 = vfs_open( XPTR_NULL, CONFIG_DEV_STDIN , O_RDONLY, 0, &stdin_xp , &stdin_id );
753 error2 = vfs_open( XPTR_NULL, CONFIG_DEV_STDOUT, O_WRONLY, 0, &stdout_xp, &stdout_id );
754 error3 = vfs_open( XPTR_NULL, CONFIG_DEV_STDERR, O_WRONLY, 0, &stderr_xp, &stderr_id );
755
756 assert( ((error1 == 0) && (error2 == 0) && (error3 == 0)) , __FUNCTION__ ,
757 "cannot open stdin/stdout/stderr pseudo files\n");
758
759 assert( ((stdin_id == 0) && (stdout_id == 1) && (stderr_id == 2)) , __FUNCTION__ ,
760 "bad indexes for stdin/stdout/stderr\n");
761
762 // initialize the exec_info structure
763 exec_info.parent_xp = XPTR( local_cxy , &process_zero );
764 strcpy( exec_info.path , CONFIG_PROCESS_INIT_PATH );
765 exec_info.args_nr = 0;
766 exec_info.envs_nr = 0;
767
768 // create process_init and thread_init
769 error1 = process_make_exec( &exec_info );
770
771 assert( (error1 == 0) , __FUNCTION__ , "cannot create process_init\n");
772
773 process_dmsg("\n[INFO] %s : exit in cluster %x\n", __FUNCTION__ , local_cxy );
774
775 hal_fence();
776
777} // end process_init_create()
778
Note: See TracBrowser for help on using the repository browser.