Changeset 457 for trunk/kernel/kern


Ignore:
Timestamp:
Aug 2, 2018, 11:47:13 AM (6 years ago)
Author:
alain
Message:

This version modifies the exec syscall and fixes a large number of small bugs.
The version number has been updated (0.1)

Location:
trunk/kernel/kern
Files:
25 edited

Legend:

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

    r450 r457  
    2323
    2424#include <kernel_config.h>
    25 #include <hal_types.h>
     25#include <hal_kernel_types.h>
    2626#include <hal_special.h>
    2727#include <hal_remote.h>
     
    127127    xptr_t     server_xp;     // extended pointer on server thread
    128128    core_t   * core_ptr;      // local pointer on core running the server thread
    129     uint32_t   lid;           // core running the server thread local index
     129    uint32_t   server_lid;    // core running the server thread local index
    130130    xptr_t     lock_xp;       // extended pointer on lock protecting the chdev queue
    131     uint32_t   different;     // non zero if server thread core != client thread core
    132131    uint32_t   save_sr;       // for critical section
    133132
     
    154153
    155154    // get server core local index
    156     lid = hal_remote_lw( XPTR( chdev_cxy , &core_ptr->lid ) );
     155    server_lid = hal_remote_lw( XPTR( chdev_cxy , &core_ptr->lid ) );
    157156
    158157#if (DEBUG_CHDEV_CMD_RX || DEBUG_CHDEV_CMD_TX)
     
    210209#endif
    211210
     211#if (DEBUG_CHDEV_CMD_RX & 1)
     212if( (is_rx) && (DEBUG_CHDEV_CMD_RX < rx_cycle) )
     213printk("\n[DBG] in %s : client thread %x blocked\n", __FUNCTION__, this );
     214#endif
     215
    212216    // unblock server thread if required
    213217    if( hal_remote_lw( blocked_xp ) & THREAD_BLOCKED_IDLE )
     
    216220#if (DEBUG_CHDEV_CMD_TX & 1)
    217221if( (is_rx == 0) && (DEBUG_CHDEV_CMD_TX < tx_cycle) )
    218 {
    219 printk("\n[DBG] in %s : server thread %x unblocked\n", __FUNCTION__, server_ptr );
    220 chdev_queue_display( chdev_xp );
    221 }
     222printk("\n[DBG] in %s : TX server thread %x unblocked\n", __FUNCTION__, server_ptr );
     223#endif
     224
     225#if (DEBUG_CHDEV_CMD_RX & 1)
     226if( (is_rx) && (DEBUG_CHDEV_CMD_RX < rx_cycle) )
     227printk("\n[DBG] in %s : RX server thread %x unblocked\n", __FUNCTION__, server_ptr );
    222228#endif
    223229
     
    227233#if (DEBUG_CHDEV_CMD_TX & 1)
    228234if( (is_rx == 0)  && (DEBUG_CHDEV_CMD_TX < tx_cycle) )
    229 {
    230235printk("\n[DBG] in %s : thread %x registered write request in chdev\n", __FUNCTION__, this );
    231 chdev_queue_display( chdev_xp );
    232 }
     236#endif
     237 
     238#if (DEBUG_CHDEV_CMD_RX & 1)
     239if( (is_rx)  && (DEBUG_CHDEV_CMD_RX < rx_cycle) )
     240printk("\n[DBG] in %s : thread %x registered read request in chdev\n", __FUNCTION__, this );
    233241#endif
    234242 
    235243    // send IPI to core running the server thread when server != client
    236     different = (lid != this->core->lid) || (local_cxy != chdev_cxy);
    237     if( different )
    238     {
    239         dev_pic_send_ipi( chdev_cxy , lid );
    240    
     244    if( (server_lid != this->core->lid) || (local_cxy != chdev_cxy) )
     245    {
     246        dev_pic_send_ipi( chdev_cxy , server_lid );
     247
    241248#if (DEBUG_CHDEV_CMD_TX & 1)
    242249if( (is_rx == 0)  && (DEBUG_CHDEV_CMD_TX < tx_cycle) )
    243 printk("\n[DBG] in %s : client thread %x sent IPI to server thread %x\n",
     250printk("\n[DBG] in %s : client thread %x sent IPI to TX server thread %x\n",
     251__FUNCTION__, this, server_ptr );
     252#endif
     253
     254#if (DEBUG_CHDEV_CMD_RX & 1)
     255if( (is_rx)  && (DEBUG_CHDEV_CMD_RX < rx_cycle) )
     256printk("\n[DBG] in %s : client thread %x sent IPI to RX server thread %x\n",
    244257__FUNCTION__, this, server_ptr );
    245258#endif
  • trunk/kernel/kern/chdev.h

    r450 r457  
    2626
    2727#include <kernel_config.h>
    28 #include <hal_types.h>
     28#include <hal_kernel_types.h>
    2929#include <xlist.h>
    3030#include <remote_spinlock.h>
  • trunk/kernel/kern/cluster.c

    r456 r457  
    123123
    124124#if( DEBUG_CLUSTER_INIT & 1 )
    125 uint32_t cycle = (uint32_t)hal_get_cycles();
     125cycle = (uint32_t)hal_get_cycles();
    126126if( DEBUG_CLUSTER_INIT < cycle )
    127127printk("\n[DBG] %s : KHM initialized in cluster %x at cycle %d\n",
     
    133133
    134134#if( DEBUG_CLUSTER_INIT & 1 )
    135 uint32_t cycle = (uint32_t)hal_get_cycles();
     135cycle = (uint32_t)hal_get_cycles();
    136136if( DEBUG_CLUSTER_INIT < cycle )
    137137printk("\n[DBG] %s : KCM initialized in cluster %x at cycle %d\n",
  • trunk/kernel/kern/cluster.h

    r443 r457  
    2828
    2929#include <kernel_config.h>
    30 #include <hal_types.h>
     30#include <hal_kernel_types.h>
    3131#include <bits.h>
    3232#include <spinlock.h>
  • trunk/kernel/kern/core.c

    r443 r457  
    2424
    2525#include <kernel_config.h>
    26 #include <hal_types.h>
     26#include <hal_kernel_types.h>
    2727#include <hal_special.h>
    2828#include <errno.h>
  • trunk/kernel/kern/core.h

    r443 r457  
    2727
    2828#include <kernel_config.h>
    29 #include <hal_types.h>
     29#include <hal_kernel_types.h>
    3030#include <list.h>
    3131#include <rpc.h>
     
    6565}
    6666core_t;
    67 
    68 /****************************************************************************************
    69  * This macro returns a pointer on the calling core descriptor.
    70  ***************************************************************************************/
    71 
    72 #define CURRENT_CORE  (CURRENT_THREAD->core)
    7367
    7468/***************************************************************************************
  • trunk/kernel/kern/do_interrupt.c

    r248 r457  
    2222 */
    2323
    24 #include <hal_types.h>
     24#include <hal_kernel_types.h>
    2525#include <kernel_config.h>
    2626#include <thread.h>
  • trunk/kernel/kern/do_interrupt.h

    r16 r457  
    2727#define _DO_INTERRUPT_H_
    2828
    29 #include <hal_types.h>
     29#include <hal_kernel_types.h>
    3030#include <thread.h>
    3131
  • trunk/kernel/kern/do_syscall.c

    r443 r457  
    2222 */
    2323
    24 #include <hal_types.h>
     24#include <hal_kernel_types.h>
    2525#include <hal_irqmask.h>
    2626#include <do_syscall.h>
     
    102102    sys_trace,              // 47
    103103    sys_fg,                 // 48
    104     sys_undefined,          // 49
     104    sys_is_fg,              // 49
    105105};
    106106
     
    160160        else if( index == SYS_TRACE          ) return "TRACE";            // 47
    161161        else if( index == SYS_FG             ) return "FG";               // 48
     162        else if( index == SYS_IS_FG          ) return "IS_FG";            // 49
    162163
    163164    else                                   return "undefined";   
  • trunk/kernel/kern/do_syscall.h

    r408 r457  
    2727#define _D0_SYSCALL_H_
    2828
    29 #include <hal_types.h>
     29#include <hal_kernel_types.h>
    3030#include <thread.h>
    3131
  • trunk/kernel/kern/dqdt.c

    r438 r457  
    2323
    2424#include <kernel_config.h>
    25 #include <hal_types.h>
     25#include <hal_kernel_types.h>
    2626#include <hal_special.h>
    2727#include <hal_atomic.h>
  • trunk/kernel/kern/dqdt.h

    r438 r457  
    2626
    2727#include <kernel_config.h>
    28 #include <hal_types.h>
     28#include <hal_kernel_types.h>
    2929#include <hal_atomic.h>
    3030
  • trunk/kernel/kern/kernel_init.c

    r443 r457  
    2525#include <kernel_config.h>
    2626#include <errno.h>
    27 #include <hal_types.h>
     27#include <hal_kernel_types.h>
    2828#include <hal_special.h>
    2929#include <hal_context.h>
     
    186186           "    /_/        \\_\\ |______| |_|    |_|   \\_____/  |______/        |_|    |_|  |_|  \\_\\ |_|   |_|  \n"
    187187           "\n\n\t\t Advanced Locality Management Operating System / Multi Kernel Hybrid\n"
    188            "\n\n\t\t Version 0.0 / %d cluster(s) / %d core(s) per cluster / cycle %d\n\n",
    189            nclusters , ncores , hal_time_stamp() );
     188           "\n\n\t\t %s / %d cluster(s) / %d core(s) per cluster\n\n",
     189           CONFIG_ALMOS_VERSION , nclusters , ncores );
    190190}
    191191
     
    761761    reg_t        status;                    // running core status register
    762762
    763     cxy_t        io_cxy = info->io_cxy;
    764 
    765     assert( (io_cxy == ((info->x_size - 1)<<(info->y_width)) + (info->y_size - 1)) ,
    766     __FUNCTION__ , "illegal IO cluter identifier\n" );
    767 
    768763    /////////////////////////////////////////////////////////////////////////////////
    769764    // STEP 0 : Each core get its core identifier from boot_info, and makes
     
    796791    thread->remote_locks = 0;
    797792
    798     // CP0 in I/O cluster initialises TXT0 chdev descriptor
    799     if( (core_lid == 0) && (core_cxy == io_cxy) ) txt0_device_init( info );
    800 
    801     /////////////////////////////////////////////////////////////////////////////////
    802     if( core_lid == 0 ) remote_barrier( XPTR( io_cxy , &global_barrier ),
     793    // CP0 in cluster 0 initialises TXT0 chdev descriptor
     794    if( (core_lid == 0) && (core_cxy == 0) ) txt0_device_init( info );
     795
     796    /////////////////////////////////////////////////////////////////////////////////
     797    if( core_lid == 0 ) remote_barrier( XPTR( 0 , &global_barrier ),
    803798                                        (info->x_size * info->y_size) );
    804799    barrier_wait( &local_barrier , info->cores_nr );
     
    838833
    839834    /////////////////////////////////////////////////////////////////////////////////
    840     if( core_lid == 0 ) remote_barrier( XPTR( io_cxy , &global_barrier ),
     835    if( core_lid == 0 ) remote_barrier( XPTR( 0 , &global_barrier ),
    841836                                        (info->x_size * info->y_size) );
    842837    barrier_wait( &local_barrier , info->cores_nr );
     
    865860   
    866861    ////////////////////////////////////////////////////////////////////////////////
    867     if( core_lid == 0 ) remote_barrier( XPTR( io_cxy , &global_barrier ),
     862    if( core_lid == 0 ) remote_barrier( XPTR( 0 , &global_barrier ),
    868863                                        (info->x_size * info->y_size) );
    869864    barrier_wait( &local_barrier , info->cores_nr );
     
    898893
    899894    /////////////////////////////////////////////////////////////////////////////////
    900     if( core_lid == 0 ) remote_barrier( XPTR( io_cxy , &global_barrier ),
     895    if( core_lid == 0 ) remote_barrier( XPTR( 0 , &global_barrier ),
    901896                                        (info->x_size * info->y_size) );
    902897    barrier_wait( &local_barrier , info->cores_nr );
     
    926921
    927922    // all cores initialize the idle thread descriptor
    928     error = thread_idle_init( thread,
    929                               THREAD_IDLE,
    930                               &thread_idle_func,
    931                               NULL,
    932                               core_lid );
    933     if( error )
    934     {
    935         assert( false , __FUNCTION__ ,
    936         "core[%x][%d] cannot initialize idle thread", local_cxy , core_lid );
    937     }
     923    thread_idle_init( thread,
     924                      THREAD_IDLE,
     925                      &thread_idle_func,
     926                      NULL,
     927                      core_lid );
    938928
    939929    // all cores unblock idle thread, and register it in scheduler
     
    1008998
    1009999    /////////////////////////////////////////////////////////////////////////////////
    1010     if( core_lid == 0 ) remote_barrier( XPTR( io_cxy , &global_barrier ),
     1000    if( core_lid == 0 ) remote_barrier( XPTR( 0 , &global_barrier ),
    10111001                                        (info->x_size * info->y_size) );
    10121002    barrier_wait( &local_barrier , info->cores_nr );
     
    10691059
    10701060    /////////////////////////////////////////////////////////////////////////////////
    1071     if( core_lid == 0 ) remote_barrier( XPTR( io_cxy , &global_barrier ),
     1061    if( core_lid == 0 ) remote_barrier( XPTR( 0 , &global_barrier ),
    10721062                                        (info->x_size * info->y_size) );
    10731063    barrier_wait( &local_barrier , info->cores_nr );
     
    10761066#if DEBUG_KERNEL_INIT
    10771067if( (core_lid ==  0) & (local_cxy == 0) )
    1078 printk("\n[DBG] %s : exit barrier 5 : VFS_root = %l in cluster %x / cycle %d\n",
    1079 __FUNCTION__, vfs_root_inode_xp , io_cxy , (uint32_t)hal_get_cycles());
     1068printk("\n[DBG] %s : exit barrier 5 : VFS_root = %l in cluster 0 / cycle %d\n",
     1069__FUNCTION__, vfs_root_inode_xp , (uint32_t)hal_get_cycles());
    10801070#endif
    10811071
     
    10861076    /////////////////////////////////////////////////////////////////////////////////
    10871077
    1088     if( (core_lid ==  0) && (local_cxy == io_cxy) )
     1078    if( (core_lid ==  0) && (local_cxy == 0) )
    10891079    {
    10901080        // create "dev" and "external" directories.
     
    11041094
    11051095    /////////////////////////////////////////////////////////////////////////////////
    1106     if( core_lid == 0 ) remote_barrier( XPTR( io_cxy , &global_barrier ),
     1096    if( core_lid == 0 ) remote_barrier( XPTR( 0 , &global_barrier ),
    11071097                                        (info->x_size * info->y_size) );
    11081098    barrier_wait( &local_barrier , info->cores_nr );
     
    11111101#if DEBUG_KERNEL_INIT
    11121102if( (core_lid ==  0) & (local_cxy == 0) )
    1113 printk("\n[DBG] %s : exit barrier 6 : dev_root = %l in cluster %x / cycle %d\n",
    1114 __FUNCTION__, devfs_dev_inode_xp , io_cxy , (uint32_t)hal_get_cycles() );
     1103printk("\n[DBG] %s : exit barrier 6 : dev_root = %l in cluster 0 / cycle %d\n",
     1104__FUNCTION__, devfs_dev_inode_xp , (uint32_t)hal_get_cycles() );
    11151105#endif
    11161106
     
    11251115    if( core_lid == 0 )
    11261116    {
    1127         // get extended pointer on "extend" field of VFS context for DEVFS in cluster IO
    1128         xptr_t  extend_xp = XPTR( io_cxy , &fs_context[FS_TYPE_DEVFS].extend );
    1129 
    1130         // get pointer on DEVFS context in cluster IO
     1117        // get extended pointer on "extend" field of VFS context for DEVFS in cluster 0
     1118        xptr_t  extend_xp = XPTR( 0 , &fs_context[FS_TYPE_DEVFS].extend );
     1119
     1120        // get pointer on DEVFS context in cluster 0
    11311121        devfs_ctx_t * devfs_ctx = hal_remote_lpt( extend_xp );
    11321122       
    1133         devfs_dev_inode_xp      = hal_remote_lwd( XPTR( io_cxy ,
    1134                                                         &devfs_ctx->dev_inode_xp ) );
    1135         devfs_external_inode_xp = hal_remote_lwd( XPTR( io_cxy ,
    1136                                                         &devfs_ctx->external_inode_xp ) );
     1123        devfs_dev_inode_xp      = hal_remote_lwd( XPTR( 0 , &devfs_ctx->dev_inode_xp ) );
     1124        devfs_external_inode_xp = hal_remote_lwd( XPTR( 0 , &devfs_ctx->external_inode_xp ) );
    11371125
    11381126        // populate DEVFS in all clusters
     
    11431131
    11441132    /////////////////////////////////////////////////////////////////////////////////
    1145     if( core_lid == 0 ) remote_barrier( XPTR( io_cxy , &global_barrier ),
     1133    if( core_lid == 0 ) remote_barrier( XPTR( 0 , &global_barrier ),
    11461134                                        (info->x_size * info->y_size) );
    11471135    barrier_wait( &local_barrier , info->cores_nr );
     
    11581146    /////////////////////////////////////////////////////////////////////////////////
    11591147
    1160     if( (core_lid ==  0) && (local_cxy == 0) )
     1148    if( (core_lid == 0) && (local_cxy == 0) )
    11611149    {
    11621150
     
    11691157
    11701158    /////////////////////////////////////////////////////////////////////////////////
    1171     if( core_lid == 0 ) remote_barrier( XPTR( io_cxy , &global_barrier ),
     1159    if( core_lid == 0 ) remote_barrier( XPTR( 0 , &global_barrier ),
    11721160                                        (info->x_size * info->y_size) );
    11731161    barrier_wait( &local_barrier , info->cores_nr );
     
    11891177    /////////////////////////////////////////////////////////////////////////////////
    11901178   
    1191     if( (core_lid ==  0) && (local_cxy == io_cxy) )
     1179    if( (core_lid == 0) && (local_cxy == 0) )
    11921180    {
    11931181        print_banner( (info->x_size * info->y_size) , info->cores_nr );
  • trunk/kernel/kern/printk.c

    r446 r457  
    2222 */
    2323
    24 #include <hal_types.h>
     24#include <hal_kernel_types.h>
    2525#include <hal_irqmask.h>
    2626#include <hal_special.h>
  • trunk/kernel/kern/printk.h

    r437 r457  
    4141#define _PRINTK_H
    4242
    43 #include <hal_types.h>
     43#include <hal_kernel_types.h>
    4444#include <stdarg.h>
    4545
  • trunk/kernel/kern/process.c

    r450 r457  
    2525
    2626#include <kernel_config.h>
    27 #include <hal_types.h>
     27#include <hal_kernel_types.h>
    2828#include <hal_remote.h>
    2929#include <hal_uspace.h>
     
    8989void process_reference_init( process_t * process,
    9090                             pid_t       pid,
    91                              xptr_t      parent_xp,
    92                              xptr_t      model_xp )
     91                             xptr_t      parent_xp )
    9392{
    9493    cxy_t       parent_cxy;
    9594    process_t * parent_ptr;
    96     cxy_t       model_cxy;
    97     process_t * model_ptr;
    9895    xptr_t      stdin_xp;
    9996    xptr_t      stdout_xp;
     
    110107    chdev_t *   chdev_ptr;
    111108    cxy_t       chdev_cxy;
    112     pid_t       model_pid;
    113109    pid_t       parent_pid;
    114 
    115     // get model process cluster and local pointer
    116     model_cxy = GET_CXY( model_xp );
    117     model_ptr = GET_PTR( model_xp );
    118110
    119111    // get parent process cluster and local pointer
     
    121113    parent_ptr = GET_PTR( parent_xp );
    122114
    123     // get model_pid and parent_pid
     115    // get parent_pid
    124116    parent_pid = hal_remote_lw( XPTR( parent_cxy , &parent_ptr->pid ) );
    125     model_pid  = hal_remote_lw( XPTR( model_cxy  , &model_ptr->pid ) );
    126117
    127118#if DEBUG_PROCESS_REFERENCE_INIT
    128119uint32_t cycle = (uint32_t)hal_get_cycles();
    129120if( DEBUG_PROCESS_REFERENCE_INIT )
    130 printk("\n[DBG] %s : thread %x enter / pid = %x / ppid = %x / model_pid = %x / cycle %d\n",
    131 __FUNCTION__ , CURRENT_THREAD , pid , parent_pid , model_pid , cycle );
     121printk("\n[DBG] %s : thread %x in process %x enter to initalialize process %x / cycle %d\n",
     122__FUNCTION__, CURRENT_THREAD->trdid, parent_pid , pid , cycle );
    132123#endif
    133124
     
    146137cycle = (uint32_t)hal_get_cycles();
    147138if( DEBUG_PROCESS_REFERENCE_INIT )
    148 printk("\n[DBG] %s : thread %x / vmm empty for process %x / cycle %d\n",
    149 __FUNCTION__ , CURRENT_THREAD , pid , cycle );
     139printk("\n[DBG] %s : thread %x in process %x / vmm empty for process %x / cycle %d\n",
     140__FUNCTION__, CURRENT_THREAD->trdid, parent_pid , cycle );
    150141#endif
    151142
     
    154145
    155146    // define the stdin/stdout/stderr pseudo files <=> select a TXT terminal.
    156     // - if INIT (pid == 1)         => link to kernel TXT[0]
    157     // - if KSH[i] (model_pid == 1) => allocate a free TXT[i]
    158     // - if USER process            => same terminal as model
    159 
    160     if( (pid == 1) || (model_pid == 1)) // INIT or KSH process
    161     {
    162         if (pid == 1 )  txt_id = 0;                    // INIT
    163         else            txt_id = process_txt_alloc();  // KSH[i]
    164 
    165         // attach process to TXT[txt_id]
     147    if( (pid == 1) || (parent_pid == 1)) // INIT or KSH process
     148    {
     149        // allocate a TXT channel
     150        if( pid == 1 )  txt_id = 0;                     // INIT
     151        else            txt_id = process_txt_alloc();   // KSH
     152
     153        // attach process to TXT
    166154        process_txt_attach( process , txt_id );
     155
     156#if (DEBUG_PROCESS_REFERENCE_INIT & 1)
     157cycle = (uint32_t)hal_get_cycles();
     158if( DEBUG_PROCESS_REFERENCE_INIT )
     159printk("\n[DBG] %s : thread %x in process %x / process %x attached to TXT%d / cycle %d\n",
     160__FUNCTION__, CURRENT_THREAD->trdid, parent_pid, pid, txt_id, cycle );
     161#endif
     162
     163
    167164
    168165        // build path to TXT_RX[i] and TXT_TX[i] chdevs
     
    184181cycle = (uint32_t)hal_get_cycles();
    185182if( DEBUG_PROCESS_REFERENCE_INIT )
    186 printk("\n[DBG] %s : thread %x / stdin open for process %x / cycle %d\n",
    187 __FUNCTION__ , CURRENT_THREAD , pid , cycle );
     183printk("\n[DBG] %s : thread %x in process %x / stdin open for process %x / cycle %d\n",
     184__FUNCTION__, CURRENT_THREAD->trdid, parent_pid, pid, cycle );
    188185#endif
    189186
     
    202199cycle = (uint32_t)hal_get_cycles();
    203200if( DEBUG_PROCESS_REFERENCE_INIT )
    204 printk("\n[DBG] %s : thread %x / stdout open for process %x / cycle %d\n",
    205 __FUNCTION__ , CURRENT_THREAD , pid , cycle );
     201printk("\n[DBG] %s : thread %x in process %x / stdout open for process %x / cycle %d\n",
     202__FUNCTION__, CURRENT_THREAD->trdid, parent_pid, pid, cycle );
    206203#endif
    207204
     
    220217cycle = (uint32_t)hal_get_cycles();
    221218if( DEBUG_PROCESS_REFERENCE_INIT )
    222 printk("\n[DBG] %s : thread %x / stderr open for process %x / cycle %d\n",
    223 __FUNCTION__ , CURRENT_THREAD , pid , cycle );
     219printk("\n[DBG] %s : thread %x in process %x / stderr open for process %x / cycle %d\n",
     220__FUNCTION__, CURRENT_THREAD->trdid, parent_pid, pid, cycle );
    224221#endif
    225222
     
    227224    else                                            // normal user process
    228225    {
    229         // get extended pointer on stdin pseudo file in model process
    230         file_xp = (xptr_t)hal_remote_lwd( XPTR( model_cxy , &model_ptr->fd_array.array[0] ) );
    231 
    232         // get extended pointer on model process TXT chdev
     226        // get extended pointer on stdin pseudo file in parent process
     227        file_xp = (xptr_t)hal_remote_lwd( XPTR( parent_cxy , &parent_ptr->fd_array.array[0] ) );
     228
     229        // get extended pointer on parent process TXT chdev
    233230        chdev_xp = chdev_from_file( file_xp );
    234231 
     
    243240        process_txt_attach( process , txt_id );
    244241
    245         // copy all open files from model process fd_array to this process
     242        // copy all open files from parent process fd_array to this process
    246243        process_fd_remote_copy( XPTR( local_cxy , &process->fd_array ),
    247                                 XPTR( model_cxy , &model_ptr->fd_array ) );
     244                                XPTR( parent_cxy , &parent_ptr->fd_array ) );
    248245    }
    249246
    250247    // initialize specific inodes root and cwd
    251     process->vfs_root_xp = (xptr_t)hal_remote_lwd( XPTR( model_cxy,
    252                                                          &model_ptr->vfs_root_xp ) );
    253     process->vfs_cwd_xp  = (xptr_t)hal_remote_lwd( XPTR( model_cxy,
    254                                                          &model_ptr->vfs_cwd_xp ) );
     248    process->vfs_root_xp = (xptr_t)hal_remote_lwd( XPTR( parent_cxy,
     249                                                         &parent_ptr->vfs_root_xp ) );
     250    process->vfs_cwd_xp  = (xptr_t)hal_remote_lwd( XPTR( parent_cxy,
     251                                                         &parent_ptr->vfs_cwd_xp ) );
    255252    vfs_inode_remote_up( process->vfs_root_xp );
    256253    vfs_inode_remote_up( process->vfs_cwd_xp );
     
    469466////////////////////////////////////////
    470467void process_sigaction( pid_t       pid,
    471                         uint32_t    action_type )
     468                        uint32_t    type )
    472469{
    473470    cxy_t              owner_cxy;         // owner cluster identifier
     
    479476    xptr_t             process_xp;        // extended pointer on process copy
    480477    cxy_t              process_cxy;       // process copy cluster identifier
     478    process_t        * process_ptr;       // local pointer on process copy
    481479    reg_t              save_sr;           // for critical section
    482480    rpc_desc_t         rpc;               // shared RPC descriptor
    483 
    484     thread_t * client = CURRENT_THREAD;
     481    thread_t         * client;            // pointer on client thread
     482    xptr_t             client_xp;         // extended pointer on client thread
     483    process_t        * local;             // pointer on process copy in local cluster
     484    uint32_t           remote_nr;         // number of remote process copies
     485
     486    client    = CURRENT_THREAD;
     487    client_xp = XPTR( local_cxy , client );
     488    local     = NULL;
     489    remote_nr = 0;
    485490
    486491#if DEBUG_PROCESS_SIGACTION
    487492uint32_t cycle = (uint32_t)hal_get_cycles();
    488493if( DEBUG_PROCESS_SIGACTION < cycle )
    489 printk("\n[DBG] %s : thread %x enter to %s process %x / cycle %d\n",
    490 __FUNCTION__ , client, process_action_str( action_type ) , pid , cycle );
     494printk("\n[DBG] %s : thread %x in process %x enter to %s process %x / cycle %d\n",
     495__FUNCTION__ , client->trdid, client->process->pid,
     496process_action_str( type ) , pid , cycle );
    491497#endif
    492498
     
    503509
    504510    // check action type
    505     assert( ((action_type == DELETE_ALL_THREADS ) ||
    506              (action_type == BLOCK_ALL_THREADS )  ||
    507              (action_type == UNBLOCK_ALL_THREADS )), __FUNCTION__ , "illegal action type" );
     511    assert( ((type == DELETE_ALL_THREADS ) ||
     512             (type == BLOCK_ALL_THREADS )  ||
     513             (type == UNBLOCK_ALL_THREADS )), __FUNCTION__ , "illegal action type" );
    508514             
    509     // allocate a - shared - RPC descriptor in client thread stack
    510     // it can be shared because all parallel, non-blocking, server threads
    511     // use the same input arguments, and use the shared RPC response field
    512 
    513     // the client thread makes the following sequence:
    514     // 1. mask interrupts
    515     // 2. block itself
    516     // 3. send RPC requests to all copies
    517     // 4. unmask interrupts
    518     // 5. deschedule
     515
     516    // The client thread send parallel RPCs to all remote clusters containing
     517    // target process copies, wait all responses, and then handles directly the
     518    // threads in local cluster, when required.
     519    // The client thread allocates a - shared - RPC descriptor in the stack,
     520    // because all parallel, non-blocking, server threads use the same input
     521    // arguments, and use the shared RPC response field
    519522
    520523    // mask IRQs
    521524    hal_disable_irq( &save_sr);
    522525
    523     // client register blocking condition for itself
    524     thread_block( XPTR( local_cxy , client ) , THREAD_BLOCKED_RPC );
     526    // client thread blocks itself
     527    thread_block( client_xp , THREAD_BLOCKED_RPC );
    525528
    526529    // take the lock protecting the copies
     
    533536    rpc.thread    = client;
    534537    rpc.lid       = client->core->lid;
    535     rpc.args[0]   = action_type;
     538    rpc.args[0]   = type;
    536539    rpc.args[1]   = pid;
    537540
    538     // send RPCs to all clusters containing process copiess
     541    // scan list of process copies
     542    // to send RPCs to remote copies
    539543    XLIST_FOREACH( root_xp , iter_xp )
    540544    {
    541         // atomically increment responses counter
    542         hal_atomic_add( (void *)&rpc.responses , 1 );
    543 
     545        // get extended pointers and cluster on process
    544546        process_xp  = XLIST_ELEMENT( iter_xp , process_t , copies_list );
    545547        process_cxy = GET_CXY( process_xp );
     548        process_ptr = GET_PTR( process_xp );
     549
     550        if( process_cxy == local_cxy )    // process is local
     551        {
     552            local = process_ptr;
     553        }
     554        else                              // process is remote
     555        {
     556            // update number of remote process copies
     557            remote_nr++;
     558
     559            // atomically increment responses counter
     560            hal_atomic_add( (void *)&rpc.responses , 1 );
    546561
    547562#if DEBUG_PROCESS_SIGACTION
    548563if( DEBUG_PROCESS_SIGACTION < cycle )
    549 printk("\n[DBG] %s : send RPC to %s process %x in cluster %x\n",
    550 __FUNCTION__ , process_action_str( action_type ) , pid , process_cxy );
    551 #endif
    552         // call RPC in target cluster
    553         rpc_process_sigaction_client( process_cxy , &rpc );
    554     }
    555    
     564printk("\n[DBG] %s : thread %x in process %x handles remote process %x in cluster %x\n",
     565__FUNCTION__, client->trdid, client->process->pid, pid , process_cxy );
     566#endif
     567            // call RPC in target cluster
     568            rpc_process_sigaction_client( process_cxy , &rpc );
     569        }
     570    }  // end list of copies
     571
    556572    // release the lock protecting process copies
    557573    remote_spinlock_unlock( lock_xp );
     
    560576    hal_restore_irq( save_sr);
    561577
    562     // client thread deschedule : will be unblocked by the last RPC server thread
    563     sched_yield("blocked on rpc_process_sigaction");
     578    // - if there is remote process copies, the client thread deschedules,
     579    //   (it will be unblocked by the last RPC server thread).
     580    // - if there is no remote copies, the client thread unblock itself.
     581    if( remote_nr )
     582    {
     583        sched_yield("blocked on rpc_process_sigaction");
     584    }
     585    else
     586    {
     587        thread_unblock( client_xp , THREAD_BLOCKED_RPC );
     588    }
     589
     590    // handle the local process copy if required
     591    if( local != NULL )
     592    {
     593
     594#if DEBUG_PROCESS_SIGACTION
     595if( DEBUG_PROCESS_SIGACTION < cycle )
     596printk("\n[DBG] %s : thread %x in process %x handles local process %x in cluster %x\n",
     597__FUNCTION__, client->trdid, client->process->pid, pid , local_cxy );
     598#endif
     599        if     (type == DELETE_ALL_THREADS  ) process_delete_threads ( local , client_xp );
     600        else if(type == BLOCK_ALL_THREADS   ) process_block_threads  ( local , client_xp );
     601        else if(type == UNBLOCK_ALL_THREADS ) process_unblock_threads( local );
     602    }
    564603
    565604#if DEBUG_PROCESS_SIGACTION
    566605cycle = (uint32_t)hal_get_cycles();
    567606if( DEBUG_PROCESS_SIGACTION < cycle )
    568 printk("\n[DBG] %s : thread %x exit after %s process %x in cluster %x / cycle %d\n",
    569 __FUNCTION__ , client, process_action_str( action_type ) , pid , local_cxy , cycle );
     607printk("\n[DBG] %s : thread %x in process %x exit after %s process %x / cycle %d\n",
     608__FUNCTION__, client->trdid, client->process->pid,
     609process_action_str( type ), pid, cycle );
    570610#endif
    571611
     
    11001140uint32_t cycle = (uint32_t)hal_get_cycles();
    11011141if( DEBUG_PROCESS_MAKE_FORK < cycle )
    1102 printk("\n[DBG] %s : thread %x enter for process %x / cluster %x / cycle %d\n",
    1103 __FUNCTION__, CURRENT_THREAD, parent_pid, local_cxy, cycle );
     1142printk("\n[DBG] %s : thread %x in process %x enter / cluster %x / cycle %d\n",
     1143__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, local_cxy, cycle );
    11041144#endif
    11051145
     
    11231163    }
    11241164
     1165#if DEBUG_PROCESS_MAKE_FORK
     1166cycle = (uint32_t)hal_get_cycles();
     1167if( DEBUG_PROCESS_MAKE_FORK < cycle )
     1168printk("\n[DBG] %s : thread %x in process %x allocated process %x / cycle %d\n",
     1169__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, new_pid, cycle );
     1170#endif
     1171
    11251172    // initializes child process descriptor from parent process descriptor
    11261173    process_reference_init( process,
    11271174                            new_pid,
    1128                             parent_process_xp,
    11291175                            parent_process_xp );
    11301176
     
    11321178cycle = (uint32_t)hal_get_cycles();
    11331179if( DEBUG_PROCESS_MAKE_FORK < cycle )
    1134 printk("\n[DBG] %s : thread %x created child_process %x / child_pid %x / cycle %d\n",
    1135 __FUNCTION__, CURRENT_THREAD, process, new_pid, cycle );
    1136 #endif
     1180printk("\n[DBG] %s : thread %x in process %x initialized child_process %x / cycle %d\n",
     1181__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, new_pid, cycle );
     1182#endif
     1183
     1184    // give TXT ownership to child process
     1185    process_txt_set_ownership( XPTR( local_cxy , process ) );
    11371186
    11381187    // copy VMM from parent descriptor to child descriptor
     
    11511200cycle = (uint32_t)hal_get_cycles();
    11521201if( DEBUG_PROCESS_MAKE_FORK < cycle )
    1153 printk("\n[DBG] %s : thread %x copied VMM from parent %x to child %x / cycle %d\n",
    1154 __FUNCTION__ , CURRENT_THREAD , parent_pid, new_pid, cycle );
    1155 #endif
     1202printk("\n[DBG] %s : thread %x in process %x copied VMM from parent %x to child %x / cycle %d\n",
     1203__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid,
     1204parent_pid, new_pid, cycle );
     1205#endif
     1206
     1207    // parent process gives TXT ownership to child process if required
     1208    if( process_txt_is_owner(parent_process_xp) )
     1209    {
     1210        process_txt_set_ownership( XPTR( local_cxy , process ) );
     1211
     1212#if( DEBUG_PROCESS_MAKE_FORK & 1 )
     1213cycle = (uint32_t)hal_get_cycles();
     1214if( DEBUG_PROCESS_MAKE_EXEC < cycle )
     1215printk("\n[DBG] %s : thread %x in process %x gives TXT from parent %x to child %x / cycle %d\n",
     1216__FUNCTION__ , CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid,
     1217parent_pid, new_pid, cycle );
     1218#endif
     1219
     1220    }
    11561221
    11571222    // update extended pointer on .elf file
     
    11781243cycle = (uint32_t)hal_get_cycles();
    11791244if( DEBUG_PROCESS_MAKE_FORK < cycle )
    1180 printk("\n[DBG] %s : thread %x created child thread %x on core[%x,%d] / cycle %d\n",
    1181 __FUNCTION__ , CURRENT_THREAD, thread, local_cxy, thread->core->lid, cycle );
     1245printk("\n[DBG] %s : thread %x in process %x created main thread %x on core[%x,%d] / cycle %d\n",
     1246__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid,
     1247thread, local_cxy, thread->core->lid, cycle );
    11821248#endif
    11831249
     
    12001266cycle = (uint32_t)hal_get_cycles();
    12011267if( DEBUG_PROCESS_MAKE_FORK < cycle )
    1202 printk("\n[DBG] %s : thread %x set COW in parent and child / cycle %d\n",
    1203 __FUNCTION__ , CURRENT_THREAD, cycle );
     1268printk("\n[DBG] %s : thread %x in process %x set COW in parent and child / cycle %d\n",
     1269__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, cycle );
    12041270#endif
    12051271
     
    12221288cycle = (uint32_t)hal_get_cycles();
    12231289if( DEBUG_PROCESS_MAKE_FORK < cycle )
    1224 printk("\n[DBG] %s : thread %x exit / cycle %d\n",
    1225 __FUNCTION__, CURRENT_THREAD, cycle );
     1290printk("\n[DBG] %s : thread %x in process %x exit / created process %x / cycle %d\n",
     1291__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, new_pid, cycle );
    12261292#endif
    12271293
     
    12291295
    12301296}   // end process_make_fork()
    1231 
    12321297
    12331298/////////////////////////////////////////////////////
    12341299error_t process_make_exec( exec_info_t  * exec_info )
    12351300{
    1236     char           * path;                    // pathname to .elf file
    1237     pid_t            pid;                     // old_process PID, given to new_process
    1238     pid_t            temp_pid;                // temporary PID / given to old_process
    1239     process_t      * old_process;             // local pointer on old process
    1240     thread_t       * old_thread;              // local pointer on old thread
    1241     process_t      * new_process;             // local pointer on new process
    1242     thread_t       * new_thread;              // local pointer on new thread
    1243     xptr_t           parent_xp;               // extended pointer on parent process
    1244     process_t      * parent_ptr;              // local pointer on parent process
    1245     cxy_t            parent_cxy;              // parent process cluster identifier
    1246     xptr_t           children_lock_xp;        // extended pointer on children lock in parent
    1247     xptr_t           children_root_xp;        // extended pointer on children root in parent
    1248     xptr_t           children_nr_xp;          // extended pointer on children number in parent
    1249     thread_t       * parent_main_ptr;         // local pointer on parent main thread
    1250     xptr_t           parent_main_xp;          // extended pointer on parent main thread
    1251     pthread_attr_t   attr;                    // new thread attributes
    1252     lid_t            lid;                     // selected core local index
     1301    thread_t       * thread;                  // local pointer on this thread
     1302    process_t      * process;                 // local pointer on this process
     1303    pid_t            pid;                     // this process identifier
    12531304        error_t          error;                   // value returned by called functions
    1254    
    1255     // get old_thread, old_process & PID
    1256     old_thread  = CURRENT_THREAD;
    1257     old_process = old_thread->process;
    1258     pid         = old_process->pid;
    1259 
    1260         // get .elf pathname from exec_info
    1261         path = exec_info->path;
    1262 
    1263     // this function must be executed by a thread running in owner cluster
    1264     assert( (CXY_FROM_PID( pid ) == local_cxy), __FUNCTION__,
    1265     "local_cluster must be owner_cluster\n" );
    1266 
    1267     assert( (LTID_FROM_TRDID( old_thread->trdid ) == 0) , __FUNCTION__,
    1268     "must be called by the main thread\n" );
    1269  
     1305    char           * path;                    // path to .elf file
     1306    xptr_t           file_xp;                 // extended pointer on .elf file descriptor
     1307    uint32_t         file_id;                 // file index in fd_array
     1308    uint32_t         args_nr;                 // number of main thread arguments
     1309    char          ** args_pointers;           // array of pointers on main thread arguments
     1310
     1311    // get thread, process & PID
     1312    thread  = CURRENT_THREAD;
     1313    process = thread->process;
     1314    pid     = process->pid;
     1315
     1316        // get relevant infos from exec_info
     1317        path          = exec_info->path;
     1318    args_nr       = exec_info->args_nr;
     1319    args_pointers = exec_info->args_pointers;
     1320
    12701321#if DEBUG_PROCESS_MAKE_EXEC
    12711322uint32_t cycle = (uint32_t)hal_get_cycles();
    12721323if( DEBUG_PROCESS_MAKE_EXEC < cycle )
    12731324printk("\n[DBG] %s : thread %x in process %x enters / path %s / cycle %d\n",
    1274 __FUNCTION__, old_thread->trdid, pid, path, cycle );
    1275 #endif
    1276 
    1277     // get parent process pointers
    1278     parent_xp   = old_process->parent_xp;
    1279     parent_cxy  = GET_CXY( parent_xp );
    1280     parent_ptr  = GET_PTR( parent_xp );
    1281    
     1325__FUNCTION__, thread->trdid, pid, path, cycle );
     1326#endif
     1327
     1328    // open the file identified by <path>
     1329    file_xp = XPTR_NULL;
     1330    file_id = -1;
     1331        error   = vfs_open( process,
     1332                            path,
     1333                            O_RDONLY,
     1334                            0,
     1335                            &file_xp,
     1336                            &file_id );
     1337        if( error )
     1338        {
     1339                printk("\n[ERROR] in %s : failed to open file <%s>\n", __FUNCTION__ , path );
     1340                return -1;
     1341        }
     1342
    12821343#if (DEBUG_PROCESS_MAKE_EXEC & 1)
    12831344if( DEBUG_PROCESS_MAKE_EXEC < cycle )
    1284 printk("\n[DBG] %s : thread %x in process %x get parent process %x in cluster %x\n",
    1285 __FUNCTION__, old_thread->trdid, pid, parent_ptr, parent_cxy );
    1286 #endif
    1287 
    1288     // get extended pointers on parent children_root, children_lock and children_nr
    1289     children_root_xp = XPTR( parent_cxy , &parent_ptr->children_root );
    1290     children_lock_xp = XPTR( parent_cxy , &parent_ptr->children_lock );
    1291     children_nr_xp   = XPTR( parent_cxy , &parent_ptr->children_nr   );
    1292 
    1293     // get pointers on the parent process main thread
    1294     parent_main_ptr = hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->th_tbl[0] ) );
    1295     parent_main_xp  = XPTR( parent_cxy , parent_main_ptr );
    1296 
    1297      // allocate memory for new_process descriptor
    1298     new_process = process_alloc();
    1299 
    1300     if( new_process == NULL )
    1301     {
    1302         printk("\n[ERROR] in %s : cannot allocate process for %s\n", __FUNCTION__ , path );
     1345printk("\n[DBG] %s : open file <%s>\n", __FUNCTION__, path );
     1346#endif
     1347
     1348    // delete all threads other than this main thread in all clusters
     1349    process_sigaction( pid , DELETE_ALL_THREADS );
     1350
     1351    // reset local process VMM
     1352    vmm_destroy( process );
     1353
     1354#if( DEBUG_PROCESS_MAKE_EXEC & 1 )
     1355cycle = (uint32_t)hal_get_cycles();
     1356if( DEBUG_PROCESS_MAKE_EXEC < cycle )
     1357printk("\n[DBG] %s : thread %x in process %x / reset VMM / cycle %d\n",
     1358__FUNCTION__, thread->trdid, pid, cycle );
     1359#endif
     1360
     1361    // re-initialize the VMM (kentry/args/envs vsegs registration)
     1362    error = vmm_init( process );
     1363    if( error )
     1364    {
     1365        printk("\n[ERROR] in %s : cannot initialise VMM for %s\n", __FUNCTION__ , path );
     1366        vfs_close( file_xp , file_id );
     1367        // FIXME restore old process VMM
    13031368        return -1;
    13041369    }
    1305 
    1306     // get a temporary PID for old_process
    1307     error = cluster_pid_alloc( old_process , &temp_pid );
    1308     if( error )
    1309     {
    1310         printk("\n[ERROR] in %s : cannot get PID in cluster %x\n",
    1311         __FUNCTION__ , local_cxy );
    1312         process_free( new_process );
    1313         return -1;
    1314     }
    1315 
    1316     // set temporary PID to old_process
    1317     old_process->pid = temp_pid;
    1318 
    1319     // initialize new process descriptor
    1320     process_reference_init( new_process,
    1321                             pid,
    1322                             parent_xp,                          // parent_process_xp
    1323                             XPTR(local_cxy , old_process) );    // model_process
    1324 
    1325     // give TXT ownership to new_process
    1326     process_txt_set_ownership( XPTR( local_cxy , new_process) );
    1327 
     1370   
    13281371#if( DEBUG_PROCESS_MAKE_EXEC & 1 )
    13291372cycle = (uint32_t)hal_get_cycles();
    13301373if( DEBUG_PROCESS_MAKE_EXEC < cycle )
    1331 printk("\n[DBG] %s : thread %x in process %x created new process %x\n",
    1332 __FUNCTION__ , old_thread->trdid, pid, new_process );
    1333 #endif
    1334 
    1335     // register code & data vsegs as well as entry-point in new process VMM,
     1374printk("\n[DBG] %s : thread %x in process %x / kentry/args/envs vsegs registered / cycle %d\n",
     1375__FUNCTION__, thread->trdid, pid, cycle );
     1376#endif
     1377
     1378    // register code & data vsegs as well as entry-point in process VMM,
    13361379    // and register extended pointer on .elf file in process descriptor
    1337         error = elf_load_process( path , new_process );
    1338 
     1380        error = elf_load_process( file_xp , process );
    13391381    if( error )
    13401382        {
    13411383                printk("\n[ERROR] in %s : failed to access <%s>\n", __FUNCTION__ , path );
    1342         process_txt_set_ownership( XPTR( local_cxy , old_process) );
    1343         process_txt_detach( XPTR( local_cxy , new_process) );
    1344         process_destroy( new_process );
    1345         old_process->pid = pid;
     1384        vfs_close( file_xp , file_id );
     1385        // FIXME restore old process VMM
    13461386        return -1;
    13471387        }
     
    13501390cycle = (uint32_t)hal_get_cycles();
    13511391if( DEBUG_PROCESS_MAKE_EXEC < cycle )
    1352 printk("\n[DBG] %s : thread %x registered code/data vsegs in new process %x / cycle %d\n",
    1353 __FUNCTION__, old_thread , new_process->pid , cycle );
    1354 #endif
    1355 
    1356     // select a core in local cluster to execute the main thread
    1357     lid  = cluster_select_local_core();
    1358 
    1359     // initialize pthread attributes for main thread
    1360     attr.attributes = PT_ATTR_DETACH | PT_ATTR_CLUSTER_DEFINED | PT_ATTR_CORE_DEFINED;
    1361     attr.cxy        = local_cxy;
    1362     attr.lid        = lid;
    1363 
    1364     // create and initialize main thread in local cluster
    1365         error = thread_user_create( pid,
    1366                                 (void *)new_process->vmm.entry_point,
    1367                                 exec_info->args_pointers,
    1368                                 &attr,
    1369                                 &new_thread );
    1370         if( error )
    1371         {
    1372                 printk("\n[ERROR] in %s : cannot create thread for %s\n", __FUNCTION__ , path );
    1373         process_txt_set_ownership( XPTR( local_cxy , old_process) );
    1374         process_txt_detach( XPTR( local_cxy , new_process) );
    1375         process_destroy( new_process );
    1376         old_process->pid = pid;
     1392printk("\n[DBG] %s : thread %x in process %x / code/data vsegs registered / cycle %d\n",
     1393__FUNCTION__, thread->trdid, pid, cycle );
     1394#endif
     1395
     1396    // update the existing main thread descriptor... and jump to user code
     1397    error = thread_user_exec( (void *)process->vmm.entry_point,
     1398                              args_nr,
     1399                              args_pointers );
     1400    if( error )
     1401    {
     1402        printk("\n[ERROR] in %s : cannot reset main thread for %s\n", __FUNCTION__ , path );
     1403        vfs_close( file_xp , file_id );
     1404        // FIXME restore old process VMM
    13771405        return -1;
    1378         }
    1379 
    1380     // check main thread LTID
    1381     assert( (LTID_FROM_TRDID(new_thread->trdid) == 0) , __FUNCTION__ ,
    1382     "main thread must have LTID == 0\n" );
    1383 
    1384 #if( DEBUG_PROCESS_MAKE_EXEC & 1 )
    1385 cycle = (uint32_t)hal_get_cycles();
    1386 if( DEBUG_PROCESS_MAKE_EXEC < cycle )
    1387 printk("\n[DBG] %s : thread %x created new_process main thread %x / cycle %d\n",
    1388 __FUNCTION__ , old_thread , new_thread , cycle );
    1389 #endif
    1390 
    1391     // register new_process in parent children list
    1392     remote_spinlock_lock( children_lock_xp );
    1393         xlist_add_last( children_root_xp , XPTR( local_cxy , &new_process->children_list ) );
    1394         hal_remote_atomic_add( children_nr_xp , 1 );
    1395     remote_spinlock_unlock( children_lock_xp );
    1396 
    1397     // activate new thread
    1398         thread_unblock( XPTR( local_cxy , new_thread ) , THREAD_BLOCKED_GLOBAL );
    1399 
    1400     // detach old_process from TXT
    1401     process_txt_detach( XPTR( local_cxy , old_process ) );
    1402 
    1403     // block old_thread
    1404     thread_block( XPTR( local_cxy , old_thread ) , THREAD_BLOCKED_GLOBAL );
    1405 
    1406     // atomically update old_process termination state
    1407     hal_atomic_or( &old_process->term_state , PROCESS_TERM_EXIT );
    1408 
    1409     // take the children lock and unblock the parent process main thread
    1410     remote_spinlock_lock( children_lock_xp );
    1411     thread_unblock( parent_main_xp , THREAD_BLOCKED_WAIT );
    1412     remote_spinlock_unlock( children_lock_xp );
    1413 
    1414     hal_fence();
    1415 
    1416 #if DEBUG_PROCESS_MAKE_EXEC
    1417 cycle = (uint32_t)hal_get_cycles();
    1418 if( DEBUG_PROCESS_MAKE_EXEC < cycle )
    1419 printk("\n[DBG] %s : old thread %x blocked for delete / new thread %x activated / cycle %d\n",
    1420 __FUNCTION__ , old_thread , new_thread , cycle );
    1421 #endif
    1422    
     1406    }
     1407
     1408    assert( false, __FUNCTION__, "we should not execute this code");
     1409 
    14231410        return 0;
    14241411
    14251412}  // end process_make_exec()
     1413
    14261414
    14271415///////////////////////////////////////////////
     
    14741462    pthread_attr_t   attr;          // main thread attributes
    14751463    lid_t            lid;           // selected core local index for main thread
     1464    xptr_t           file_xp;       // extended pointer on .elf file descriptor
     1465    uint32_t         file_id;       // file index in fd_array
    14761466    error_t          error;
    14771467
     
    14791469uint32_t cycle = (uint32_t)hal_get_cycles();
    14801470if( DEBUG_PROCESS_INIT_CREATE < cycle )
    1481 printk("\n[DBG] %s : thread %x enter / cycle %d\n", __FUNCTION__, CURRENT_THREAD, cycle );
     1471printk("\n[DBG] %s : thread %x in process %x enter / cycle %d\n",
     1472__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, cycle );
    14821473#endif
    14831474
    14841475    // allocates memory for process descriptor from local cluster
    14851476        process = process_alloc();
    1486         if( process == NULL )
    1487     {
    1488                 printk("\n[PANIC] in %s : no memory for process descriptor in cluster %x\n",
    1489                 __FUNCTION__, local_cxy  );
    1490     }
     1477       
     1478    assert( (process != NULL), __FUNCTION__,
     1479    "no memory for process descriptor in cluster %x\n", local_cxy  );
    14911480
    14921481    // get PID from local cluster
    14931482    error = cluster_pid_alloc( process , &pid );
    1494     if( error )
    1495     {
    1496                 printk("\n[PANIC] in %s : cannot allocate PID in cluster %x\n",
    1497                 __FUNCTION__, local_cxy );
    1498         process_free( process );
    1499     }
    1500 
    1501     // check allocated PID
    1502     assert( (pid == 1) , __FUNCTION__ , "process INIT must be first process in cluster 0\n" );
     1483
     1484    assert( (error == 0), __FUNCTION__,
     1485    "cannot allocate PID in cluster %x\n", local_cxy );
     1486
     1487    assert( (pid == 1) , __FUNCTION__,
     1488    "process INIT must be first process in cluster 0\n" );
    15031489
    15041490    // initialize process descriptor / parent is local process_zero
    15051491    process_reference_init( process,
    15061492                            pid,
    1507                             XPTR( local_cxy , &process_zero ),     // parent
    1508                             XPTR( local_cxy , &process_zero ) );   // model
     1493                            XPTR( local_cxy , &process_zero ) ); 
     1494
     1495    // open the file identified by CONFIG_PROCESS_INIT_PATH
     1496    file_xp = XPTR_NULL;
     1497    file_id = -1;
     1498        error   = vfs_open( process,
     1499                            CONFIG_PROCESS_INIT_PATH,
     1500                            O_RDONLY,
     1501                            0,
     1502                            &file_xp,
     1503                            &file_id );
     1504
     1505        assert( (error == 0), __FUNCTION__,
     1506    "failed to open file <%s>\n", CONFIG_PROCESS_INIT_PATH );
    15091507
    15101508    // register "code" and "data" vsegs as well as entry-point
    15111509    // in process VMM, using information contained in the elf file.
    1512         if( elf_load_process( CONFIG_PROCESS_INIT_PATH , process ) )
    1513         {
    1514                 printk("\n[PANIC] in %s : cannot access .elf file / path = %s\n",
    1515                 __FUNCTION__, CONFIG_PROCESS_INIT_PATH );
    1516         process_destroy( process );
    1517         }
     1510        error = elf_load_process( file_xp , process );
     1511
     1512        assert( (error == 0), __FUNCTION__,
     1513    "cannot access .elf file <%s>\n", CONFIG_PROCESS_INIT_PATH );
    15181514
    15191515    // get extended pointers on process_zero children_root, children_lock
     
    15411537                                &attr,
    15421538                                &thread );
    1543         if( error )
    1544         {
    1545                 printk("\n[PANIC] in %s : cannot create main thread / path = %s\n",
    1546                 __FUNCTION__, CONFIG_PROCESS_INIT_PATH );
    1547         process_destroy( process );
    1548         }
    1549 
    1550     // check main thread index
    1551     assert( (thread->trdid == 0) , __FUNCTION__ , "main thread must have index 0\n" );
     1539
     1540        assert( (error == 0), __FUNCTION__,
     1541    "cannot create main thread for <%s>\n", CONFIG_PROCESS_INIT_PATH );
     1542
     1543    assert( (thread->trdid == 0), __FUNCTION__,
     1544    "main thread must have index 0 for <%s>\n", CONFIG_PROCESS_INIT_PATH );
    15521545
    15531546    // activate thread
     
    15591552cycle = (uint32_t)hal_get_cycles();
    15601553if( DEBUG_PROCESS_INIT_CREATE < cycle )
    1561 printk("\n[DBG] %s : thread %x exit / cycle %d\n", __FUNCTION__, CURRENT_THREAD, cycle );
     1554printk("\n[DBG] %s : thread %x in process %x exit / cycle %d\n",
     1555__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, cycle );
    15621556#endif
    15631557
     
    17021696    xptr_t      lock_xp;      // extended pointer on list lock in chdev
    17031697
    1704 #if DEBUG_PROCESS_TXT
    1705 uint32_t cycle = (uint32_t)hal_get_cycles();
    1706 if( DEBUG_PROCESS_TXT < cycle )
    1707 printk("\n[DBG] %s : thread %x enter for process %x / txt_id = %d  / cycle %d\n",
    1708 __FUNCTION__, CURRENT_THREAD, process->pid, txt_id, cycle );
    1709 #endif
    1710 
    17111698    // check process is in owner cluster
    17121699    assert( (CXY_FROM_PID( process->pid ) == local_cxy) , __FUNCTION__ ,
     
    17321719
    17331720#if DEBUG_PROCESS_TXT
    1734 cycle = (uint32_t)hal_get_cycles();
     1721uint32_t cycle = (uint32_t)hal_get_cycles();
    17351722if( DEBUG_PROCESS_TXT < cycle )
    1736 printk("\n[DBG] %s : thread %x exit for process %x / txt_id = %d / cycle %d\n",
    1737 __FUNCTION__, CURRENT_THREAD, process->pid, txt_id , cycle );
     1723printk("\n[DBG] %s : thread %x in process %x attached process %x to TXT %d / cycle %d\n",
     1724__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid,
     1725process->pid, txt_id , cycle );
    17381726#endif
    17391727
     
    17551743    process_cxy = GET_CXY( process_xp );
    17561744    process_ptr = GET_PTR( process_xp );
     1745
     1746    // check process descriptor in owner cluster
    17571747    process_pid = hal_remote_lw( XPTR( process_cxy , &process_ptr->pid ) );
    1758 
    1759     // check process descriptor in owner cluster
    17601748    assert( (CXY_FROM_PID( process_pid ) == process_cxy ) , __FUNCTION__ ,
    17611749    "process descriptor not in owner cluster" );
    1762 
    1763 #if DEBUG_PROCESS_TXT
    1764 uint32_t cycle = (uint32_t)hal_get_cycles();
    1765 if( DEBUG_PROCESS_TXT < cycle )
    1766 printk("\n[DBG] %s : thread %x enter for process %x / cycle %d\n",
    1767 __FUNCTION__, CURRENT_THREAD, process_pid, cycle );
    1768 #endif
    17691750
    17701751    // release TXT ownership (does nothing if not TXT owner)
     
    17881769
    17891770#if DEBUG_PROCESS_TXT
    1790 cycle  = (uint32_t)hal_get_cycles();
     1771uint32_t cycle  = (uint32_t)hal_get_cycles();
    17911772uint32_t txt_id = hal_remote_lw( XPTR( chdev_cxy , &chdev_ptr->channel ) );
    17921773if( DEBUG_PROCESS_TXT < cycle )
    1793 printk("\n[DBG] %s : thread %x exit / process %x detached from TXT %d / cycle %d\n",
    1794 __FUNCTION__, CURRENT_THREAD, process_pid, txt_id, cycle );
     1774printk("\n[DBG] %s : thread %x in process %x detached process %x from TXT %d / cycle %d\n",
     1775__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid,
     1776process_pid, txt_id, cycle );
    17951777#endif
    17961778
     
    18111793    process_cxy = GET_CXY( process_xp );
    18121794    process_ptr = GET_PTR( process_xp );
    1813 
    1814     // get process PID
    18151795    process_pid = hal_remote_lw( XPTR( process_cxy , &process_ptr->pid ) );
    18161796
     
    18181798    assert( (process_cxy == CXY_FROM_PID( process_pid )) , __FUNCTION__,
    18191799    "process descriptor not in owner cluster\n" );
    1820 
    1821 #if DEBUG_PROCESS_TXT
    1822 uint32_t cycle = (uint32_t)hal_get_cycles();
    1823 if( DEBUG_PROCESS_TXT < cycle )
    1824 printk("\n[DBG] %s : thread %x enter for process %x / cycle %d\n",
    1825 __FUNCTION__, CURRENT_THREAD, process_pid, cycle );
    1826 #endif
    18271800
    18281801    // get extended pointer on stdin pseudo file
     
    18381811
    18391812#if DEBUG_PROCESS_TXT
    1840 cycle = (uint32_t)hal_get_cycles();
     1813uint32_t cycle  = (uint32_t)hal_get_cycles();
     1814uint32_t txt_id = hal_remote_lw( XPTR( txt_cxy , &txt_ptr->channel ) );
    18411815if( DEBUG_PROCESS_TXT < cycle )
    1842 printk("\n[DBG] %s : thread %x exit for process %x / cycle %d\n",
    1843 __FUNCTION__, CURRENT_THREAD, process_pid, cycle );
     1816printk("\n[DBG] %s : thread %x in process %x give TXT %d to process %x / cycle %d\n",
     1817__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, txt_id, process_pid, cycle );
    18441818#endif
    18451819
     
    18651839    cxy_t       current_cxy;     // cluster for current process
    18661840
     1841#if DEBUG_PROCESS_TXT
     1842uint32_t cycle;
     1843#endif
     1844
    18671845    // get pointers on process in owner cluster
    18681846    process_cxy = GET_CXY( process_xp );
    18691847    process_ptr = GET_PTR( process_xp );
    1870 
    1871     // get process PID
    18721848    process_pid = hal_remote_lw( XPTR( process_cxy , &process_ptr->pid ) );
    18731849
     
    18751851    assert( (process_cxy == CXY_FROM_PID( process_pid )) , __FUNCTION__,
    18761852    "process descriptor not in owner cluster\n" );
    1877 
    1878 #if DEBUG_PROCESS_TXT
    1879 uint32_t cycle = (uint32_t)hal_get_cycles();
    1880 if( DEBUG_PROCESS_TXT < cycle )
    1881 printk("\n[DBG] %s : thread %x enter / process %x / cycle %d\n",
    1882 __FUNCTION__, CURRENT_THREAD, process_pid, cycle );
    1883 #endif
    18841853
    18851854    // get extended pointer on stdin pseudo file
     
    18951864    txt_id   = hal_remote_lw ( XPTR( txt_cxy , &txt_ptr->channel ) );
    18961865
    1897 #if( DEBUG_PROCESS_TXT & 1 )
    1898 if( DEBUG_PROCESS_TXT < cycle )
    1899 printk("\n[DBG] %s : file_ptr %x / txt_ptr %x / txt_id %d / owner_ptr = %x\n",
    1900 __FUNCTION__, GET_PTR(file_xp), txt_ptr, txt_id, GET_PTR(owner_xp) );
    1901 #endif
    1902 
    19031866    // transfer ownership only if process is the TXT owner
    19041867    if( (owner_xp == process_xp) && (txt_id > 0) ) 
     
    19131876        if( process_get_ppid( process_xp ) != 1 )           // process is not KSH
    19141877        {
    1915 
    1916 #if( DEBUG_PROCESS_TXT & 1 )
    1917 if( DEBUG_PROCESS_TXT < cycle )
    1918 printk("\n[DBG] %s : process is not the KSH process => search the KSH\n", __FUNCTION__ );
    1919 #endif
    19201878            // scan attached process list to find KSH process
    19211879            XLIST_FOREACH( root_xp , iter_xp )
     
    19341892
    19351893#if DEBUG_PROCESS_TXT
    1936 cycle = (uint32_t)hal_get_cycles();
     1894cycle   = (uint32_t)hal_get_cycles();
     1895uint32_t ksh_pid = hal_remote_lw( XPTR( current_cxy , &current_ptr->pid ) );
    19371896if( DEBUG_PROCESS_TXT < cycle )
    1938 printk("\n[DBG] %s : thread %x exit / process %x to KSH process %x / cycle %d\n",
    1939 __FUNCTION__, CURRENT_THREAD, process_pid,
    1940 hal_remote_lw( XPTR( current_cxy , &current_ptr->pid ) ), cycle );
     1897printk("\n[DBG] %s : thread %x in process %x release TXT %d to KSH %x / cycle %d\n",
     1898__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, txt_id, ksh_pid, cycle );
     1899process_txt_display( txt_id );
    19411900#endif
    19421901                     return;
     
    19541913        else                                               // process is KSH
    19551914        {
    1956 
    1957 #if( DEBUG_PROCESS_TXT & 1 )
    1958 if( DEBUG_PROCESS_TXT < cycle )
    1959 printk("\n[DBG] %s : process is the KSH process => search another\n", __FUNCTION__ );
    1960 #endif
    1961 
    19621915            // scan attached process list to find another process
    19631916            XLIST_FOREACH( root_xp , iter_xp )
     
    19761929
    19771930#if DEBUG_PROCESS_TXT
    1978 cycle = (uint32_t)hal_get_cycles();
     1931cycle   = (uint32_t)hal_get_cycles();
     1932uint32_t new_pid = hal_remote_lw( XPTR( current_cxy , &current_ptr->pid ) );
    19791933if( DEBUG_PROCESS_TXT < cycle )
    1980 printk("\n[DBG] %s : thread %x exit / KSH process %x to process %x / cycle %d\n",
    1981 __FUNCTION__, CURRENT_THREAD, process_pid,
    1982 hal_remote_lw( XPTR( current_cxy , &current_ptr->pid ) ), cycle );
     1934printk("\n[DBG] %s : thread %x in process %x release TXT %d to process %x / cycle %d\n",
     1935__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, txt_id, new_pid, cycle );
     1936process_txt_display( txt_id );
    19831937#endif
    19841938                     return;
     
    19951949cycle = (uint32_t)hal_get_cycles();
    19961950if( DEBUG_PROCESS_TXT < cycle )
    1997 printk("\n[DBG] %s : thread %x exit / KSH process %x to nobody / cycle %d\n",
    1998 __FUNCTION__, CURRENT_THREAD, process_pid, cycle );
     1951printk("\n[DBG] %s : thread %x in process %x release TXT %d to nobody / cycle %d\n",
     1952__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, txt_id, cycle );
     1953process_txt_display( txt_id );
    19991954#endif
    20001955            return;
     
    20071962cycle = (uint32_t)hal_get_cycles();
    20081963if( DEBUG_PROCESS_TXT < cycle )
    2009 printk("\n[DBG] %s : thread %x exit / process %x is not TXT owner / cycle %d\n",
    2010 __FUNCTION__, CURRENT_THREAD, process_pid, cycle );
     1964printk("\n[DBG] %s : thread %x in process %d does nothing (not TXT owner) / cycle %d\n",
     1965__FUNCTION__, CURRENT_THREAD->trdid, process_pid, cycle );
     1966process_txt_display( txt_id );
    20111967#endif
    20121968
     
    20141970}  // end process_txt_transfer_ownership()
    20151971
     1972
     1973//////////////////////////////////////////////////
     1974uint32_t process_txt_is_owner( xptr_t process_xp )
     1975{
     1976    // get local pointer and cluster of process in owner cluster
     1977    cxy_t       process_cxy = GET_CXY( process_xp );
     1978    process_t * process_ptr = GET_PTR( process_xp );
     1979
     1980    // check owner cluster
     1981    pid_t process_pid = hal_remote_lw( XPTR( process_cxy , &process_ptr->pid ) );
     1982    assert( (process_cxy == CXY_FROM_PID( process_pid )) , __FUNCTION__,
     1983    "process descriptor not in owner cluster\n" );
     1984
     1985    // get extended pointer on stdin pseudo file
     1986    xptr_t file_xp = hal_remote_lwd( XPTR( process_cxy , &process_ptr->fd_array.array[0] ) );
     1987
     1988    // get pointers on TXT chdev
     1989    xptr_t    txt_xp  = chdev_from_file( file_xp );
     1990    cxy_t     txt_cxy = GET_CXY( txt_xp );
     1991    chdev_t * txt_ptr = GET_PTR( txt_xp );
     1992
     1993    // get extended pointer on TXT_RX owner process
     1994    xptr_t owner_xp = hal_remote_lwd( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) );
     1995
     1996    return (process_xp == owner_xp);
     1997
     1998}   // end process_txt_is_owner()
    20161999
    20172000////////////////////////////////////////////////     
     
    20232006
    20242007    return (xptr_t)hal_remote_lwd( XPTR( txt_rx_cxy , &txt_rx_ptr->ext.txt.owner_xp ) );
    2025 }
     2008
     2009}  // end process_txt_get_owner()
    20262010
    20272011///////////////////////////////////////////
  • trunk/kernel/kern/process.h

    r450 r457  
    2929#include <kernel_config.h>
    3030#include <errno.h>
    31 #include <hal_types.h>
     31#include <hal_kernel_types.h>
    3232#include <list.h>
    3333#include <xlist.h>
     
    146146
    147147    uint32_t          term_state;       /*! termination status (flags & exit status)        */
    148 
    149     bool_t            txt_owner;        /*! current TXT owner                               */
    150148}
    151149process_t;
     
    213211/*********************************************************************************************
    214212 * This function initializes a local, reference, user process descriptor from another process
    215  * descriptor, defined by the <model_xp> argument. The <process> and <pid> arguments must
    216  * be previously allocated by he caller. This function can be called by three functions:
    217  * 1) process_init_create() : process is the reference INIT process / pid = 1 /
    218  *    the parent and model process descriptors are both the kernel process_zero.
    219  * 2) process_make_fork() : the model process descriptor is the (generally remote)
    220  *    parent process.
    221  * 3) process_make exec() : the model process is the local old_process, the new_process
    222  *    parent is the same as the old_process parent.
     213 * descriptor, defined by the <parent_xp> argument. The <process> and <pid> arguments must
     214 * be previously allocated by the caller. This function can be called by two functions:
     215 * 1) process_init_create() : process is the INIT process; parent is process-zero.
     216 * 2) process_make_fork() : the parent process descriptor is generally remote.
    223217 * The following fields are initialised :
    224218 * - It set the pid / ppid / ref_xp / parent_xp / state fields.
    225219 * - It initializes the VMM (register the kentry, args, envs vsegs in VSL)
    226220 * - It initializes the FDT, defining the three pseudo files STDIN / STDOUT / STDERR.
     221 *   . if INIT process     => link to kernel TXT[0].
     222 *   . if KSH[i] process   => allocate a free TXT[i] and give TXT ownership.
     223 *   . if USER process     => same TXT[i] as parent process and give TXT ownership.
    227224 * - It set the root_xp, bin_xp, cwd_xp fields.
    228225 * - It reset the children list as empty, but does NOT register it in parent children list.
     
    236233 * @ pid          : [in] process identifier.
    237234 * @ parent_xp    : [in] extended pointer on parent process descriptor.
    238  * @ model_xp     : [in] extended pointer on model process descriptor.
    239235 ********************************************************************************************/
    240236void process_reference_init( process_t * process,
    241237                             pid_t       pid,
    242                              xptr_t      parent_xp,
    243                              xptr_t      model_xp );
     238                             xptr_t      parent_xp );
    244239
    245240/*********************************************************************************************
     
    515510 * It is called only by the process_reference_init() function when creating a KSH process.
    516511 * It makes a kernel panic if no free TXT terminal is found.
    517  * The allocated TXT terminal is only released if the KSH process is deleted,
    518  * which is a rare and abnormal event.
     512 * The allocated TXT terminal is only released when the KSH process is deleted.
    519513 *********************************************************************************************
    520514 * @ return TXT terminal index if succes / kernel panic if no terminal found.
     
    547541
    548542/*********************************************************************************************
    549  * This function gives to a process identified by the <owner_xp> argument, and attached
    550  * to terminal TXT[i] the exclusive ownership of the TXT_RX[i] terminal.
    551  * The process descriptor must be in the process owner cluster.
     543 * This function gives the TXT ownership to a process identified by the <process_xp> argument.
     544 * It can be called by a thread running in any cluster, but the <process_xp> must be the
     545 * owner cluster process descriptor.
    552546 *********************************************************************************************
    553547 * @ owner_xp  : extended pointer on process descriptor in owner cluster.
    554548 ********************************************************************************************/
    555 void process_txt_set_ownership( xptr_t owner_xp );
    556 
    557 /*********************************************************************************************
    558  * When the process dentified by the <owner_xp> argument has the exclusive ownership of
     549void process_txt_set_ownership( xptr_t process_xp );
     550
     551/*********************************************************************************************
     552 * When the process identified by the <owner_xp> argument has the exclusive ownership of
    559553 * the TXT_RX terminal, this function transfer this ownership to another attached process.
    560554 * The process descriptor must be the process owner.
     
    565559 * - If there is no other attached process, the TXT has no more defined owner.
    566560 *********************************************************************************************
    567  * @ owner_xp  : extended pointer on process descriptor in owner cluster.
    568  ********************************************************************************************/
    569 void process_txt_transfer_ownership( xptr_t owner_xp );
    570 
    571 /*********************************************************************************************
    572  * This function returns the TXT owner process (foreground process)
    573  * for a given TXT terminal identified by its <channel> index.
    574  *********************************************************************************************
    575  * @ channel  : TXT terminal channel.
    576  * @ return extentded pointer on TXT owner process in owner cluster.
     561 * @ process_xp  : extended pointer on process descriptor in owner cluster.
     562 ********************************************************************************************/
     563void process_txt_transfer_ownership( xptr_t process_xp );
     564
     565/*********************************************************************************************
     566 * This function returns true if the  process identified by the <process_xp> argument
     567 * is the TXT owner. It can be called by a thread running in any cluster, but the
     568 * process_xp must be the owner cluster process descriptor.
     569 *********************************************************************************************
     570 * @ return a non-zero value if target process is TXT owner.
     571 ********************************************************************************************/
     572uint32_t process_txt_is_owner( xptr_t process_xp );
     573
     574/*********************************************************************************************
     575 * This function returns an extended ponter on the current TXT owner process,
     576 * for the TXT terminal identified by the <channel> index.
     577 *********************************************************************************************
     578 * @ channel : TXT channel.
     579 * @ return extended pointer on TXT owner process.
    577580 ********************************************************************************************/
    578581xptr_t process_txt_get_owner( uint32_t channel );
  • trunk/kernel/kern/rpc.c

    r450 r457  
    2323
    2424#include <kernel_config.h>
    25 #include <hal_types.h>
     25#include <hal_kernel_types.h>
    2626#include <hal_atomic.h>
    2727#include <hal_remote.h>
     
    100100    volatile error_t   full;
    101101    thread_t         * this;
    102     cluster_t        * cluster;
    103 
    104 #if DEBUG_RPC_CLIENT_GENERIC
    105 uint32_t cycle = (uint32_t)hal_get_cycles();
    106 if( DEBUG_RPC_CLIENT_GENERIC < cycle )
    107 printk("\n[DBG] %s : thread %x in cluster %x enter for rpc[%d] / rpc_ptr %x / cycle %d\n",
    108 __FUNCTION__, CURRENT_THREAD, local_cxy, rpc->index, rpc, cycle );
    109 #endif
    110102
    111103    full            = 0;
    112104    this            = CURRENT_THREAD;
    113     cluster         = LOCAL_CLUSTER;
    114105    client_core_lid = this->core->lid;
    115106
     107#if DEBUG_RPC_CLIENT_GENERIC
     108uint32_t cycle = (uint32_t)hal_get_cycles();
     109if( DEBUG_RPC_CLIENT_GENERIC < cycle )
     110printk("\n[DBG] %s : thread %x in process %x enter for rpc[%d] / cycle %d\n",
     111__FUNCTION__, this->trdid, this->process->pid, rpc->index, cycle );
     112#endif
     113
    116114    // select a server_core : use client core index if possible / core 0 otherwise
    117     if( client_core_lid < hal_remote_lw( XPTR( server_cxy , &cluster->cores_nr ) ) )
     115    if( client_core_lid < hal_remote_lw( XPTR( server_cxy , &LOCAL_CLUSTER->cores_nr ) ) )
    118116    {
    119117        server_core_lid = client_core_lid;
     
    150148 
    151149    hal_fence();
     150
     151#if DEBUG_RPC_CLIENT_GENERIC
     152cycle = (uint32_t)hal_get_cycles();
     153if( DEBUG_RPC_CLIENT_GENERIC < cycle )
     154printk("\n[DBG] %s : thread %x in process %x / rpc[%d] / rpc_ptr %x / cycle %d\n",
     155__FUNCTION__, this->trdid, this->process->pid, rpc->index, rpc, cycle );
     156#endif
    152157       
    153     // send IPI to the selected server core
    154         dev_pic_send_ipi( server_cxy , server_core_lid );
     158   // send IPI to the selected server core
     159   dev_pic_send_ipi( server_cxy , server_core_lid );
    155160
    156161    // wait RPC completion before returning if blocking RPC
     
    165170cycle = (uint32_t)hal_get_cycles();
    166171if( DEBUG_RPC_CLIENT_GENERIC < cycle )
    167 printk("\n[DBG] %s : thread %x in cluster %x busy waiting / rpc[%d] / cycle %d\n",
    168 __FUNCTION__, CURRENT_THREAD, local_cxy, rpc->index , cycle );
     172printk("\n[DBG] %s : thread %x in process %x busy waiting for rpc[%d] / cycle %d\n",
     173__FUNCTION__, this->trdid, this->process->pid, rpc->index , cycle );
    169174#endif
    170175
     
    174179cycle = (uint32_t)hal_get_cycles();
    175180if( DEBUG_RPC_CLIENT_GENERIC < cycle )
    176 printk("\n[DBG] %s : thread %x in cluster %x resumes / rpc[%d] / cycle %d\n",
    177 __FUNCTION__, CURRENT_THREAD, local_cxy, rpc->index, cycle );
     181printk("\n[DBG] %s : thread %x in process %x resumes for rpc[%d] / cycle %d\n",
     182__FUNCTION__, this->trdid, this->process->pid, rpc->index, cycle );
    178183#endif
    179184        }
     
    184189cycle = (uint32_t)hal_get_cycles();
    185190if( DEBUG_RPC_CLIENT_GENERIC < cycle )
    186 printk("\n[DBG] %s : thread %x in cluster %x blocks & deschedules / rpc[%d] / cycle %d\n",
    187 __FUNCTION__, CURRENT_THREAD, local_cxy, rpc->index , cycle );
     191printk("\n[DBG] %s : thread %x in process %x blocks & deschedules for rpc[%d] / cycle %d\n",
     192__FUNCTION__, this->trdid, this->process->pid, rpc->index , cycle );
    188193#endif
    189194            thread_block( XPTR( local_cxy , this ) , THREAD_BLOCKED_RPC );
     
    193198cycle = (uint32_t)hal_get_cycles();
    194199if( DEBUG_RPC_CLIENT_GENERIC < cycle )
    195 printk("\n[DBG] %s : thread %x in cluster %x resumes / rpcr[%d] / cycle %d\n",
    196 __FUNCTION__, CURRENT_THREAD, local_cxy, rpc->index, cycle );
     200printk("\n[DBG] %s : thread %x in process %x resumes for rpc[%d] / cycle %d\n",
     201__FUNCTION__, this->trdid, this->process->pid, rpc->index, cycle );
    197202#endif
    198203        }
     
    207212cycle = (uint32_t)hal_get_cycles();
    208213if( DEBUG_RPC_CLIENT_GENERIC < cycle )
    209 printk("\n[DBG] %s : non blocking rpc[%d] => thread %x return / cycle %d\n",
    210 __FUNCTION__, rpc->index, CURRENT_THREAD, cycle );
     214printk("\n[DBG] %s : thread %x in process %x returns for non blocking rpc[%d] / cycle %d\n",
     215__FUNCTION__, this->trdid, this->process->pid, rpc->index, cycle );
    211216#endif
    212217
     
    225230    thread_t      * thread; 
    226231    uint32_t        sr_save;
     232
     233#if DEBUG_RPC_SERVER_GENERIC
     234uint32_t cycle;
     235#endif
    227236
    228237    bool_t          found    = false;
     
    232241        remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo[core->lid];
    233242
    234 #if DEBUG_RPC_SERVER_GENERIC
    235 uint32_t cycle = (uint32_t)hal_get_cycles();
    236 if( DEBUG_RPC_SERVER_GENERIC < cycle )
    237 printk("\n[DBG] %s : thread %x interrupted in cluster %x / cycle %d\n",
    238 __FUNCTION__, this, local_cxy, cycle );
    239 #endif
    240 
    241243    // interrupted thread not preemptable during RPC chek
    242244        hal_disable_irq( &sr_save );
     
    249251cycle = (uint32_t)hal_get_cycles();
    250252if( DEBUG_RPC_SERVER_GENERIC < cycle )
    251 printk("\n[DBG] %s : RPC FIFO non empty in cluster %x / cycle %d\n",
    252 __FUNCTION__, local_cxy, cycle );
     253printk("\n[DBG] %s : RPC FIFO non empty for core[%x,%d] / cycle %d\n",
     254__FUNCTION__, local_cxy, core->lid, cycle );
    253255#endif
    254256
     
    290292cycle = (uint32_t)hal_get_cycles();
    291293if( DEBUG_RPC_SERVER_GENERIC < cycle )
    292 printk("\n[DBG] %s : create a new RPC thread %x in cluster %x / cycle %d\n",
    293 __FUNCTION__, thread, local_cxy, cycle );
     294printk("\n[DBG] %s : new RPC thread %x created for core[%x,%d] / cycle %d\n",
     295__FUNCTION__, thread, local_cxy, core->lid, cycle );
    294296#endif
    295297        }
     
    299301cycle = (uint32_t)hal_get_cycles();
    300302if( DEBUG_RPC_SERVER_GENERIC < cycle )
    301 printk("\n[DBG] %s : interrupted thread %x deschedules in cluster %x / cycle %d\n",
    302 __FUNCTION__, this, local_cxy, cycle );
     303printk("\n[DBG] %s : interrupted thread %x deschedules on core[%x,%d] / cycle %d\n",
     304__FUNCTION__, this, local_cxy, core->lid, cycle );
    303305#endif
    304306
     
    309311cycle = (uint32_t)hal_get_cycles();
    310312if( DEBUG_RPC_SERVER_GENERIC < cycle )
    311 printk("\n[DBG] %s : interrupted thread %x resumes in cluster %x / cycle %d\n",
    312 __FUNCTION__, this, local_cxy, cycle );
     313printk("\n[DBG] %s : interrupted thread %x resumes on core[%x,%d] / cycle %d\n",
     314__FUNCTION__, this, local_cxy, core->lid, cycle );
    313315#endif
    314316
     
    410412#endif
    411413                        // send IPI to client core
    412                             dev_pic_send_ipi( desc_cxy , client_core_lid );
     414                            // dev_pic_send_ipi( desc_cxy , client_core_lid );
    413415                    }
    414416                        }
     
    872874pid_t     pid    = rpc->args[1];
    873875if( DEBUG_RPC_PROCESS_SIGACTION < cycle )
    874 printk("\n[DBG] %s : enter to %s process %x in cluster %x / cycle %d\n",
     876printk("\n[DBG] %s : enter to request %s of process %x in cluster %x / cycle %d\n",
    875877__FUNCTION__ , process_action_str( action ) , pid , cxy , cycle );
    876878#endif
     
    949951
    950952        // send an IPI to client core
    951         dev_pic_send_ipi( client_cxy , client_lid );
     953        // dev_pic_send_ipi( client_cxy , client_lid );
    952954    }
    953955
  • trunk/kernel/kern/rpc.h

    r450 r457  
    2626
    2727#include <kernel_config.h>
    28 #include <hal_types.h>
     28#include <hal_kernel_types.h>
    2929#include <hal_atomic.h>
    3030#include <bits.h>
  • trunk/kernel/kern/scheduler.c

    r450 r457  
    2323
    2424#include <kernel_config.h>
    25 #include <hal_types.h>
     25#include <hal_kernel_types.h>
    2626#include <hal_switch.h>
    2727#include <hal_irqmask.h>
  • trunk/kernel/kern/scheduler.h

    r450 r457  
    2525#define _SCHEDULER_H_
    2626
    27 #include <hal_types.h>
     27#include <hal_kernel_types.h>
    2828#include <list.h>
    2929#include <spinlock.h>
  • trunk/kernel/kern/signal.c

    r409 r457  
    2424 */
    2525
    26 #include <hal_types.h>
     26#include <hal_kernel_types.h>
    2727#include <printk.h>
    2828#include <signal.h>
  • trunk/kernel/kern/signal.h

    r435 r457  
    2727#define _SIGNAL_H_
    2828
    29 #include <hal_types.h>
     29#include <hal_kernel_types.h>
    3030
    3131
  • trunk/kernel/kern/thread.c

    r450 r457  
    2424
    2525#include <kernel_config.h>
    26 #include <hal_types.h>
     26#include <hal_kernel_types.h>
    2727#include <hal_context.h>
    2828#include <hal_irqmask.h>
     
    167167    thread->quantum         = 0;            // TODO
    168168    thread->ticks_nr        = 0;            // TODO
    169     thread->time_last_check = 0;
     169    thread->time_last_check = 0;            // TODO
    170170        thread->core            = &local_cluster->core_tbl[core_lid];
    171171        thread->process         = process;
     
    243243uint32_t cycle = (uint32_t)hal_get_cycles();
    244244if( DEBUG_THREAD_USER_CREATE < cycle )
    245 printk("\n[DBG] %s : thread %x enter for process %x in cluster %x / cycle %d\n",
    246 __FUNCTION__, CURRENT_THREAD, pid , local_cxy , cycle );
     245printk("\n[DBG] %s : thread %x in process %x enter in cluster %x / cycle %d\n",
     246__FUNCTION__, CURRENT_THREAD->trdid, pid , local_cxy , cycle );
    247247#endif
    248248
     
    301301    }
    302302
     303#if( DEBUG_THREAD_USER_CREATE & 1)
     304if( DEBUG_THREAD_USER_CREATE < cycle )
     305printk("\n[DBG] %s : stack vseg created / vpn_base %x / %d pages\n",
     306__FUNCTION__, vseg->vpn_base, vseg->vpn_size );
     307#endif
     308
    303309    // allocate memory for thread descriptor
    304310    thread = thread_alloc();
     
    313319#if( DEBUG_THREAD_USER_CREATE & 1)
    314320if( DEBUG_THREAD_USER_CREATE < cycle )
    315 printk("\n[DBG] %s : thread descriptor %x allocated\n",
     321printk("\n[DBG] %s : new thread descriptor %x allocated\n",
    316322__FUNCTION__, thread );
    317323#endif
     
    336342#if( DEBUG_THREAD_USER_CREATE & 1)
    337343if( DEBUG_THREAD_USER_CREATE < cycle )
    338 printk("\n[DBG] %s : thread descriptor %x initialised / trdid = %x\n",
    339 __FUNCTION__, thread , thread->trdid );
     344printk("\n[DBG] %s : new thread descriptor initialised / trdid %x\n",
     345__FUNCTION__, thread->trdid );
    340346#endif
    341347
     
    347353
    348354    // allocate & initialize CPU context
    349         if( hal_cpu_context_create( thread ) )
     355        if( hal_cpu_context_alloc( thread ) )
    350356    {
    351357            printk("\n[ERROR] in %s : cannot create CPU context\n", __FUNCTION__ );
     
    354360        return ENOMEM;
    355361    }
    356 
    357     // allocate  FPU context
     362    hal_cpu_context_init( thread );
     363
     364    // allocate & initialize FPU context
    358365    if( hal_fpu_context_alloc( thread ) )
    359366    {
     
    363370        return ENOMEM;
    364371    }
     372    hal_fpu_context_init( thread );
     373
     374#if( DEBUG_THREAD_USER_CREATE & 1)
     375if( DEBUG_THREAD_USER_CREATE < cycle )
     376printk("\n[DBG] %s : CPU & FPU contexts created\n",
     377__FUNCTION__, thread->trdid );
     378vmm_display( process , true );
     379#endif
    365380
    366381#if DEBUG_THREAD_USER_CREATE
    367382cycle = (uint32_t)hal_get_cycles();
    368383if( DEBUG_THREAD_USER_CREATE < cycle )
    369 printk("\n[DBG] %s : thread %x exit / new_thread %x in process %x / core %d / cycle %d\n",
    370 __FUNCTION__, CURRENT_THREAD, thread->trdid , pid , core_lid, cycle );
     384printk("\n[DBG] %s : thread %x in process %x exit / new_thread %x / core %d / cycle %d\n",
     385__FUNCTION__, CURRENT_THREAD->trdid , pid, thread->trdid, core_lid, cycle );
    371386#endif
    372387
     
    554569}  // end thread_user_fork()
    555570
     571////////////////////////////////////////////////
     572error_t thread_user_exec( void     * entry_func,
     573                          uint32_t   argc,
     574                          char    ** argv )
     575{
     576    thread_t  * thread  = CURRENT_THREAD;
     577    process_t * process = thread->process;
     578
     579#if DEBUG_THREAD_USER_EXEC
     580uint32_t cycle = (uint32_t)hal_get_cycles();
     581if( DEBUG_THREAD_USER_EXEC < cycle )
     582printk("\n[DBG] %s : thread %x in process %x enter / cycle %d\n",
     583__FUNCTION__, thread->trdid, process->pid, cycle );
     584#endif
     585
     586        assert( (thread->type == THREAD_USER )          , __FUNCTION__, "bad type" );
     587        assert( (thread->signature == THREAD_SIGNATURE) , __FUNCTION__, "bad signature" );
     588        assert( (thread->local_locks == 0)              , __FUNCTION__, "bad local locks" );
     589        assert( (thread->remote_locks == 0)             , __FUNCTION__, "bad remote locks" );
     590
     591        // re-initialize various thread descriptor fields
     592    thread->quantum         = 0;            // TODO
     593    thread->ticks_nr        = 0;            // TODO
     594    thread->time_last_check = 0;            // TODO
     595
     596#if CONFIG_LOCKS_DEBUG
     597    list_root_init( &thread->locks_root ); 
     598    xlist_root_init( XPTR( local_cxy , &thread->xlocks_root ) );
     599#endif
     600
     601    thread->entry_func      = entry_func;
     602    thread->main_argc       = argc;
     603    thread->main_argv       = argv;
     604
     605    // the main thread is always detached
     606    thread->flags           = THREAD_FLAG_DETACHED;
     607    thread->blocked         = 0;
     608    thread->errno           = 0;
     609    thread->fork_user       = 0;    // not inherited
     610    thread->fork_cxy        = 0;    // not inherited
     611
     612    // reset thread info
     613    memset( &thread->info , 0 , sizeof(thread_info_t) );
     614
     615    // initialize join_lock
     616    remote_spinlock_init( XPTR( local_cxy , &thread->join_lock ) );
     617
     618    // allocate an user stack vseg for main thread
     619    vseg_t * vseg = vmm_create_vseg( process,
     620                                     VSEG_TYPE_STACK,
     621                                     0,                 // size unused
     622                                     0,                 // length unused
     623                                     0,                 // file_offset unused
     624                                     0,                 // file_size unused
     625                                     XPTR_NULL,         // mapper_xp unused
     626                                     local_cxy );
     627    if( vseg == NULL )
     628    {
     629            printk("\n[ERROR] in %s : cannot create stack vseg for main thread\n", __FUNCTION__ );
     630                return -1;
     631    }
     632
     633    // update user stack in stack descriptor
     634    thread->u_stack_base = vseg->min;
     635    thread->u_stack_size = vseg->max - vseg->min;
     636   
     637    // release FPU ownership if required
     638    if( thread->core->fpu_owner == thread ) thread->core->fpu_owner = NULL;
     639
     640    // re-initialize  FPU context
     641    hal_fpu_context_init( thread );
     642
     643#if DEBUG_THREAD_USER_EXEC
     644cycle = (uint32_t)hal_get_cycles();
     645if( DEBUG_THREAD_USER_EXEC < cycle )
     646printk("\n[DBG] %s : thread %x in process %x set CPU context & jump to user code / cycle %d\n",
     647__FUNCTION__, thread->trdid, process->pid, cycle );
     648vmm_display( process , true );
     649#endif
     650
     651    // re-initialize CPU context... and jump to user code
     652        hal_cpu_context_exec( thread );
     653
     654    assert( false, __FUNCTION__, "we should execute this code");
     655 
     656    return 0;
     657
     658}  // end thread_user_exec()
     659
    556660/////////////////////////////////////////////////////////
    557661error_t thread_kernel_create( thread_t     ** new_thread,
     
    594698    {
    595699        thread_release( thread );
     700        return ENOMEM;
     701    }
     702
     703    // allocate & initialize CPU context
     704        error = hal_cpu_context_alloc( thread );
     705    if( error )
     706    {
     707        thread_release( thread );
    596708        return EINVAL;
    597709    }
    598 
    599     // allocate & initialize CPU context
    600         hal_cpu_context_create( thread );
     710    hal_cpu_context_init( thread );
     711
    601712
    602713#if DEBUG_THREAD_KERNEL_CREATE
     
    612723} // end thread_kernel_create()
    613724
    614 /////////////////////////////////////////////////
    615 error_t thread_idle_init( thread_t      * thread,
    616                           thread_type_t   type,
    617                           void          * func,
    618                           void          * args,
    619                                           lid_t           core_lid )
     725//////////////////////////////////////////////
     726void thread_idle_init( thread_t      * thread,
     727                       thread_type_t   type,
     728                       void          * func,
     729                       void          * args,
     730                           lid_t           core_lid )
    620731{
    621732    assert( (type == THREAD_IDLE) , __FUNCTION__ , "illegal thread type" );
    622 
    623733    assert( (core_lid < LOCAL_CLUSTER->cores_nr) , __FUNCTION__ , "illegal core index" );
    624734
     735    // initialize thread descriptor
    625736    error_t  error = thread_init( thread,
    626737                                  &process_zero,
     
    631742                                  0 , 0 );   // no user stack for a kernel thread
    632743
     744    assert( (error == 0), __FUNCTION__, "cannot create thread idle" );
     745
    633746    // allocate & initialize CPU context if success
    634     if( error == 0 ) hal_cpu_context_create( thread );
    635 
    636     return error;
     747    error = hal_cpu_context_alloc( thread );
     748
     749    assert( (error == 0), __FUNCTION__, "cannot allocate CPU context" );
     750
     751    hal_cpu_context_init( thread );
    637752
    638753}  // end thread_idle_init()
     
    798913
    799914#if DEBUG_THREAD_BLOCK
    800 uint32_t cycle = (uint32_t)hal_get_cycles();
     915uint32_t    cycle   = (uint32_t)hal_get_cycles();
     916process_t * process = hal_remote_lpt( XPTR( cxy , &ptr->process ) );
    801917if( DEBUG_THREAD_BLOCK < cycle )
    802 printk("\n[DBG] %s : thread %x  in cxy %x blocked thread %x in cxy %x / cause %x / cycle %d\n",
    803 __FUNCTION__ , CURRENT_THREAD , local_cxy , ptr , cxy , cause , cycle );
     918printk("\n[DBG] %s : thread %x in process %x blocked thread %x in process %x / cause %x\n",
     919__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid,
     920ptr->trdid, hal_remote_lw(XPTR( cxy , &process->pid )), cause );
    804921#endif
    805922
     
    819936
    820937#if DEBUG_THREAD_BLOCK
    821 uint32_t cycle = (uint32_t)hal_get_cycles();
     938uint32_t    cycle   = (uint32_t)hal_get_cycles();
     939process_t * process = hal_remote_lpt( XPTR( cxy , &ptr->process ) );
    822940if( DEBUG_THREAD_BLOCK < cycle )
    823 printk("\n[DBG] %s : thread %x  in cxy %x unblocked thread %x in cxy %x / cause %x / cycle %d\n",
    824 __FUNCTION__ , CURRENT_THREAD , local_cxy , ptr , cxy , cause , cycle );
     941printk("\n[DBG] %s : thread %x in process %x unblocked thread %x in process %x / cause %x\n",
     942__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid,
     943ptr->trdid, hal_remote_lw(XPTR( cxy , &process->pid )), cause );
    825944#endif
    826945
  • trunk/kernel/kern/thread.h

    r446 r457  
    2626#define _THREAD_H_
    2727
    28 #include <hal_types.h>
     28#include <hal_kernel_types.h>
    2929#include <shared_syscalls.h>
    3030#include <hal_special.h>
     
    161161    void              * entry_func;      /*! pointer on entry function                */
    162162    void              * entry_args;      /*! pointer on entry function arguments      */
     163    uint32_t            main_argc;       /*! main thread number of arguments          */
     164    char             ** main_argv;       /*! main thread array of strings arguments   */
    163165
    164166    uint32_t            flags;           /*! bit vector of flags                      */
     
    218220 * The CPU context is initialized from scratch.
    219221 * It is registered in the local process descriptor specified by the <pid> argument.
    220  * The THREAD_BLOCKED_GLOBAL bit is set => the thread must be activated to start.
     222 * The THREAD_BLOCKED_GLOBAL bit is set => the thread must be activated by the caller
     223 * to start at the next scheduling point.
    221224 ***************************************************************************************
    222225 * @ pid          : process identifier.
     
    258261
    259262/***************************************************************************************
     263 * This function is called by the process_make_exec() function to re-initialise the
     264 * thread descriptor of the calling thread (that will become the new process main
     265 * thread), and immediately jump to user code without returning to kentry!!!
     266 * It must be called by the main thread of the calling process.
     267 * - A new user stack vseg is created and initialised.
     268 * - The kernel stack (currently in use) is not modified. 
     269 * - The function calls the hal_cpu_context_exec() to re-initialize the CPU context
     270 *   an jump to user code. 
     271 ***************************************************************************************
     272 * @ entry_func : main thread entry point.
     273 * @ argc       : number of main thread arguments.
     274 * @ argv       : array of pointers on stringarguments.
     275 * @ returns 0 if success / returns ENOMEM if error.
     276 **************************************************************************************/
     277error_t thread_user_exec( void     * entry_func,
     278                          uint32_t   argc,
     279                          char    ** argv);
     280
     281/***************************************************************************************
    260282 * This function allocates memory for a kernel thread descriptor in the local cluster,
    261283 * and initializes it from arguments values.
     
    281303 * descriptor from arguments values.
    282304 * The THREAD_BLOCKED_GLOBAL bit is set, and the thread must be activated to start.
     305 * It returns a kernel panic if failure.
    283306 ***************************************************************************************
    284307 * @ thread   : pointer on existing thread descriptor.
     
    287310 * @ args     : function arguments.
    288311 * @ core_lid : local core index.
    289  * @ returns 0 if success / returns EINVAL if error
    290  **************************************************************************************/
    291 error_t thread_idle_init( thread_t      * thread,
    292                           thread_type_t   type,
    293                           void          * func,
    294                           void          * args,
    295                           lid_t           core_lid );
     312 **************************************************************************************/
     313void thread_idle_init( thread_t      * thread,
     314                       thread_type_t   type,
     315                       void          * func,
     316                       void          * args,
     317                       lid_t           core_lid );
    296318
    297319/***************************************************************************************
Note: See TracChangeset for help on using the changeset viewer.