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

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

Introduce the chdev_t structure in place of the device_t structure.

File size: 25.9 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)
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 <almos_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
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
273    // first loop on threads to send the THREAD_SIG_KILL signal to all process threads
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
548    if( process == NULL )
549    {
550        printk("\n[PANIC] in %s : process argument is NULL\n", __FUNCTION__ );
551        hal_core_sleep();
552    }
553    if( thread == NULL )
554    {
555        printk("\n[PANIC] in %s : thread argument is NULL\n", __FUNCTION__ );
556        hal_core_sleep();
557    }
558
559    // search a free slot in th_tbl[]
560    found = false;
561    for( ltid = 0 ; ltid < CONFIG_THREAD_MAX_PER_CLUSTER ; ltid++ )
562    {
563        if( process->th_tbl[ltid] == NULL )
564        {
565            found = true;
566            break;
567        }
568    }
569
570    if( found )
571    {
572        // register thread in th_tbl[]
573        process->th_tbl[ltid] = thread;
574        process->th_nr++;
575
576        // returns trdid
577        *trdid = TRDID( local_cxy , ltid );
578    }
579
580    return (found) ? 0 : ENOMEM;
581}
582   
583///////////////////////////////////////////////
584void process_remove_thread( thread_t * thread )
585{
586    if( thread == NULL )
587    {
588        printk("\n[PANIC] in %s : thread argument is NULL\n", __FUNCTION__ );
589        hal_core_sleep();
590    }
591   
592    process_t * process = thread->process;
593
594    // get thread local index
595    ltid_t  ltid = LTID_FROM_TRDID( thread->trdid );
596
597    // remove thread from th_tbl[]
598    process->th_tbl[ltid] = NULL;
599    process->th_nr--;
600}
601
602/////////////////////////////////////////////////////
603error_t process_make_exec( exec_info_t  * exec_info )
604{
605    char           * path;                            // pathname to .elf file
606    process_t      * process;                         // pointer on new process
607    pid_t            pid;                             // new process pid
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
612        error_t          error; 
613
614        // get pid and pathname to .elf file 
615        path  = exec_info->path;
616    pid   = exec_info->pid;
617   
618    if( CXY_FROM_PID( pid ) != local_cxy )
619    {
620        printk("\n[PANIC] in %s : illegal process PID %x in cluster %x\n",
621               __FUNCTION__ , pid , local_cxy );
622        hal_core_sleep();
623    }
624
625    exec_dmsg("\n[INFO] %s enters in cluster %x for process %x / path = %s\n",
626                __FUNCTION__ , local_cxy , pid , path );
627
628    // create new process descriptor
629    process = process_alloc();
630
631    if( process == NULL )
632    {
633        printk("\n[ERROR] in %s : no memory in cluster %x for process %x / path = %s\n",
634               __FUNCTION__ , local_cxy , pid , path );
635        return ENOMEM;
636    }
637
638    // initialize the process descriptor as the reference
639    process_reference_init( process , pid , exec_info->ppid );
640                               
641    // restore from exec_info the extended pointer on vfs root, cwd, and bin
642    process->vfs_root_xp = exec_info->vfs_root_xp;
643    process->vfs_cwd_xp  = exec_info->vfs_cwd_xp;
644    process->vfs_bin_xp  = exec_info->vfs_bin_xp;
645
646    // restore from exec_info the embedded fd_array
647    process_fd_remote_copy( XPTR( local_cxy , &process->fd_array ), exec_info->fd_array_xp );
648                           
649    exec_dmsg("\n[INFO] %s restaured fd-array in cluster %x for process %x / path = %s\n",
650                __FUNCTION__, local_cxy , pid , path );
651
652        // initialize signal manager TODO ??? [AG]
653        // signal_manager_init( process );
654
655    // initialize process VMM
656        vmm_init( process );
657
658    exec_dmsg("\n[INFO] %s initialized VMM in cluster %x for process %x / path = %s\n",
659                __FUNCTION__ , local_cxy , pid , path );
660
661    // register "code" and "data" vsegs as well a the process entry-point in VMM,
662    // using informations contained in the elf file.
663        error = elf_load_process( path , process );
664
665        if( error )
666        {
667                printk("\n[ERROR] in %s : failed to access elf file for process %x / path = %s\n", 
668                       __FUNCTION__, pid , path );
669        process_destroy( process );
670        return error;
671        }
672
673    // create "heap" vseg descriptor
674    vseg_t * heap_vseg = vmm_create_vseg( process,
675                                          CONFIG_VMM_HEAP_BASE,
676                                          CONFIG_VMM_HEAP_SIZE,
677                                          VSEG_TYPE_HEAP );
678    if( heap_vseg == NULL )
679        {
680                printk("\n[ERROR] in %s : cannot create heap vseg for process %x / path = %s\n",
681                       __FUNCTION__, pid , path );
682        process_destroy( process );
683        return error;
684        }
685
686    // create "stack" vseg descriptor for associated main thread
687    vseg_t * stack_vseg = vmm_create_vseg( process,
688                                           0,             // base defined by VMM
689                                           0,             // size defined by VMM
690                                           VSEG_TYPE_STACK );
691    if( stack_vseg == NULL )
692        {
693                printk("\n[ERROR] in %s : cannot create stack 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
704    attr.pid          = pid;
705    attr.entry_func   = (void*)process->vmm.entry_point;
706    attr.entry_args   = exec_info->args_pointers; 
707    attr.flags        = PT_FLAG_DETACH;             // main thread always detached
708    attr.cxy          = local_cxy;
709    attr.lid          = lid;
710
711    // create and initialise thread descriptor, link thread & process
712        error = thread_user_create( &thread, 
713                                &attr,
714                                stack_vseg->min,
715                                stack_vseg->max - stack_vseg->min );
716        if( error )
717        {
718                printk("\n[ERROR] in %s : cannot create thread for process %x / path = %s\n",
719                       __FUNCTION__, pid , path );
720        process_destroy( process );
721        return error;
722        }
723
724        // Register thread in scheduler
725        sched_register_thread( core , thread );
726
727        exec_dmsg("\n[INFO] %s created thread for process %x on core %d in cluster %x\n",
728               __FUNCTION__ , process->pid , core->lid , local_cxy );
729
730    // activate new thread
731        thread_unblock( XPTR( local_cxy , thread ) , THREAD_BLOCKED_GLOBAL );
732
733        return 0;
734
735} // end process_make_exec()
736
737//////////////////////////
738void process_init_create()
739{
740        process_t   * process_init;  // process_init descriptor
741        thread_t    * thread_init;   // process_init main thread descriptor
742    pid_t         init_pid;      // process_init pid
743    exec_info_t   exec_info;     // structure to be passed to process_make_exec()
744
745        error_t error1 = 0;
746        error_t error2 = 0;
747        error_t error3 = 0;
748
749        process_dmsg("\n[INFO] %s enters in cluster %x\n", __FUNCTION__ , local_cxy );
750
751    // allocate memory for process descriptor
752    process_init = process_alloc();
753    if( process_init == NULL )
754    {
755        printk("\n[PANIC] in %s : no memory for process descriptor in cluster %x\n",
756               __FUNCTION__ , local_cxy );
757        hal_core_sleep();
758    }
759
760    // get a pid from the local cluster
761    xptr_t xp_process = XPTR( local_cxy , process_init );
762    error1 = cluster_pid_alloc( xp_process , &init_pid );
763    if( error1 )
764    {
765        printk("\n[PANIC] in %s : cannot get PID in cluster %x\n", 
766               __FUNCTION__ , local_cxy );
767                hal_core_sleep();
768    }
769 
770    // initializes process_init descriptor as the reference
771        process_reference_init( process_init , init_pid , process_zero.pid );
772
773    // initialize process_init VMM
774        vmm_init( process_init );
775
776    // initializes vfs_root and vfs_cwd from process_zero
777        vfs_file_count_up( process_zero.vfs_root_xp );
778        process_init->vfs_root_xp = process_zero.vfs_root_xp;
779
780        vfs_file_count_up( process_zero.vfs_cwd_xp );
781        process_init->vfs_cwd_xp  = process_zero.vfs_cwd_xp;
782
783    // update children list in process_zero
784        xlist_add_last( XPTR( local_cxy , &process_zero.children_root ),
785                    XPTR( local_cxy , &process_init->brothers_list ) );
786        process_zero.children_nr = 1;
787
788    // TODO open stdin / stdout / stderr pseudo-files
789    xptr_t  stdin_xp;
790    xptr_t  stdout_xp;
791    xptr_t  stderr_xp; 
792
793        // error1 = vfs_open( process_init->vfs_cwd_xp, NULL, VFS_O_RDONLY, &stdin_xp );
794        // error2 = vfs_open( process_init->vfs_cwd_xp, NULL, VFS_O_WRONLY, &stdout_xp );
795        // error3 = vfs_open( process_init->vfs_cwd_xp, NULL, VFS_O_WRONLY, &stderr_xp );
796
797        if( error1 || error2 || error3 )
798        {
799                if( !error1 ) vfs_close( stdin_xp  , NULL );
800                if( !error2 ) vfs_close( stdout_xp , NULL );
801                if( !error3 ) vfs_close( stderr_xp , NULL );
802   
803                printk("\n[PANIC] in %s : cannot open stdin/stdout/stderr in cluster %x\n",
804               __FUNCTION__ , local_cxy );
805        hal_core_sleep();
806        }
807
808    // register stdin / stdout / stderr in the fd_array 3 first slots
809        process_init->fd_array.array[0] = stdin_xp;
810        process_init->fd_array.array[1] = stdout_xp;
811        process_init->fd_array.array[2] = stderr_xp;
812    process_init->fd_array.current  = 3;
813
814    // initialize the exec_info structure
815    exec_info.pid          = process_init->pid;
816    exec_info.ppid         = process_init->ppid;
817    exec_info.fd_array_xp  = XPTR( local_cxy , &process_init->fd_array );
818    exec_info.vfs_root_xp  = process_init->vfs_root_xp;
819    exec_info.vfs_cwd_xp   = process_init->vfs_cwd_xp;
820    exec_info.vfs_bin_xp   = process_init->vfs_bin_xp;
821
822    // TODO thread_init ???
823    // exec_info.args_nr      = 1;
824    // exec_info.envs_nr      = 1;
825    // strcpy( exec_info.args[0] , "init" );
826    // strcpy( exec_info.envs[0] , "ALMOS-MKH.CONFIG = "CONFIG_ALMOS_VERSION );
827    // strcpy( exec_info.path    , INIT_PATHNAME );
828
829    // create process_init and thread_init
830        error1 = process_make_exec( &exec_info );
831        if( error1 )
832        {
833        printk("\n[PANIC] in %s : cannot create main thread in cluster %x\n",
834               __FUNCTION__ , local_cxy );
835                hal_core_sleep();
836    }
837
838        process_dmsg("\n[INFO] %s successfully exit in cluster %x\n", __FUNCTION__ , local_cxy );
839               
840    hal_wbflush();
841
842} // end process_init_create()
843
844
Note: See TracBrowser for help on using the repository browser.