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

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

rename hal_wbflush->hal_fence

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