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

Last change on this file since 176 was 172, checked in by max@…, 7 years ago

style

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