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

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

The thread has already been registered in thread_user_create, so don't
register it twice.

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