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

Last change on this file since 16 was 14, checked in by alain, 8 years ago

Bugs fix.

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