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

Last change on this file since 199 was 188, checked in by alain, 7 years ago

Redefine the PIC device API.

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