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

Last change on this file since 274 was 204, checked in by alain, 7 years ago

Bug fix in kernel_init
-This line, and those below, will be ignored--

M params.mk
M kernel_config.h
M Makefile
M hdd/virt_hdd.dmg
M tools/bootloader_tsar/boot.c
M kernel/libk/bits.h
M kernel/libk/elf.c
M kernel/libk/xhtab.c
M kernel/libk/elf.h
M kernel/libk/xhtab.h
M kernel/devices/dev_pic.c
M kernel/mm/vmm.c
M kernel/mm/mapper.c
M kernel/mm/mapper.h
M kernel/vfs/devfs.h
M kernel/vfs/vfs.c
M kernel/vfs/vfs.h
M kernel/vfs/devfs.c
M kernel/kern/chdev.h
M kernel/kern/kernel_init.c
M kernel/kern/process.c
M kernel/kern/process.h
M hal/tsar_mips32/core/hal_remote.c
M hal/tsar_mips32/drivers/soclib_pic.c

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