Changeset 433 for trunk/kernel/syscalls


Ignore:
Timestamp:
Feb 14, 2018, 3:40:19 PM (6 years ago)
Author:
alain
Message:

blip

Location:
trunk/kernel/syscalls
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/syscalls/sys_display.c

    r421 r433  
    2525#include <hal_uspace.h>
    2626#include <errno.h>
     27#include <vmm.h>
    2728#include <cluster.h>
    2829#include <thread.h>
    2930#include <process.h>
     31#include <string.h>
    3032
    3133
     
    3537                 reg_t  arg1 )
    3638{
     39    // get thread, process and core
     40    thread_t  * this    = CURRENT_THREAD;
     41    process_t * process = this->process;
     42    core_t    * core    = this->core;
     43
     44#if CONFIG_DEBUG_SYS_DISPLAY
     45uint64_t    tm_start;
     46uint64_t    tm_end;
     47tm_start = hal_get_cycles();
     48if( CONFIG_DEBUG_SYS_DISPLAY < tm_start )
     49printk("\n[DBG] %s : thread %d enter / process %x / cycle = %d\n",
     50__FUNCTION__, this, process->pid, (uint32_t)tm_start );
     51#endif
     52
    3753    if( type == DISPLAY_STRING )
    3854    {
    3955        paddr_t   paddr;
    4056        char      kbuf[256];
     57        uint32_t  length;
    4158
    4259        char    * string = (char *)arg0;
    4360 
    4461        // check string in user space
    45         if( vmm_v2p_translate( false , string , &paddr ) ) return -1;
     62        if( vmm_v2p_translate( false , string , &paddr ) )
     63        {
     64            printk("\n[ERROR] in %s : string buffer %x unmapped\n",
     65            __FUNCTION__ , string );
     66            return -1;
     67        }
    4668
    4769        // ckeck string length
    48         if( hal_strlen_from_uspace( string ) >= 256 ) return -1;
     70        length = hal_strlen_from_uspace( string );
     71        if( length >= 256 )
     72        {
     73            printk("\n[ERROR] in %s : string length %d too large\n",
     74            __FUNCTION__ , length );
     75            return -1;
     76        }
    4977
    5078        // copy string in kernel space
    5179        hal_strcpy_from_uspace( kbuf , string , 256 );
    52 
    53         // get thread, process and core
    54         thread_t  * this    = CURRENT_THREAD;
    55         process_t * process = this->process;
    56         core_t    * core    = this->core;
    5780
    5881        // print message on TXT0 kernel terminal
     
    6083        this->trdid , process->pid , local_cxy, core->lid ,
    6184        (uint32_t)hal_get_cycles() , kbuf );
    62 
    63             return 0;
    6485    }
    6586    else if( type == DISPLAY_VMM )
     
    7091        xptr_t process_xp = cluster_get_reference_process_from_pid( pid );
    7192
    72             if( process_xp == XPTR_NULL ) return -1;
     93            if( process_xp == XPTR_NULL )
     94        {
     95            printk("\n[ERROR] in %s : undefined PID %x\n",
     96            __FUNCTION__ , pid );
     97            return -1;
     98        }
    7399
    74100        // get cluster and local pointer on process
     
    85111            rpc_vmm_display_client( process_cxy , process_ptr , true );
    86112        }
    87 
    88             return 0;
    89113    }
    90114    else if( type == DISPLAY_SCHED )
     
    94118
    95119        // check cluster argument
    96             if( cluster_is_undefined( cxy ) ) return -1;
     120            if( cluster_is_undefined( cxy ) )
     121        {
     122            printk("\n[ERROR] in %s : undefined cluster identifier %x\n",
     123            __FUNCTION__ , cxy );
     124            return -1;
     125        }
    97126
    98127        // check core argument
    99         if( lid >= LOCAL_CLUSTER->cores_nr ) return -1;
     128        if( lid >= LOCAL_CLUSTER->cores_nr )
     129        {
     130            printk("\n[ERROR] in %s : undefined local index %d\n",
     131            __FUNCTION__ , lid );
     132            return -1;
     133        }
    100134
    101         // call kernel function
    102135        if( cxy == local_cxy )
    103136        {
     
    108141            rpc_sched_display_client( cxy , lid );
    109142        }
    110 
    111             return 0;
    112143    }
    113144    else if( type == DISPLAY_PROCESS )
     
    116147
    117148        // check cluster argument
    118             if( cluster_is_undefined( cxy ) ) return -1;
     149            if( cluster_is_undefined( cxy ) )
     150        {
     151            printk("\n[ERROR] in %s : undefined cluster identifier %x\n",
     152            __FUNCTION__ , cxy );
     153            return -1;
     154        }
    119155
    120         // call kernel function
    121156        cluster_processes_display( cxy );
    122 
    123         return 0;
    124157    }
    125158    else if( type == DISPLAY_VFS )
     
    128161        process_t * process = CURRENT_THREAD->process;
    129162        vfs_display( process->vfs_root_xp );
    130 
    131         return 0;
    132163    }
    133164    else if( type == DISPLAY_CHDEV )
    134165    {
    135         // call kernel function
    136166        chdev_dir_display();
     167    }
     168    else
     169    {
     170        printk("\n[ERROR] in %s : undefined display type %x\n",
     171        __FUNCTION__ , type );
     172        return -1;
     173    }
    137174
    138         return 0;
    139     }
    140     else return -1;
     175#if CONFIG_DEBUG_SYS_DISPLAY
     176tm_end = hal_get_cycles();
     177if( CONFIG_DEBUG_SYS_DISPLAY < tm_end )
     178printk("\n[DBG] %s : thread %x exit / process %x / cost = %d / cycle %d\n",
     179__FUNCTION__, this, process->pid, (uint32_t)(tm_end - tm_start) , (uint32_t)tm_end );
     180#endif
    141181
    142 }  // end sys_get_sched()
     182    return 0;
     183
     184}  // end sys_display()
  • trunk/kernel/syscalls/sys_exec.c

    r421 r433  
    149149/////////////////////////////////////////////////////////////////////////////////////////
    150150// Implementation note:
    151 // This function build an exec_info_t structure containing all informations
     151// This function must be called by the main thread (thread 0 in owner cluster).
     152// IT build an exec_info_t structure containing all informations
    152153// required to initialize the new process descriptor and the associated thread.
    153 // It includes the process PID (unchanged), main() arguments, environment variables,
     154// It includes the process main() arguments, the environment variables,
    154155// and the pathname to the new process .elf file.
    155156// It calls the process_exec_get_strings() functions to copy the main() arguments and
     
    169170    error_t       error;
    170171
    171     // get parent process pid
     172    // get calling thread, process, & pid
    172173    thread_t    * this    = CURRENT_THREAD;
    173174    process_t   * process = this->process;
    174175    pid_t         pid     = process->pid;
    175176
    176 #if CONFIG_SYSCALL_DEBUG
     177    assert( (CXY_FROM_PID( pid ) == local_cxy) , __FUNCTION__ ,
     178    "must be called in the owner cluster\n");
     179
     180    assert( (LTID_FROM_TRDID( this->trdid ) == 0) , __FUNCTION__ ,
     181    "must be called by the main thread\n");
     182
     183    assert( (args == NULL) , __FUNCTION__ ,
     184    "args not supported yet\n" );
     185
     186    assert( (envs == NULL) , __FUNCTION__ ,
     187    "args not supported yet\n" );
     188
     189    // get owner cluster
     190
     191    // check pathname length
     192    if( hal_strlen_from_uspace( pathname ) >= CONFIG_VFS_MAX_PATH_LENGTH )
     193    {
     194
     195#if CONFIG_DEBUG_SYSCALLS_ERROR
     196printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ );
     197#endif
     198        this->errno = ENFILE;
     199        return -1;
     200    }
     201
     202    // copy pathname in exec_info structure (kernel space)
     203    hal_strcpy_from_uspace( exec_info.path , pathname , CONFIG_VFS_MAX_PATH_LENGTH );
     204
     205#if CONFIG_DEBUG_SYS_EXEC
    177206uint64_t      tm_start;
    178207uint64_t      tm_end;
    179208tm_start = hal_get_cycles();
    180 printk("\n[DBG] %s : core[%x,%d] enter / process %x / cycle = %d\n",
    181 __FUNCTION__, local_cxy, this->core->lid, pid, (uint32_t)tm_start );
    182 #endif
    183 
    184     // get owner cluster
    185     cxy_t  owner_cxy = CXY_FROM_PID( pid );
    186 
    187     // check pathname length
    188     if( hal_strlen_from_uspace( pathname ) >= CONFIG_VFS_MAX_PATH_LENGTH )
    189     {
    190         printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ );
    191         this->errno = ENFILE;
    192         return -1;
    193     }
    194 
    195     // copy pathname in exec_info structure (kernel space)
    196     hal_strcpy_from_uspace( exec_info.path , pathname , CONFIG_VFS_MAX_PATH_LENGTH );
    197 
    198     // check args argument
    199     assert( (args == NULL) , __FUNCTION__ ,
    200     "args not supported yet\n" );
    201 
    202     // check envs argument
    203     assert( (envs == NULL) , __FUNCTION__ ,
    204     "args not supported yet\n" );
     209if( CONFIG_DEBUG_SYS_EXEC < tm_start )
     210printk("\n[DBG] %s : thread %x enter / process %x / path %s / cycle = %d\n",
     211__FUNCTION__, this, pid, exec_info.path, (uint32_t)tm_start );
     212#endif
    205213
    206214    // check and store args in exec_info structure if required
     
    209217        if( process_exec_get_strings( &exec_info , true , args ) )
    210218        {
    211             printk("\n[ERROR] in %s : cannot access args\n", __FUNCTION__ );
     219
     220#if CONFIG_DEBUG_SYSCALLS_ERROR
     221printk("\n[ERROR] in %s : cannot access args\n", __FUNCTION__ );
     222#endif
    212223            this->errno = error;
    213224            return -1;
     
    220231        if( process_exec_get_strings( &exec_info , false , envs ) )
    221232        {
    222             printk("\n[ERROR] in %s : cannot access envs\n", __FUNCTION__ );
     233
     234#if CONFIG_DEBUG_SYCALLS_ERROR
     235printk("\n[ERROR] in %s : cannot access envs\n", __FUNCTION__ );
     236#endif
    223237            this->errno = error;
    224238            return -1;
     
    226240    }
    227241
    228     // register PID in exec_info
    229     exec_info.pid = pid;
    230 
    231     // call process_make_exec (local or remote)
    232     if( owner_cxy == local_cxy )
    233     {
    234         error = process_make_exec( &exec_info );
    235     }
    236     else
    237     {
    238         rpc_process_make_exec_client( owner_cxy,
    239                                       &exec_info,
    240                                       &error );
    241     }
     242    // call relevant kernel function
     243    error = process_make_exec( &exec_info );
    242244
    243245    if( error )
    244246    {
    245         printk("\n[ERROR] in %s : cannot create new process %x in cluster %x\n",
    246         __FUNCTION__, pid, owner_cxy );
     247
     248#if CONFIG_DEBUG_SYSCALLS_ERROR
     249printk("\n[ERROR] in %s : cannot create process %x in cluster %x\n",
     250__FUNCTION__, pid, CXY_FROM_PID( pid );
     251#endif
    247252        this->errno = error;
    248253        return -1;
    249254    }
    250255
    251 #if CONFIG_SYSCALL_DEBUG
     256#if CONFIG_DEBUG_SYS_EXEC
    252257tm_end = hal_get_cycles();
    253 printk("\n[DBG] %s : core[%x,%d] exit / process %x / path = %s / cost = %d / cycle %d\n",
    254 __FUNCTION__, local_cxy, this->core->lid, pid, exec_info.path,
    255 (uint32_t)(tm_end - tm_start) , (uint32_t)tm_end );
    256 #endif
    257 
    258     return 0;
     258if( CONFIG_DEBUG_SYS_EXEC < tm_end )
     259printk("\n[DBG] %s : thread %x exit / process %x / cost = %d / cycle %d\n",
     260__FUNCTION__, this, pid, (uint32_t)(tm_end - tm_start), (uint32_t)tm_end );
     261#endif
     262
     263    // deschedule <=> old thread suicide because the BLOCKED_GLOBAL
     264    // and the FLAG_REQ_DELETE have been set by process_make_exec()
     265    sched_yield( "old process suicide in sys_exec()" );
     266
     267    assert( false , __FUNCTION__ , "This code should not be executed\n" );
     268
     269    return 0; 
    259270
    260271} // end sys_exec()
  • trunk/kernel/syscalls/sys_exit.c

    r416 r433  
    3636int sys_exit( uint32_t status )
    3737{
    38     uint32_t    save_sr;       // required to enable IRQs
     38    reg_t       save_sr;       // required to enable IRQs
    3939
    40     thread_t  * this = CURRENT_THREAD;
    41     pid_t       pid  = this->process->pid;
     40    thread_t  * this    = CURRENT_THREAD;
     41    process_t * process = this->process;
     42    pid_t       pid     = process->pid;
    4243
    43 #if CONFIG_SYSCALL_DEBUG
     44#if CONFIG_DEBUG_SYS_EXIT
    4445uint64_t    tm_start;
    4546uint64_t    tm_end;
    4647tm_start = hal_get_cycles();
    47 printk("\n[DBG] %s : core[%x,%d] enter / process %x / status %x / cycle %d\n",
    48 __FUNCTION__ , local_cxy , this->core->lid , pid , status , (uint32_t)tm_start );
     48if( CONFIG_DEBUG_SYS_EXIT < tm_start )
     49printk("\n[DBG] %s : thread %x enter / process %x / status %x / cycle %d\n",
     50__FUNCTION__ , this, pid , status , (uint32_t)tm_start );
    4951#endif
    5052
    51     // get owner process cluster
    52     cxy_t   owner_cxy  = CXY_FROM_PID( pid );
     53    // get cluster and pointers on process in owner cluster
     54    xptr_t      owner_xp  = cluster_get_owner_process_from_pid( pid );
     55    cxy_t       owner_cxy = GET_CXY( owner_xp );
     56    process_t * owner_ptr = GET_PTR( owner_xp );
     57
     58    assert( (owner_xp != XPTR_NULL) , __FUNCTION__ , "owner_xp cannot be NULL\n" );
    5359
    5460    // enable IRQs
    5561    hal_enable_irq( &save_sr );
    5662
    57     // execute process_make_exit() function in owner cluster
    58     if( local_cxy == owner_cxy )                                // owner is local
    59     {
    60         process_make_exit( pid , status );
    61     }
    62     else                                                        // owner is remote
    63     {
    64         rpc_process_make_exit_client( owner_cxy, pid , status );
    65     }
     63    // the process_make_kill() function must be executed
     64    // by an RPC thread in reference cluster
     65    rpc_process_make_kill_client( owner_cxy, owner_ptr, true , status );
    6666
    6767    // restore IRQs
     
    7070    hal_fence();
    7171
    72 #if CONFIG_SYSCALL_DEBUG
     72#if CONFIG_DEBUG_SYS_EXIT
    7373tm_end = hal_get_cycles();
    74 printk("\n[DBG] %s : core[%x,%d] exit / process %x / status %x / cost = %d\n",
    75 __FUNCTION__ , local_cxy , this->core->lid , pid , status , (uint32_t)(tm_end - tm_start) );
     74if( CONFIG_DEBUG_SYS_EXIT < tm_end )
     75printk("\n[DBG] %s : thread %x exit / process %x / status %x / cost = %d / cycle %d\n",
     76__FUNCTION__, this, pid, status, (uint32_t)(tm_end - tm_start), (uint32_t)tm_end );
    7677#endif
    7778
  • trunk/kernel/syscalls/sys_fork.c

    r416 r433  
    6363    parent_pid         = parent_process_ptr->pid;
    6464
    65 #if CONFIG_SYSCALL_DEBUG
     65#if CONFIG_DEBUG_SYS_FORK
    6666uint64_t          tm_start;
    6767uint64_t          tm_end;
    6868tm_start = hal_get_cycles();
    69 printk("\n[DBG] %s : core[%x,%d] enter / process %x / cycle =  %d\n",
    70 __FUNCTION__, local_cxy, parent_thread_ptr->core->lid, parent_pid,
    71 (uint32_t)tm_start );
     69if( CONFIG_DEBUG_SYS_FORK < tm_start )
     70printk("\n[DBG] %s : thread %x enter / parent %x / cycle =  %d\n",
     71__FUNCTION__, parent_thread_ptr, parent_pid, (uint32_t)tm_start );
    7272#endif
    7373
     
    148148        thread_unblock( XPTR( target_cxy , child_thread_ptr ) , THREAD_BLOCKED_GLOBAL );
    149149
    150 #if CONFIG_SYSCALL_DEBUG
     150#if CONFIG_DEBUG_SYS_FORK
    151151tm_end = hal_get_cycles();
    152 printk("\n[DBG] %s : core[%x,%d] parent_process %x exit / cost = %d\n",
    153 __FUNCTION__, local_cxy, parent_thread_ptr->core->lid,  parent_pid,
    154 (uint32_t)(tm_end - tm_start) );
     152if( CONFIG_DEBUG_SYS_FORK < tm_end )
     153printk("\n[DBG] %s : parent_thread %x exit / cost = %d / cycle %d\n",
     154__FUNCTION__ , parent_thread_ptr, (uint32_t)(tm_end - tm_start), (uint32_t)tm_end );
    155155#endif
    156156
     
    160160    {
    161161
    162 #if CONFIG_SYSCALL_DEBUG
     162#if CONFIG_DEBUG_SYS_FORK
    163163tm_end = hal_get_cycles();
    164 printk("\n[DBG] %s : core[%x,%d] child process %x exit / cost =  %d\n",
    165 __FUNCTION__, local_cxy, parent_thread_ptr->core->lid, child_pid,
    166 (uint32_t)(tm_end - tm_start) );
     164if( CONFIG_DEBUG_SYS_FORK < tm_end )
     165printk("\n[DBG] %s : child_thread %x exit / cost = %d / cycle %d\n",
     166__FUNCTION__ , child_thread_ptr, (uint32_t)(tm_end - tm_start), (uint32_t)tm_end );
    167167#endif
    168168
  • trunk/kernel/syscalls/sys_kill.c

    r421 r433  
    3838{
    3939    uint32_t    save_sr;       // required to enable IRQs
    40     xptr_t      process_xp;    // extended pointer on target reference process
    41     cxy_t       process_cxy;   // target process cluster
    42     process_t * process_ptr;   // local pointer on target process
     40    xptr_t      owner_xp;      // extended pointer on target reference process
     41    cxy_t       owner_cxy;     // target process cluster
     42    process_t * owner_ptr;     // local pointer on target process
    4343    xptr_t      parent_xp;     // extended pointer on parent process
    4444    cxy_t       parent_cxy;    // parent process cluster
    4545    process_t * parent_ptr;    // local pointer on parent process
    4646    pid_t       ppid;          // parent process PID
     47    uint32_t    retval;        // return value for the switch
    4748
    4849    thread_t  * this    = CURRENT_THREAD;
    4950
    50 #if CONFIG_SYSCALL_DEBUG
     51#if CONFIG_DEBUG_SYS_KILL
    5152uint64_t    tm_start;
    5253uint64_t    tm_end;
    5354tm_start = hal_get_cycles();
    54 printk("\n[DBG] %s : core[%x,%d] enter / process %x / sig %d / cycle %d\n",
    55 __FUNCTION__ , local_cxy , this->core->lid , pid, sig_id, (uint32_t)tm_start );
     55if( CONFIG_DEBUG_SYS_KILL < tm_start )
     56printk("\n[DBG] %s : thread %x enter / process %x / sig %d / cycle %d\n",
     57__FUNCTION__ , this, pid, sig_id, (uint32_t)tm_start );
    5658#endif
    5759
    58     // get cluster and pointers on reference process
    59     process_xp  = cluster_get_reference_process_from_pid( pid );
    60     process_cxy = GET_CXY( process_xp );
    61     process_ptr = (process_t *)GET_PTR( process_xp );
     60    // get cluster and pointers on owner process
     61    owner_xp  = cluster_get_owner_process_from_pid( pid );
     62    owner_cxy = GET_CXY( owner_xp );
     63    owner_ptr = GET_PTR( owner_xp );
    6264
    6365    // check process existence
    64     if( process_xp == XPTR_NULL )
     66    if( owner_xp == XPTR_NULL )
    6567    {
    66         syscall_dmsg("\n[ERROR] in %s : process %x not found\n",
    67         __FUNCTION__ , pid );
     68
     69syscall_dmsg("\n[ERROR] in %s : process %x not found\n", __FUNCTION__ , pid );
     70
    6871        this->errno = EINVAL;
    6972        return -1;
     
    7174   
    7275    // get parent process PID
    73     parent_xp  = hal_remote_lwd( XPTR( process_cxy , &process_ptr->parent_xp ) );
     76    parent_xp  = hal_remote_lwd( XPTR( owner_cxy , &owner_ptr->parent_xp ) );
    7477    parent_cxy = GET_CXY( parent_xp );
    7578    parent_ptr = GET_PTR( parent_xp );
     
    7982    if( ppid < 2 )
    8083    {
    81         syscall_dmsg("\n[ERROR] in %s : process %x cannot be killed\n",
    82         __FUNCTION__ , pid );
    83                 this->errno = EINVAL;
    84         return -1;
    85     }
    8684
    87     // does nothing if sig_id == 0
    88     if( sig_id == 0 )  return 0;
    89    
    90     // check sig_id
    91     if( (sig_id != SIGSTOP) && (sig_id != SIGCONT) && (sig_id != SIGKILL) )
    92     {
    93         syscall_dmsg("\n[ERROR] in %s : illegal signal type for process %x\n",
    94         __FUNCTION__ , sig_id , pid );
     85syscall_dmsg("\n[ERROR] in %s : process %x cannot be killed\n", __FUNCTION__ , pid );
     86
    9587                this->errno = EINVAL;
    9688        return -1;
     
    10092    hal_enable_irq( &save_sr );
    10193
    102     // execute process_make_kill() function in owner cluster
    103     if( local_cxy == process_cxy )                            // owner cluster is local
     94    // analyse signal type
     95    // supported values are : 0, SIGSTOP, SIGCONT, SIGKILL
     96    switch( sig_id )
    10497    {
    105         process_make_kill( pid , sig_id );
     98        case 0 :
     99        {
     100            // does nothing
     101            retval = 0;
     102            break;
     103        }
     104        case SIGSTOP:     
     105        {
     106            // remove TXT ownership from target process
     107            process_txt_reset_ownership( owner_xp );
     108
     109            // block all threads in all clusters
     110            process_sigaction( owner_ptr , BLOCK_ALL_THREADS );
     111
     112            // atomically update reference process termination state
     113            hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) ,
     114                                  PROCESS_FLAG_BLOCK );
     115 
     116            retval = 0;
     117            break;
     118        }
     119        case SIGCONT:
     120        {
     121            // unblock all threads in all clusters
     122            process_sigaction( owner_ptr , UNBLOCK_ALL_THREADS );
     123
     124            // atomically update reference process termination state
     125            hal_remote_atomic_and( XPTR( owner_cxy , &owner_ptr->term_state ) ,
     126                                   ~PROCESS_FLAG_BLOCK );
     127            retval = 0;
     128            break;
     129        }
     130        break;
     131        case SIGKILL:
     132        {
     133            // the process_make_kill() function must be executed
     134            // by an RPC thread in process owner cluster
     135            // It deletes all target process threads in all clusters,
     136            // and updates the process termination state
     137            rpc_process_make_kill_client( owner_cxy , owner_ptr , false , 0 );
     138
     139            retval = 0;
     140            break;
     141        }
     142        default:
     143        {
     144
     145syscall_dmsg("\n[ERROR] in %s : illegal signal type %d for process %x\n",
     146__FUNCTION__ , sig_id , pid );
     147
     148            this->errno = EINVAL;
     149            retval = -1;
     150            break;
     151        }
    106152    }
    107     else                                                      // owner cluster is remote
    108     {
    109         rpc_process_make_kill_client( process_cxy , pid , sig_id );
    110     }
    111 
     153   
    112154    // restore IRQs
    113155    hal_restore_irq( save_sr );
     
    115157    hal_fence();
    116158
    117 #if CONFIG_SYSCALL_DEBUG
     159#if CONFIG_DEBUG_SYS_KILL
    118160tm_end = hal_get_cycles();
    119 printk("\n[DBG] %s : core[%x,%d] exit / process %x / sig %d / cost = %d\n",
    120 __FUNCTION__ , local_cxy , this->core->lid , pid, sig_id, (uint32_t)(tm_end - tm_start) );
     161if( CONFIG_DEBUG_SYS_KILL < tm_end )
     162printk("\n[DBG] %s : thread %x enter / process %x / sig %d / cost = %d / cycle %d\n",
     163__FUNCTION__ , this, pid, sig_id, (uint32_t)(tm_end - tm_start), (uint32_t)tm_end );
    121164#endif
    122  
    123         return 0;
     165
     166        return retval;
    124167
    125168}  // end sys_kill()
  • trunk/kernel/syscalls/sys_read.c

    r421 r433  
    6565
    6666#if CONFIG_READ_DEBUG
     67enter_sys_read = (uint32_t)tm_start;
     68#endif
     69
     70        thread_t  *  this    = CURRENT_THREAD;
     71        process_t *  process = this->process;
     72 
     73#if CONFIG_DEBUG_SYS_READ
    6774uint64_t     tm_start;
    6875uint64_t     tm_end;
    6976tm_start = hal_get_cycles();
    70 #endif
    71 
    72 #if CONFIG_READ_DEBUG
    73 enter_sys_read = (uint32_t)tm_start;
    74 #endif
    75 
    76         thread_t  *  this    = CURRENT_THREAD;
    77         process_t *  process = this->process;
    78  
     77if( CONFIG_DEBUG_SYS_READ < tm_start )
     78printk("\n[DBG] %s : thread %d enter / process %x / vaddr = %x / count %d / cycle %d\n",
     79__FUNCTION__, this, process->pid, vaddr, count, (uint32_t)tm_start );
     80#endif
     81
    7982    // check file_id argument
    8083        if( file_id >= CONFIG_PROCESS_FILE_MAX_NR )
     
    188191    hal_fence();
    189192
    190 #if CONFIG_READ_DEBUG
     193#if CONFIG_DEBUG_SYS_READ
    191194tm_end = hal_get_cycles();
    192 printk("\n[DBG] %s : core[%x,%d] / thread %x in process %x / cycle %d\n"
     195if( CONFIG_DEBUG_SYS_READ < tm_end )
     196printk("\n[DBG] %s : thread %x / process %x / cycle %d\n"
    193197"nbytes = %d / first byte = %c / file_id = %d / cost = %d\n",
    194198__FUNCTION__ , local_cxy , this->core->lid , this->trdid , this->process->pid ,
  • trunk/kernel/syscalls/sys_thread_exit.c

    r409 r433  
    8787            thread_block( this , THREAD_BLOCKED_JOIN );
    8888
    89             // release the lock protecting the flags
     89            // release the lock protecting the join
    9090                remote_spinlock_unlock( XPTR( local_cxy, &this->join_lock ) );
    9191
  • trunk/kernel/syscalls/sys_wait.c

    r421 r433  
    4141    pid_t       child_pid;
    4242    int         child_state;
     43    thread_t  * child_thread;
    4344
    4445    thread_t  * this    = CURRENT_THREAD;
    4546    process_t * process = this->process;
     47    pid_t       pid     = process->pid;
    4648
    47 #if CONFIG_SYSCALL_DEBUG
     49#if CONFIG_DEBUG_SYS_WAIT
    4850uint64_t    tm_start;
    4951uint64_t    tm_end;
    5052tm_start = hal_get_cycles();
    51 printk("\n[DBG] %s : core[%x,%d] enter / process %x / cycle %d\n",
    52 __FUNCTION__ , local_cxy , this->core->lid , process->pid, (uint32_t)tm_start );
     53if( CONFIG_DEBUG_SYS_WAIT < tm_start )
     54printk("\n[DBG] %s : thread %x enter / process %x / cycle %d\n",
     55__FUNCTION__, this, process->pid, (uint32_t)tm_start );
    5356#endif
    5457
     
    6467        }
    6568
    66     // get cluster and local pointer on reference process
    67     xptr_t      ref_xp  = process->ref_xp;
    68     cxy_t       ref_cxy = GET_CXY( ref_xp );
    69     process_t * ref_ptr = GET_PTR( ref_xp );
     69    // get process owner cluster
     70    cxy_t owner_cxy = CXY_FROM_PID( pid );
    7071
    71     // get extended pointer on children list root
    72     xptr_t root_xp = XPTR( ref_cxy , &ref_ptr->children_root );
     72    // This function must be executed in owner cluster
     73    assert( (owner_cxy == local_cxy) , __FUNCTION__ ,
     74    "calling thread must execute in owner cluster" );
    7375
    74     // get extended pointer on lock protecting the children list
    75     xptr_t lock_xp = XPTR( ref_cxy , &ref_ptr->children_lock );
     76    // This function must be executed by the main thread
     77    assert( (process->th_tbl[0] == this) , __FUNCTION__ ,
     78    "this function must be executed by the main thread" );
     79   
     80    // get extended pointer on children list root and lock
     81    xptr_t children_root_xp = XPTR( owner_cxy , &process->children_root );
     82    xptr_t children_lock_xp = XPTR( owner_cxy , &process->children_lock );
    7683
    7784    // exit this blocking loop only when a child processes change state
    7885    while( 1 )
    7986    {
    80         // get lock
    81         remote_spinlock_lock( lock_xp );
     87        // get lock protecting children list
     88        remote_spinlock_lock( children_lock_xp );
    8289
    83         // scan the list of child process
    84         XLIST_FOREACH( root_xp , iter_xp )
     90        // scan the list of owner child process
     91        XLIST_FOREACH( children_root_xp , iter_xp )
    8592        {
    86             // get child process cluster and local pointer
     93            // get child process owner cluster and local pointer
    8794            child_xp  = XLIST_ELEMENT( iter_xp , process_t , children_list );
    8895            child_ptr = GET_PTR( child_xp );
    8996            child_cxy = GET_CXY( child_xp );
    9097
    91             // get the child PID
    92             child_pid = (int)hal_remote_lw( XPTR( child_cxy , &child_ptr->pid ) );
     98            // get term_state from child owner process
     99            child_state = (int)hal_remote_lw ( XPTR(child_cxy,&child_ptr->term_state));
    93100
    94             // get the child process state
    95             child_state = hal_remote_lw( XPTR( child_cxy , &child_ptr->state ) );
     101            // test if child process is terminated,
     102            // but termination not yet reported to parent process
     103            if( ((child_state & PROCESS_FLAG_EXIT)   ||
     104                 (child_state & PROCESS_FLAG_KILL)   ||
     105                 (child_state & PROCESS_FLAG_BLOCK)) &&
     106                 ((child_state & PROCESS_FLAG_WAIT) == 0) )
     107            {
     108                // get pointer on main thread and PID from child owner process
     109                child_pid    = (pid_t)     hal_remote_lw ( XPTR(child_cxy,&child_ptr->pid));
     110                child_thread = (thread_t *)hal_remote_lpt( XPTR(child_cxy,&child_ptr->th_tbl[0]));
    96111
    97             // check child process state
    98             if( child_state != PROCESS_STATE_RUNNING )
    99             {
    100                 // release lock
    101                 remote_spinlock_unlock( lock_xp );
     112                // set the PROCESS_FLAG_WAIT in owner child descriptor
     113                hal_remote_atomic_or( XPTR( child_cxy , &child_ptr->term_state ),
     114                                      PROCESS_FLAG_WAIT );
    102115
    103 #if CONFIG_SYSCALL_DEBUG
     116                // set the THREAD_FLAG_REQ_DELETE in child main thread
     117                hal_remote_atomic_or( XPTR( child_cxy , &child_thread->flags ) ,
     118                                            THREAD_FLAG_REQ_DELETE );
     119
     120#if CONFIG_DEBUG_SYS_WAIT
    104121tm_end = hal_get_cycles();
    105 printk("\n[DBG] %s : core[%x,%d] exit / process %x / cost = %d\n",
    106 __FUNCTION__ , local_cxy, this->core->lid, process->pid, (uint32_t)(tm_end - tm_start) );
     122if( CONFIG_DEBUG_SYS_WAIT < tm_end )
     123printk("\n[DBG] %s : thread %x exit / process %x / cycle %d\n",
     124__FUNCTION__, this, process->pid, (uint32_t)tm_end );
    107125#endif
    108126
    109                 // return relevant info to process
    110                 hal_copy_to_uspace( status , &child_state , sizeof(int) );
    111                 return child_pid;
     127                 // return relevant info to calling parent process
     128                 hal_copy_to_uspace( status , &child_state , sizeof(int) );
     129                 return child_pid;
    112130            }
    113131        }
    114132       
    115133        // release lock
    116         remote_spinlock_unlock( lock_xp );
     134        remote_spinlock_unlock( children_lock_xp );
    117135
    118         // block the calling thread until a child process change state
    119         thread_block( this , THREAD_BLOCKED_WAIT );
    120         sched_yield( "wait child termination" );
     136        // deschedule without blocking
     137        sched_yield( "parent wait children termination" );
    121138    }
    122139
  • trunk/kernel/syscalls/sys_write.c

    r421 r433  
    4646    reg_t        save_sr;         // required to enable IRQs during syscall
    4747
    48 #if CONFIG_WRITE_DEBUG
     48        thread_t   * this = CURRENT_THREAD;
     49        process_t  * process = this->process;
     50
     51#if CONFIG_DEBUG_SYS_WRITE
    4952uint32_t     tm_start;
    5053uint32_t     tm_end;
    5154tm_start = hal_get_cycles();
     55if( CONFIG_DEBUG_SYS_WRITE < tm_start )
     56printk("\n[DBG] %s : thread %x / process %x / vaddr %x / count %d / cycle %d\n",
     57__FUNCTION__, this, process->pid, vaddr, count, (uint32_t)tm_start );
    5258#endif
    53 
    54         thread_t   * this = CURRENT_THREAD;
    55         process_t  * process = this->process;
    5659 
    5760    // check file_id argument
    5861        if( file_id >= CONFIG_PROCESS_FILE_MAX_NR )
    5962        {
    60         printk("\n[ERROR] in %s : illegal file descriptor index\n", __FUNCTION__ );
     63
     64#if CONFIG_DEBUG_SYSCALLS_ERROR
     65printk("\n[ERROR] in %s : illegal file descriptor index\n", __FUNCTION__ );
     66#endif
    6167        this->errno = EBADFD;
    6268                return -1;
     
    6874    if ( error )
    6975    {
    70         printk("\n[ERROR] in %s : user buffer unmapped = %x\n",
    71         __FUNCTION__ , (intptr_t)vaddr );
     76
     77#if CONFIG_DEBUG_SYSCALLS_ERROR
     78printk("\n[ERROR] in %s : user buffer unmapped = %x\n", __FUNCTION__ , (intptr_t)vaddr );
     79#endif
    7280                this->errno = EINVAL;
    7381                return -1;
     
    8290    if( file_xp == XPTR_NULL )
    8391    {
    84         printk("\n[ERROR] in %s : undefined file descriptor index = %d in process %x\n",
    85         __FUNCTION__ , file_id , process->pid );
     92
     93#if CONFIG_DEBUG_SYSCALLS_ERROR
     94printk("\n[ERROR] in %s : undefined file descriptor index = %d in process %x\n",
     95__FUNCTION__ , file_id , process->pid );
     96#endif
    8697                this->errno = EBADFD;
    8798                return -1;
     
    103114        if( (attr & FD_ATTR_WRITE_ENABLE) == 0 )
    104115            {
    105             printk("\n[ERROR] in %s : file %d not writable in process %x\n",
    106             __FUNCTION__ , file_id , process->pid );
     116
     117#if CONFIG_DEBUG_SYSCALLS_ERROR
     118printk("\n[ERROR] in %s : file %d not writable in process %x\n",
     119__FUNCTION__ , file_id , process->pid );
     120#endif
    107121                    this->errno = EBADFD;
    108122                    return -1;
     
    131145    if( nbytes != count )
    132146    {
    133         printk("\n[ERROR] in %s cannot write data to file %d in process %x\n",
    134         __FUNCTION__ , file_id , process->pid );
     147
     148#if CONFIG_DEBUG_SYSCALLS_ERROR
     149printk("\n[ERROR] in %s cannot write data to file %d in process %x\n",
     150__FUNCTION__ , file_id , process->pid );
     151#endif
    135152        this->errno = error;
    136153        return -1;
     
    142159    hal_fence();
    143160
    144 #if CONFIG_WRITE_DEBUG
     161#if CONFIG_DEBUG_SYS_WRITE
    145162tm_end = hal_get_cycles();
    146 printk("\n[DBG] %s : core[%x,%d] / thread %x in process %x / cycle %d\n"
     163if( CONFIG_DEBUG_SYS_WRITE < tm_end )
     164printk("\n[DBG] %s : thread %x in process %x / cycle %d\n"
    147165"nbytes = %d / first byte = %c / file_id = %d / cost = %d\n",
    148 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , this->process->pid ,
    149 (uint32_t)tm_start , nbytes , *((char *)(intptr_t)paddr) , file_id ,
    150 (uint32_t)(tm_end - tm_start) );
     166__FUNCTION__, this, process->pid, (uint32_t)tm_start,
     167nbytes, *((char *)(intptr_t)paddr) , file_id , (uint32_t)(tm_end - tm_start) );
    151168#endif
    152169 
    153 #if (CONFIG_WRITE_DEBUG & 0x1)
    154 printk("\n@@@@@@@@@@@@ timing to write character %c\n"
    155 " - enter_sys_write    = %d\n"
    156 " - exit_sys_write     = %d\n",
    157 *((char *)(intptr_t)paddr) , (uint32_t)tm_start , (uint32_t)tm_end );
    158 #endif
    159 
    160170        return nbytes;
    161171
  • trunk/kernel/syscalls/syscalls.h

    r421 r433  
    171171/******************************************************************************************
    172172 * [10] This function implement the exit system call terminating a POSIX process.
     173 * In the present implementation, this function implements actually the _exit():
     174 * - it does not flush open ourput steams.
     175 * - it does not close open streams.
    173176 ******************************************************************************************
    174177 * @ status   : terminaison status (not used in present implementation).
     
    421424
    422425/******************************************************************************************
    423  * [34] This function implements the "kill" system call.
     426 * [34] This function implements the "kill" system call on the kernel side.
    424427 * It register the signal defined by the <sig_id> argument in all thread descriptors
    425428 * of a target process identified by the <pid> argument. This is done in all clusters
     
    432435 ******************************************************************************************
    433436 * @ pid      : target process identifier.
    434  * @ sig_id   : index defining the signal type (from 1 to 31).
     437 * @ sig_id   : index defining the signal type.
    435438 * @ return 0 if success / returns -1 if failure.
    436439 *****************************************************************************************/
     
    439442
    440443/******************************************************************************************
    441  * [35] This function implements the "getpid" system call.
     444 * [35] This function implements the "getpid" system call on the kernel side.
    442445 ******************************************************************************************
    443446 * @ returns the process PID for the calling thread.
     
    446449
    447450/******************************************************************************************
    448  * [36] This function implement the "fork" system call.
    449  * The calling process descriptor (parent process), and the associated thread descriptor are
    450  * replicated in the same cluster as the calling thread, but the new process (child process)
    451  * is registered in another target cluster, that is the new process owner.
    452  * The child process and the associated main thread will be migrated to the target cluster
    453  * later, when the child process makes an "exec" or any other system call... TODO [AG]
     451 * [36] This function implement the "fork" system call on the kernel side.
     452 * The calling process descriptor (parent process), and the associated thread descriptor
     453 * are replicated in a - likely - remote cluster, that becomes the child process owner.
     454 * The child process get a new PID, and is linked to the parent PID. The child process
     455 * inherit from its parent the memory image, and all open files (including the TXT).
     456 * The child process becomes the TXT terminal owner.
    454457 * The target cluster depends on the "fork_user" flag and "fork_cxy" variable that can be
    455458 * stored in the calling thread descriptor by the specific fork_place() system call.
    456  * If not, the sys_fork() function makes a query to the DQDT to select the target cluster.
     459 * If not, the kernel function makes a query to the DQDT to select the target cluster.
    457460 ******************************************************************************************
    458461 * @ if success, returns child process PID to parent, and return O to child.
     
    462465
    463466/******************************************************************************************
    464  * [37] This function implement the "exec" system call, that creates a new process
    465  * descriptor.
    466  * It is executed in the client cluster, but the new process descriptor and the main
    467  * thread are created in a server cluster, that is generally another cluster.
    468  * - if the server_cluster is the client cluster, it calls directly the process_make_exec()
    469  *   function to create a new process, and launch a new thread in local cluster.
    470  * - if the target_cluster is remote, it calls the rpc_process_exec_client() to execute
    471  *   process_signedmake_exec() on the remote cluster.
    472  * In both case this function build an exec_info_t structure containing all informations
    473  * required to build the new process descriptor and the associated thread.
    474  * Finally, the calling process and thread are deleted.
     467 * [37] This function implement the "exec" system call on the kernel side.
     468 * It creates, in the same cluster as the calling thread, a new process descriptor,
     469 * and a new associated main thread descriptor, executing a new memory image defined
     470 * by the <filename> argument. This new process inherit from the old process the PID
     471 * and the PPID, as well as all open files (including the TXT).
     472 * The old process descriptor, and all its threads are blocked, and marked for deletion.
     473 * Therefore the exec syscall does not return to the calling thread in case of success.
     474 * This function build an exec_info_t structure containing the new process arguments,
     475 * as defined by the <arv> argument, and the new process environment variables,
     476 * as defined by the <envp>  argument.
     477 * TODO : the <argv> and <envp> arguments are not supported yet (both must be NULL).
    475478 ******************************************************************************************
    476479 * @ filename : string pointer on .elf filename (pointer in user space)
    477480 * @ argv     : array of strings on process arguments (pointers in user space)
    478481 * @ envp     : array of strings on environment variables (pointers in user space)
    479  * @ returns O if success / returns -1 if failure.
     482 * @ does not return if success / returns -1 if failure.
    480483 *****************************************************************************************/
    481484int sys_exec( char  * filename,
     
    495498
    496499/******************************************************************************************
    497  * [39] This blocking function wait a change of a child process state. A change can be:
    498  * - a termination of child following a child exit.
    499  * - a termination of child following a SIGKILL signal.
     500 * [39] This blocking function waits a change of a child process state, that can be:
     501 * - a termination of child following a process_make_exit().
     502 * - a termination of child following a process_make_kill().
    500503 * - a blocking of child following a SIGSTOP signal.
    501  * It returns the PID of the involved child process, after storing in the memory slot
    502  * pointed by the <status> argument relevant information on the child state change.
     504 * In case of a multi-thread process, this function must be called by the main thread
     505 * runningin the reference cluster.
     506 * When a change has been observed, it returns the PID of the child process, and stores
     507 * in the <status> argument relevant information on the child state change.
    503508 * The following macros can be used to extract information from status:
    504509 * - WIFEXITED(status)   : is true if the child process terminated with an exit().
     
    506511 * - WIFSTOPPED(status)  : is true if the child process is stopped by a signal.
    507512 * - WEXITSTATUS(status) : returns the low-order 8 bits of the exit() argument.
    508  * A status of 0 indicates a normal termination.
    509513 * If a parent process terminates without waiting for all child processes to terminate,
    510514 * the remaining child processes are attached to the init process.
    511  ******************************************************************************************
    512  * @ status : pointer on the child PID status.
    513  * @ return child PID if success / return -1 if failure.
     515 * WARNING: negative values for the <pid> argument are not supported.
     516 ******************************************************************************************
     517 * @ searched_pid : searched child process identifier.
     518 * @ status       : [out] child termination status.
     519 * @ return child PID if success / return -1 if searched PID not found.
    514520 *****************************************************************************************/
    515521int sys_wait( uint32_t * status );
Note: See TracChangeset for help on using the changeset viewer.