Ignore:
Timestamp:
Dec 20, 2017, 4:51:09 PM (4 years ago)
Author:
alain
Message:

Fix bugs in exec

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/kern/process.c

    r408 r409  
    88 * Copyright (c) UPMC Sorbonne Universites
    99 *
    10  * This file is part of ALMOS-MKH..
     10 * This file is part of ALMOS-MKH.
    1111 *
    1212 * ALMOS-MKH is free software; you can redistribute it and/or modify it
     
    2828#include <hal_remote.h>
    2929#include <hal_uspace.h>
     30#include <hal_irqmask.h>
    3031#include <errno.h>
    3132#include <printk.h>
     
    4950#include <elf.h>
    5051#include <syscalls.h>
     52#include <signal.h>
    5153
    5254//////////////////////////////////////////////////////////////////////////////////////////
     
    124126    uint32_t    stderr_id;
    125127
    126 process_dmsg("\n[DBG] %s : core[%x,%d] enters for process %x\n",
    127 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , pid );
     128process_dmsg("\n[DBG] %s : core[%x,%d] enters for process %x / ppid = %x\n",
     129__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , pid , ppid );
    128130
    129131    // get model process cluster and local pointer
     
    136138    process->ref_xp = XPTR( local_cxy , process );
    137139
    138     // initialize vmm
     140    // initialize vmm as empty
    139141    vmm_init( process );
    140142
     
    142144__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , pid );
    143145
    144     // initialize fd_array (not for kernel)
     146    // initialize fd_array as empty
    145147    process_fd_init( process );
    146148
    147149    // create stdin / stdout / stderr pseudo-files
    148     if( ppid == 0 )                                        // process_init
     150    if( ppid == 0 )                                       // process_init
    149151    {
    150152        error1 = vfs_open( process,
     
    169171                           &stderr_id );
    170172    }
    171     else                                                  // other user process
     173    else                                                  // any other process
    172174    {
    173175        error1 = vfs_open( process,
     
    199201    "bad indexes : stdin %d / stdout %d / stderr %d \n", stdin_id , stdout_id , stderr_id );
    200202
    201     // initialize specific files, cwd_lock, and fd_array
     203    // initialize specific inodes root and cwd
    202204    process->vfs_root_xp = (xptr_t)hal_remote_lwd( XPTR( model_cxy,
    203205                                                         &model_ptr->vfs_root_xp ) );
    204206    process->vfs_cwd_xp  = (xptr_t)hal_remote_lwd( XPTR( model_cxy,
    205207                                                         &model_ptr->vfs_cwd_xp ) );
    206     process->vfs_bin_xp  = (xptr_t)hal_remote_lwd( XPTR( model_cxy,
    207                                                          &model_ptr->vfs_bin_xp ) );
    208     vfs_file_count_up( process->vfs_root_xp );
    209     vfs_file_count_up( process->vfs_cwd_xp );
    210     vfs_file_count_up( process->vfs_bin_xp );
    211 
     208    vfs_inode_remote_up( process->vfs_root_xp );
     209    vfs_inode_remote_up( process->vfs_cwd_xp );
     210
     211    remote_rwlock_init( XPTR( local_cxy , &process->cwd_lock ) );
     212
     213    // copy all open file descriptors (other than stdin / stdout / stderr)
    212214    process_fd_remote_copy( XPTR( local_cxy , &process->fd_array ),
    213215                            XPTR( model_cxy , &model_ptr->fd_array ) );
    214216
    215     remote_rwlock_init( XPTR( local_cxy , &process->cwd_lock ) );
    216 
    217 process_dmsg("\n[DBG] %s : core[%x,%d] / fd array initialised for process %x\n",
     217process_dmsg("\n[DBG] %s : core[%x,%d] / fd array for process %x\n",
    218218__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , pid );
    219219
     
    352352    remote_spinlock_unlock( copies_lock );
    353353
    354     // synchronize memory
    355354        hal_fence();
    356355
    357356    // From this point, the process descriptor is unreachable
    358357
    359     // close all open files and update dirty TODO [AG]
    360 
    361     // release signal manager TODO [AG]
     358    // FIXME close all open files and update dirty [AG]
    362359
    363360    // Decrease refcount for bin file, root file and cwd file
     
    374371}  // end process_destroy()
    375372
     373/////////////////////////////////////////////////
     374char * process_action_str( uint32_t action_type )
     375{
     376    if     ( action_type == BLOCK_ALL_THREADS   ) return "BLOCK";
     377    else if( action_type == UNBLOCK_ALL_THREADS ) return "UNBLOCK";
     378    else if( action_type == DELETE_ALL_THREADS  ) return "DELETE";
     379    else                                          return "undefined";
     380}
     381
     382////////////////////////////////////////////
     383void process_sigaction( process_t * process,
     384                        uint32_t    action_type )
     385{
     386    cxy_t              owner_cxy;         // owner cluster identifier
     387    lpid_t             lpid;              // process index in owner cluster
     388    cluster_t        * cluster;           // pointer on cluster manager
     389    xptr_t             root_xp;           // extended pointer on root of copies
     390    xptr_t             lock_xp;           // extended pointer on lock protecting copies
     391    xptr_t             client_xp;         // extended pointer on client thread
     392    uint32_t           rsp_count;         // number of expected responses
     393    xptr_t             rsp_xp;            // extended pointer on responses counter
     394    xptr_t             iter_xp;           // iterator on copies list
     395    xptr_t             process_xp;        // extended pointer on process copy
     396    cxy_t              process_cxy;       // process copy cluster identifier
     397    process_t        * process_ptr;       // local pointer on process copy
     398
     399signal_dmsg("\n[DBG] %s : enter for signal %s to process %x in cluster %x\n",
     400__FUNCTION__ , process_action_str( action_type ) , process , local_cxy );
     401
     402    thread_t         * this = CURRENT_THREAD;
     403
     404    // get extended pointer on client thread and response counter
     405    client_xp = XPTR( local_cxy , this );
     406    rsp_xp    = XPTR( local_cxy , &rsp_count );
     407
     408    // get owner cluster identifier and process lpid
     409    owner_cxy = CXY_FROM_PID( process->pid );
     410    lpid      = LPID_FROM_PID( process->pid );
     411
     412    assert( (owner_cxy == local_cxy) , __FUNCTION__ , "illegal cluster\n" );
     413   
     414    // get local pointer on local cluster manager
     415    cluster = LOCAL_CLUSTER;
     416
     417    // get extended pointers on copies root, copies lock, and number of copies
     418    root_xp   = XPTR( local_cxy , &cluster->pmgr.copies_root[lpid] );
     419    lock_xp   = XPTR( local_cxy , &cluster->pmgr.copies_lock[lpid] );
     420
     421    // initialize responses number
     422    rsp_count = cluster->pmgr.copies_nr[lpid];
     423
     424    // take the lock protecting the copies
     425    remote_spinlock_lock( lock_xp );
     426
     427    // send RPCs to all process copies
     428    XLIST_FOREACH( root_xp , iter_xp )
     429    {
     430        process_xp  = XLIST_ELEMENT( iter_xp , process_t , copies_list );
     431        process_cxy = GET_CXY( process_xp );
     432        process_ptr = (process_t *)GET_PTR( process_xp );
     433
     434printk("\n    @@@ %s : process = %x / pid = %x / ppid = %x\n",
     435__FUNCTION__ , process_ptr , process_ptr->pid , process_ptr->ppid );
     436
     437        rpc_process_sigaction_client( process_cxy,
     438                                      process_ptr,
     439                                      action_type,
     440                                      rsp_xp,
     441                                      client_xp );
     442    }
     443   
     444    // release the lock protecting process copies
     445    remote_spinlock_unlock( lock_xp );
     446
     447    // block and deschedule to wait response
     448    thread_block( CURRENT_THREAD , THREAD_BLOCKED_RPC );
     449    sched_yield("BLOCKED on RPC");
     450
     451signal_dmsg("\n[DBG] %s : exit for signal %s to process %x in cluster %x\n",
     452__FUNCTION__ , process_action_str( action_type ) , process , local_cxy );
     453
     454}  // end process_sigaction()
     455
    376456////////////////////////////////////////
    377 void process_kill( process_t * process )
    378 {
    379     thread_t     * thread;    // pointer on current thead descriptor
    380     uint32_t       ltid;      // index in process th_tbl
    381     uint32_t       count;     // thread counter
    382 
    383 printk("\n[@@@] %s enter\n", __FUNCTION__ );
    384 
    385     // get lock protecting th_tbl[]
     457void process_block( process_t * process,
     458                    xptr_t      rsp_xp,
     459                    xptr_t      client_xp )
     460{
     461    thread_t          * target;         // pointer on target thread
     462    uint32_t            ltid;           // index in process th_tbl
     463    thread_t          * killer;         // killer thread pointer
     464    uint32_t            count;          // requests counter
     465    volatile uint32_t   sig_rsp_count;  // responses counter
     466    cxy_t               client_cxy;     // client thread cluster identifier
     467    thread_t          * client_ptr;     // client thread pointer
     468    core_t            * client_core;    // client thread core pointer
     469
     470    // get local killer thread pointer
     471    killer = CURRENT_THREAD;
     472
     473signal_dmsg("\n[DBG] %s : enter for process %x in cluster %x\n",
     474__FUNCTION__ , process->pid , local_cxy );
     475
     476    // get lock protecting process th_tbl[]
    386477    spinlock_lock( &process->th_lock );
    387478
    388     // first loop on threads to send the THREAD_SIG_KILL signal to all process threads
    389     // we use both "ltid" and "count" indexes, because it can exist "holes" in th_tbl
    390     for( ltid = 0 , count = 0  ;
    391          (ltid < CONFIG_THREAD_MAX_PER_CLUSTER) && (count < process->th_nr) ;
     479    // initialize local responses counter
     480    sig_rsp_count = process->th_nr;
     481
     482    // loop on process threads to block and deschedule all threads in cluster
     483    // we use both "ltid" and "count" because it can exist "holes" in th_tbl
     484    for( ltid = 0 , count = 0 ; count < process->th_nr ; ltid++ )
     485    {
     486        target = process->th_tbl[ltid];
     487
     488        if( target != NULL )             // thread found
     489        {
     490            count++;
     491
     492            // set signal in target thread descriptor
     493            thread_set_signal( target , (uint32_t *)sig_rsp_count );
     494
     495            // set the global blocked bit in target thread descriptor.
     496            thread_block( target , THREAD_BLOCKED_GLOBAL );
     497
     498            // - if the killer thread and the target thread are not on the same core
     499            //   we want the scheduler of target thread to acknowlege the signal
     500            //   to be sure that the target thread is descheduled
     501            // - if the killer thread and the target thread are on the same core
     502            //   we simply decrement the response counter.
     503            if( killer->core->lid != target->core->lid )
     504            {
     505                dev_pic_send_ipi( local_cxy , target->core->lid );
     506            }
     507            else                                                         
     508            {
     509                hal_atomic_add( (void *)&sig_rsp_count , -1 );
     510            }
     511        }
     512    }
     513
     514    // poll the reponses counter
     515    while( 1 )
     516    {
     517        // exit loop when all responses received
     518        if ( sig_rsp_count == 0 ) break;
     519   
     520        // wait 1000 cycles before retry
     521        hal_fixed_delay( 1000 );
     522    }
     523
     524    // acknowledge client thread & unblock client thread if last response
     525    client_cxy  = GET_CXY( client_xp );
     526    client_ptr  = (thread_t *)GET_PTR( client_xp );
     527    client_core = (core_t *)hal_remote_lpt( XPTR( client_cxy , &client_ptr->core ) );
     528    if( hal_remote_atomic_add( rsp_xp , -1 ) == 1 )
     529    {
     530        thread_unblock( client_xp , THREAD_BLOCKED_RPC);
     531        dev_pic_send_ipi( client_cxy , client_core->lid );
     532    }
     533
     534signal_dmsg("\n[DBG] %s : exit for process %x in cluster %x / %d threads blocked\n",
     535__FUNCTION__ , process->pid , local_cxy , count );
     536
     537}  // end process_block()
     538
     539//////////////////////////////////////////
     540void process_unblock( process_t * process,
     541                      xptr_t      rsp_xp,
     542                      xptr_t      client_xp )
     543{
     544    thread_t          * target;        // pointer on target thead
     545    uint32_t            ltid;          // index in process th_tbl
     546    thread_t          * killer;        // killer thread pointer
     547    uint32_t            req_count;     // requests counter
     548    cxy_t               client_cxy;    // client thread cluster identifier
     549    thread_t          * client_ptr;    // client thread pointer
     550    core_t            * client_core;   // client thread core pointer
     551
     552    // get local killer thread pointer
     553    killer = CURRENT_THREAD;
     554
     555signal_dmsg("\n[DBG] %s : enter for process %x in cluster %x\n",
     556__FUNCTION__ , process->pid , local_cxy );
     557
     558    // get lock protecting process th_tbl[]
     559    spinlock_lock( &process->th_lock );
     560
     561    // loop on process threads to unblock all threads in cluster
     562    // we use both "ltid" and "req_count" because it can exist "holes" in th_tbl
     563    for( ltid = 0 , req_count = 0 ;
     564         req_count < process->th_nr ;
    392565         ltid++ )
    393566    {
     567        target = process->th_tbl[ltid];
     568
     569        if( target != NULL )             // thread found
     570        {
     571            req_count++;
     572
     573            // reset the global blocked bit in target thread descriptor.
     574            thread_unblock( XPTR( local_cxy , target ) , THREAD_BLOCKED_GLOBAL );
     575        }
     576    }
     577
     578    // acknowledge client thread & unblock client thread if last response
     579    client_cxy  = GET_CXY( client_xp );
     580    client_ptr  = (thread_t *)GET_PTR( client_xp );
     581    client_core = (core_t *)hal_remote_lpt( XPTR( client_cxy , &client_ptr->core ) );
     582    if( hal_remote_atomic_add( rsp_xp , -1 ) == 1 )
     583    {
     584        thread_unblock( client_xp , THREAD_BLOCKED_RPC);
     585        dev_pic_send_ipi( client_cxy , client_core->lid );
     586    }
     587
     588signal_dmsg("\n[DBG] %s : exit for process %x in cluster %x / %d threads blocked\n",
     589__FUNCTION__ , process->pid , local_cxy , req_count );
     590
     591}  // end process_unblock()
     592
     593/////////////////////////////////////////
     594void process_delete( process_t * process,
     595                     xptr_t      rsp_xp,
     596                     xptr_t      client_xp )
     597{
     598    thread_t          * thread;        // pointer on target thread
     599    uint32_t            ltid;          // index in process th_tbl
     600    uint32_t            count;         // request counter
     601    pid_t               pid;           // process PID
     602    cxy_t               client_cxy;    // client thread cluster identifier
     603    thread_t          * client_ptr;    // client thread pointer
     604    core_t            * client_core;   // client thread core pointer
     605
     606    // get process PID
     607    pid = process->pid;
     608
     609signal_dmsg("\n[DBG] %s : enter for process %x in cluster %x at cycle %d\n",
     610__FUNCTION__ , pid , local_cxy , (uint32_t)hal_get_cycles() );
     611
     612    // loop on threads to release memory allocated to threads
     613    for( ltid = 0 , count = 0  ; count < process->th_nr ; ltid++ )
     614    {
    394615        thread = process->th_tbl[ltid];
    395616
    396         if( thread != NULL )
     617        if( thread != NULL )             // thread found
    397618        {
    398             thread_kill( thread );
    399619            count++;
     620
     621            // detach thread from parent if attached
     622            if( (thread->flags & THREAD_FLAG_DETACHED) == 0 )
     623            thread_child_parent_unlink( thread->parent , XPTR( local_cxy , thread ) );
     624
     625            // detach thread from process
     626            process_remove_thread( thread );
     627
     628            // remove thread from scheduler
     629            sched_remove_thread( thread );
     630
     631            // release memory allocated to thread
     632            thread_destroy( thread );
    400633        }
    401634    }
    402635
    403 printk("\n[@@@] %s : %d signal(s) sent\n", __FUNCTION__, count );
    404 
    405     // second loop on threads to wait acknowledge from scheduler,
    406     // unlink thread from process and parent thread, and release thread descriptor
    407     for( ltid = 0 , count = 0  ;
    408          (ltid < CONFIG_THREAD_MAX_PER_CLUSTER) && (count < process->th_nr) ;
    409          ltid++ )
    410     {
    411         thread = process->th_tbl[ltid];
    412 
    413         if( thread != NULL )
    414         {
    415 
    416 printk("\n[@@@] %s start polling at cycle %d\n", __FUNCTION__ , hal_time_stamp() );
    417 
    418             // poll the THREAD_SIG_KILL bit until reset
    419             while( thread->signals & THREAD_SIG_KILL ) asm volatile( "nop" );
    420 
    421 printk("\n[@@@] %s exit polling\n", __FUNCTION__ );
    422 
    423             // detach target thread from parent if attached
    424             if( (thread->flags & THREAD_FLAG_DETACHED) != 0 )
    425             thread_child_parent_unlink( thread->parent , XPTR( local_cxy , thread ) );
    426 
    427             // unlink thread from process
    428             process_remove_thread( thread );
    429 
    430             // release memory for thread descriptor
    431             thread_destroy( thread );
    432 
    433             count++;
    434         }
    435     }
    436 
    437 printk("\n[@@@] %s : %d ack(s) received\n", __FUNCTION__, count );
    438 
    439     // release lock protecting th_tbl[]
    440     spinlock_unlock( &process->th_lock );
    441 
    442     // release memory allocated for process descriptor
    443     process_destroy( process );
    444 
    445 printk("\n[DBG] %s : core[%x,%d] exit\n",
    446 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid );
    447 
    448 }  // end process_kill()
     636    // release memory allocated to process descriptors
     637    // for all clusters other than the owner cluster
     638    if( local_cxy != CXY_FROM_PID( process->pid ) ) process_destroy( process );
     639
     640    // acknowledge client thread & unblock client thread if last response
     641    client_cxy  = GET_CXY( client_xp );
     642    client_ptr  = (thread_t *)GET_PTR( client_xp );
     643    client_core = (core_t *)hal_remote_lpt( XPTR( client_cxy , &client_ptr->core ) );
     644    if( hal_remote_atomic_add( rsp_xp , -1 ) == 1 )
     645    {
     646        thread_unblock( client_xp , THREAD_BLOCKED_RPC);
     647        dev_pic_send_ipi( client_cxy , client_core->lid );
     648    }
     649
     650signal_dmsg("\n[DBG] %s : exit for process %x in cluster %x at cycle %d\n",
     651__FUNCTION__ , pid , local_cxy , (uint32_t)hal_get_cycles() );
     652
     653}  // end process_delete()
    449654
    450655///////////////////////////////////////////////
     
    496701
    497702    return process_ptr;
    498 }
     703
     704}  // end process_get_local_copy()
    499705
    500706//////////////////////////////////////////////////////////////////////////////////////////
     
    621827        remote_spinlock_lock( XPTR( src_cxy , &src_ptr->lock ) );
    622828
    623     // loop on all entries in source process fd_array
    624     for( fd = 0 ; fd < CONFIG_PROCESS_FILE_MAX_NR ; fd++ )
     829    // loop on all entries other than
     830    // the three first entries: stdin/stdout/stderr
     831    for( fd = 3 ; fd < CONFIG_PROCESS_FILE_MAX_NR ; fd++ )
    625832        {
    626833                entry = (xptr_t)hal_remote_lwd( XPTR( src_cxy , &src_ptr->array[fd] ) );
     
    724931    "parent process must be the reference process\n" );
    725932
    726 process_dmsg("\n[DBG] %s : core[%x,%d] enter at cycle %d\n",
    727 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid , hal_get_cycles() );
     933fork_dmsg("\n[DBG] %s : core[%x,%d] enter at cycle %d\n",
     934__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid , (uint32_t)hal_get_cycles() );
    728935
    729936    // allocate a process descriptor
     
    736943    }
    737944
    738 process_dmsg("\n[DBG] %s : core[%x,%d] child process descriptor allocated at cycle %d\n",
    739  __FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, hal_get_cycles() );
     945fork_dmsg("\n[DBG] %s : core[%x,%d] child process descriptor allocated at cycle %d\n",
     946 __FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, (uint32_t)hal_get_cycles() );
    740947
    741948    // allocate a child PID from local cluster
     
    749956    }
    750957
    751 process_dmsg("\n[DBG] %s : core[%x, %d] child process PID allocated = %x at cycle %d\n",
    752  __FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, new_pid , hal_get_cycles() );
     958fork_dmsg("\n[DBG] %s : core[%x, %d] child process PID allocated = %x at cycle %d\n",
     959 __FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, new_pid , (uint32_t)hal_get_cycles() );
    753960
    754961    // initializes child process descriptor from parent process descriptor
     
    758965                            parent_process_xp );
    759966
    760 process_dmsg("\n[DBG] %s : core[%x, %d] child process initialised at cycle %d\n",
     967fork_dmsg("\n[DBG] %s : core[%x, %d] child process initialised at cycle %d\n",
    761968__FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, hal_get_cycles() );
    762969
     
    773980    }
    774981
    775 process_dmsg("\n[DBG] %s : core[%x, %d] child process VMM copied at cycle %d\n",
    776 __FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, hal_get_cycles() );
     982fork_dmsg("\n[DBG] %s : core[%x, %d] child process VMM copied at cycle %d\n",
     983__FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, (uint32_t)hal_get_cycles() );
    777984
    778985    // create child thread descriptor from parent thread descriptor
     
    789996    }
    790997
    791 process_dmsg("\n[DBG] %s : core[%x,%d] child thread created at cycle %d\n",
    792 __FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, hal_get_cycles() );
     998fork_dmsg("\n[DBG] %s : core[%x,%d] child thread created at cycle %d\n",
     999__FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, (uint32_t)hal_get_cycles() );
    7931000
    7941001    // update parent process GPT to set Copy_On_Write for shared data vsegs
     
    8041011    }
    8051012
    806 process_dmsg("\n[DBG] %s : core[%x,%d] COW set in parent_process at cycle %d\n",
    807 __FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, hal_get_cycles() );
     1013fork_dmsg("\n[DBG] %s : core[%x,%d] COW set in parent_process at cycle %d\n",
     1014__FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, (uint32_t)hal_get_cycles() );
    8081015
    8091016    // update children list in parent process
     
    8211028    *child_pid    = new_pid;
    8221029
     1030fork_dmsg("\n[DBG] %s : core[%x,%d] exit at cycle %d\n",
     1031__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, (uint32_t)hal_get_cycles() );
     1032
    8231033    return 0;
    8241034
    8251035}  // end process_make_fork()
     1036
     1037/*  deprecated because we don't wand to destroy the existing process descriptor
    8261038
    8271039/////////////////////////////////////////////////////
     
    8411053    pid  = exec_info->pid;
    8421054
    843     // check local cluster is old process owner
     1055    // check local cluster is process owner
    8441056    assert( (CXY_FROM_PID( pid ) == local_cxy), __FUNCTION__,
    8451057    "local cluster %x is not owner for process %x\n", local_cxy, pid );
     
    8761088        }
    8771089
    878 exec_dmsg("\n[DBG] %s : core[%x,%d] registered code/data vsegs / process %x / path = %s\n",
    879 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, pid, path );
     1090exec_dmsg("\n[DBG] %s : core[%x,%d] vsegs registered / path = %s\n",
     1091__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, path );
    8801092
    8811093    // select a core in local cluster to execute the main thread
     
    9081120                   XPTR( local_cxy , &new->brothers_list ) );
    9091121
    910     // FIXME request destruction of old process copies and threads in all clusters
     1122    // request destruction of old process copies and threads in all clusters
     1123    process_sigaction( old , SIGKILL );
    9111124
    9121125    // activate new thread
     
    9201133}  // end process_make_exec()
    9211134
     1135*/
     1136
     1137/////////////////////////////////////////////////////
     1138error_t process_make_exec( exec_info_t  * exec_info )
     1139{
     1140    char           * path;                    // pathname to .elf file
     1141    process_t      * process;                 // local pointer on old process
     1142    pid_t            pid;                     // old process identifier
     1143    thread_t       * thread;                  // pointer on new main thread
     1144    pthread_attr_t   attr;                    // main thread attributes
     1145    lid_t            lid;                     // selected core local index
     1146        error_t          error;
     1147
     1148        // get .elf pathname and PID from exec_info
     1149        path = exec_info->path;
     1150    pid  = exec_info->pid;
     1151
     1152    // check local cluster is process owner
     1153    assert( (CXY_FROM_PID( pid ) == local_cxy), __FUNCTION__,
     1154    "local cluster %x is not owner for process %x\n", local_cxy, pid );
     1155
     1156exec_dmsg("\n[DBG] %s : core[%x,%d] enters for process %x / path = %s\n",
     1157__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, pid , path );
     1158
     1159    // get process local pointer
     1160    process = (process_t *)cluster_get_local_process_from_pid( pid );
     1161   
     1162    assert( (process != NULL ) , __FUNCTION__ ,
     1163    "process %x not found in cluster %x\n", pid , local_cxy );
     1164
     1165    // reset the existing vmm
     1166    vmm_destroy( process );
     1167
     1168exec_dmsg("\n[DBG] %s : core[%x,%d] VMM cleared\n",
     1169__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid );
     1170
     1171    // block all existing process threads
     1172    process_sigaction( process , BLOCK_ALL_THREADS );
     1173
     1174    // kill all existing threads and process descriptors (other than owner)
     1175    process_sigaction( process , DELETE_ALL_THREADS );
     1176
     1177    // check no threads
     1178    assert( (process->th_nr == 0) , __FUNCTION__ , "no threads at this point" );
     1179
     1180exec_dmsg("\n[DBG] %s : core[%x,%d] all threads deleted\n",
     1181__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid );
     1182
     1183    // re-initialize VMM
     1184    vmm_init( process );
     1185
     1186    // register "code" and "data" vsegs as well as entry-point and vfs_bin_xp
     1187    // in VMM, using information contained in the elf file.
     1188        if( elf_load_process( path , process ) )
     1189        {
     1190                printk("\n[ERROR] in %s : failed to access .elf file for process %x / path = %s\n",
     1191                __FUNCTION__, pid , path );
     1192        process_destroy( process );
     1193        return -1;
     1194        }
     1195
     1196exec_dmsg("\n[DBG] %s : core[%x,%d] new vsegs registered / path = %s\n",
     1197__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, path );
     1198
     1199// @@@
     1200vmm_display( process , true );
     1201// @@@
     1202
     1203    // select a core in local cluster to execute the new main thread
     1204    lid  = cluster_select_local_core();
     1205
     1206    // initialize pthread attributes for new main thread
     1207    attr.attributes = PT_ATTR_DETACH | PT_ATTR_CLUSTER_DEFINED | PT_ATTR_CORE_DEFINED;
     1208    attr.cxy        = local_cxy;
     1209    attr.lid        = lid;
     1210
     1211    // create and initialize thread descriptor
     1212        error = thread_user_create( pid,
     1213                                (void *)process->vmm.entry_point,
     1214                                exec_info->args_pointers,
     1215                                &attr,
     1216                                &thread );
     1217        if( error )
     1218        {
     1219                printk("\n[ERROR] in %s : cannot create thread for process %x / path = %s\n",
     1220                       __FUNCTION__, pid , path );
     1221        process_destroy( process );
     1222        return -1;
     1223        }
     1224
     1225exec_dmsg("\n[DBG] %s : core[%x,%d] created main thread %x for new process %x\n",
     1226__FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, thread->trdid, pid );
     1227
     1228    // activate new thread
     1229        thread_unblock( XPTR( local_cxy , thread ) , THREAD_BLOCKED_GLOBAL );
     1230
     1231exec_dmsg("\n[DBG] %s : core[%x,%d] exit for path = %s\n",
     1232__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, path  );
     1233
     1234        return 0;
     1235
     1236}  // end process_make_exec()
     1237
     1238////////////////////////////////////////////
     1239void process_make_kill( process_t * process,
     1240                        uint32_t    sig_id )
     1241{
     1242    // this function must be executed by a thread running in owner cluster
     1243    assert( (CXY_FROM_PID( process->pid ) == local_cxy) , __FUNCTION__ ,
     1244    "must execute in owner cluster" );
     1245
     1246    // analyse signal type
     1247    switch( sig_id )
     1248    {
     1249        case SIGSTOP:     // block all threads
     1250        {
     1251            process_sigaction( process , BLOCK_ALL_THREADS );
     1252        }
     1253        break;
     1254        case SIGCONT:     // unblock all threads
     1255        {
     1256            process_sigaction( process , UNBLOCK_ALL_THREADS );
     1257        }
     1258        break;
     1259        case SIGKILL:  // block all threads, then delete all threads
     1260        {
     1261            process_sigaction( process , BLOCK_ALL_THREADS );
     1262            process_sigaction( process , DELETE_ALL_THREADS );
     1263            process_destroy( process );
     1264        }
     1265        break;
     1266    }
     1267}  // end process_make_kill()
     1268
     1269////////////////////////////////////////////
     1270void process_make_exit( process_t * process,
     1271                        uint32_t    status )
     1272{
     1273    // this function must be executed by a thread running in owner cluster
     1274    assert( (CXY_FROM_PID( process->pid ) == local_cxy) , __FUNCTION__ ,
     1275    "must execute in owner cluster" );
     1276
     1277    // block all threads in all clusters
     1278    process_sigaction( process , BLOCK_ALL_THREADS );
     1279
     1280    // delete all threads in all clusters
     1281    process_sigaction( process , DELETE_ALL_THREADS );
     1282
     1283    // delete local process descriptor
     1284    process_destroy( process );
     1285
     1286}  // end process_make_exit()
     1287
    9221288//////////////////////////
    9231289void process_init_create()
    9241290{
    925     exec_info_t   exec_info;     // structure to be passed to process_make_exec()
    926     process_t   * process;       // local pointer on process_init descriptor
    927     pid_t         pid;           // process_init identifier
    928     error_t       error;
    929 
    930 process_dmsg("\n[DBG] %s : enters in cluster %x\n",
    931 __FUNCTION__ , local_cxy );
     1291    process_t      * process;       // local pointer on process_init descriptor
     1292    pid_t            pid;           // process_init identifier
     1293    thread_t       * thread;        // local pointer on main thread
     1294    pthread_attr_t   attr;          // main thread attributes
     1295    lid_t            lid;           // selected core local index for main thread
     1296    error_t          error;
     1297
     1298kinit_dmsg("\n[DBG] %s :  core[%x,%d] enters\n",
     1299__FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid );
    9321300
    9331301    // allocates memory for process descriptor from local cluster
     
    9361304    {
    9371305                printk("\n[PANIC] in %s : no memory for process descriptor in cluster %x\n",
    938                 __FUNCTION__, local_cxy );
    939     }
    940 
    941     // get new PID from local cluster
     1306                __FUNCTION__, local_cxy  );
     1307    }
     1308
     1309    // get PID from local cluster
    9421310    error = cluster_pid_alloc( XPTR( local_cxy , process ) , &pid );
    9431311    if( error )
     
    9451313                printk("\n[PANIC] in %s : cannot allocate PID in cluster %x\n",
    9461314                __FUNCTION__, local_cxy );
    947     }
    948 
    949     // initialise the process desciptor (parent is local kernel process)
    950     process_reference_init( process,
     1315        process_destroy( process );
     1316    }
     1317
     1318    assert( (LPID_FROM_PID(pid) == 1) , __FUNCTION__ , "LPID must be 1 for process_init" );
     1319
     1320    // initialize process descriptor / parent is local process_zero
     1321    process_reference_init( process,
    9511322                            pid,
    952                             process_zero.pid,
     1323                            0,
    9531324                            XPTR( local_cxy , &process_zero ) );
    9541325
    955     // initialize the exec_info structure
    956     exec_info.pid          = pid;
    957     exec_info.args_nr      = 0;
    958     exec_info.envs_nr      = 0;
    959     strcpy( exec_info.path , CONFIG_PROCESS_INIT_PATH );
    960 
    961     // update process descriptor and create thread descriptor
    962         error = process_make_exec( &exec_info );
    963 
     1326kinit_dmsg("\n[DBG] %s : core[%x,%d] / process initialised\n",
     1327__FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid );
     1328
     1329    // register "code" and "data" vsegs as well as entry-point
     1330    // in process VMM, using information contained in the elf file.
     1331        if( elf_load_process( CONFIG_PROCESS_INIT_PATH , process ) )
     1332        {
     1333                printk("\n[PANIC] in %s : cannot access .elf file / path = %s\n",
     1334                __FUNCTION__, CONFIG_PROCESS_INIT_PATH );
     1335        process_destroy( process );
     1336        }
     1337
     1338kinit_dmsg("\n[DBG] %s : core[%x,%d] vsegs registered / path = %s\n",
     1339__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, CONFIG_PROCESS_INIT_PATH );
     1340
     1341    // select a core in local cluster to execute the main thread
     1342    lid  = cluster_select_local_core();
     1343
     1344    // initialize pthread attributes for main thread
     1345    attr.attributes = PT_ATTR_DETACH | PT_ATTR_CLUSTER_DEFINED | PT_ATTR_CORE_DEFINED;
     1346    attr.cxy        = local_cxy;
     1347    attr.lid        = lid;
     1348
     1349    // create and initialize thread descriptor
     1350        error = thread_user_create( pid,
     1351                                (void *)process->vmm.entry_point,
     1352                                NULL,
     1353                                &attr,
     1354                                &thread );
    9641355        if( error )
    965     {
    966                 printk("\n[PANIC] in %s : cannot exec %s in cluster %x\n",
    967                 __FUNCTION__, CONFIG_PROCESS_INIT_PATH , local_cxy );
    968     }
    969 
    970 process_dmsg("\n[DBG] %s : exit in cluster %x\n",
    971 __FUNCTION__ , local_cxy );
    972                
     1356        {
     1357                printk("\n[PANIC] in %s : cannot create main thread / path = %s\n",
     1358                __FUNCTION__, CONFIG_PROCESS_INIT_PATH );
     1359        process_destroy( process );
     1360        }
     1361
     1362    // activate thread
     1363        thread_unblock( XPTR( local_cxy , thread ) , THREAD_BLOCKED_GLOBAL );
     1364
    9731365    hal_fence();
    9741366
     1367kinit_dmsg("\n[DBG] %s : core[%x,%d] exit / main thread = %x\n",
     1368__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, thread );
     1369
    9751370}  // end process_init_create()
    9761371
Note: See TracChangeset for help on using the changeset viewer.