Ignore:
Timestamp:
Nov 19, 2020, 11:44:34 PM (3 years ago)
Author:
alain
Message:

1) Introduce up to 4 command lines arguments in the KSH "load" command.
These arguments are transfered to the user process through the
argc/argv mechanism, using the user space "args" vseg.

2) Introduce the named and anonymous "pipes", for inter-process communication
through the pipe() and mkfifo() syscalls.

3) Introduce the "chat" application to validate the two above mechanisms.

4) Improve printk() and assert() fonctions in printk.c.

File:
1 edited

Legend:

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

    r662 r669  
    4141#include <thread.h>
    4242#include <chdev.h>
     43#include <ksocket.h>
    4344#include <list.h>
    4445#include <string.h>
     
    7273process_t * process_alloc( void )
    7374{
     75
     76assert( __FUNCTION__, (sizeof(process_t) < CONFIG_PPM_PAGE_SIZE),
     77"process descriptor exceeds 1 page" );
     78
    7479        kmem_req_t req;
    7580
    76     req.type  = KMEM_KCM;
    77         req.order = bits_log2( sizeof(process_t) );
    78         req.flags = AF_KERNEL;
    79 
     81    req.type  = KMEM_PPM;
     82        req.order = 0;
     83        req.flags = AF_KERNEL | AF_ZERO;
    8084    return kmem_alloc( &req );
    8185}
     
    8690    kmem_req_t  req;
    8791
    88         req.type = KMEM_KCM;
     92        req.type = KMEM_PPM;
    8993        req.ptr  = process;
    9094        kmem_free( &req );
     
    109113    char        rx_path[40];
    110114    char        tx_path[40];
    111     xptr_t      file_xp;
    112     xptr_t      chdev_xp;
    113     chdev_t   * chdev_ptr;
    114     cxy_t       chdev_cxy;
    115115    pid_t       parent_pid;
    116116    vmm_t     * vmm;
     
    211211
    212212        // attach process to TXT
    213         process_txt_attach( process , txt_id );
     213        process_txt_attach( process_xp , txt_id );
    214214
    215215#if (DEBUG_PROCESS_REFERENCE_INIT & 1)
     
    220220#endif
    221221        // build path to TXT_RX[i] and TXT_TX[i] chdevs
    222         snprintf( rx_path , 40 , "/dev/external/txt%d_rx", txt_id );
    223         snprintf( tx_path , 40 , "/dev/external/txt%d_tx", txt_id );
     222        snprintk( rx_path , 40 , "/dev/external/txt%d_rx", txt_id );
     223        snprintk( tx_path , 40 , "/dev/external/txt%d_tx", txt_id );
    224224
    225225        // create stdin pseudo file         
     
    237237        }
    238238
    239 assert( (stdin_id == 0) , "stdin index must be 0" );
     239assert( __FUNCTION__, (stdin_id == 0) , "stdin index must be 0" );
    240240
    241241#if (DEBUG_PROCESS_REFERENCE_INIT & 1)
     
    260260        }
    261261
    262 assert( (stdout_id == 1) , "stdout index must be 1" );
     262assert( __FUNCTION__, (stdout_id == 1) , "stdout index must be 1" );
    263263
    264264#if (DEBUG_PROCESS_REFERENCE_INIT & 1)
     
    283283        }
    284284
    285 assert( (stderr_id == 2) , "stderr index must be 2" );
     285assert( __FUNCTION__, (stderr_id == 2) , "stderr index must be 2" );
    286286
    287287#if (DEBUG_PROCESS_REFERENCE_INIT & 1)
     
    295295    else                                            // normal user process
    296296    {
    297         // get extended pointer on stdin pseudo file in parent process
    298         file_xp = (xptr_t)hal_remote_l64( XPTR( parent_cxy,
    299                                                 &parent_ptr->fd_array.array[0] ) );
    300 
    301         // get extended pointer on parent process TXT chdev
    302         chdev_xp = chdev_from_file( file_xp );
    303  
    304         // get cluster and local pointer on chdev
    305         chdev_cxy = GET_CXY( chdev_xp );
    306         chdev_ptr = GET_PTR( chdev_xp );
    307  
    308         // get parent process TXT terminal index
    309         txt_id = hal_remote_l32( XPTR( chdev_cxy , &chdev_ptr->channel ) );
    310 
    311         // attach child process to parent process TXT terminal
    312         process_txt_attach( process , txt_id );
    313 
    314         // copy all open files from parent process fd_array to this process
    315         process_fd_remote_copy( XPTR( local_cxy , &process->fd_array ),
    316                                 XPTR( parent_cxy , &parent_ptr->fd_array ) );
     297        // get parent process TXT index
     298        txt_id = process_txt_get_index( parent_xp );
     299
     300        // attach child process to same TXT terminal as parent
     301        process_txt_attach( process_xp , txt_id );
     302
     303        // recreate all open files from parent process fd_array to child process fd_array
     304        process_fd_replicate( process_xp , parent_xp );
    317305    }
    318306
    319307    // initialize lock protecting CWD changes
    320     remote_busylock_init( XPTR( local_cxy ,
    321                                 &process->cwd_lock ), LOCK_PROCESS_CWD );
     308    remote_busylock_init( XPTR( local_cxy , &process->cwd_lock ), LOCK_PROCESS_CWD );
    322309
    323310#if (DEBUG_PROCESS_REFERENCE_INIT & 1)
     
    415402
    416403// check user process
    417 assert( (local_process->pid != 0), "LPID cannot be 0" );
     404assert( __FUNCTION__, (local_process->pid != 0), "LPID cannot be 0" );
    418405
    419406    // initialize VSL as empty
     
    520507
    521508// check no more threads
    522 assert( (process->th_nr == 0),
     509assert( __FUNCTION__, (process->th_nr == 0),
    523510"process %x in cluster %x contains threads", pid , local_cxy );
    524511
     
    616603cycle = (uint32_t)hal_get_cycles();
    617604if( DEBUG_PROCESS_DESTROY < cycle )
    618 printk("\n[%s] thread[%x,%x] exit / process %x in cluster %x / cycle %d\n",
     605printk("\n[%s] thread[%x,%x] exit for process %x in cluster %x / cycle %d\n",
    619606__FUNCTION__, this->process->pid, this->trdid, pid, local_cxy, cycle );
    620607#endif
     
    683670
    684671// check action type
    685 assert( ((type == DELETE_ALL_THREADS ) ||
     672assert( __FUNCTION__, ((type == DELETE_ALL_THREADS ) ||
    686673         (type == BLOCK_ALL_THREADS )  ||
    687674         (type == UNBLOCK_ALL_THREADS )), "illegal action type" );
     
    809796
    810797// check target process is an user process
    811 assert( (LPID_FROM_PID( process->pid ) != 0 ),
     798assert( __FUNCTION__, (LPID_FROM_PID( process->pid ) != 0 ),
    812799"process %x is not an user process\n", process->pid );
    813800
     
    894881
    895882// check target process is an user process
    896 assert( (LPID_FROM_PID( process->pid ) != 0),
     883assert( __FUNCTION__, (LPID_FROM_PID( process->pid ) != 0),
    897884"process %x is not an user process\n", process->pid );
    898885
     
    916903            {
    917904                // mark target thread for delete and block it
    918                 thread_delete( target_xp , true );                   // forced
     905                thread_delete_request( target_xp , true );                   // forced
    919906            }
    920907        }
     
    950937
    951938// check target process is an user process
    952 assert( ( LPID_FROM_PID( process->pid ) != 0 ),
     939assert( __FUNCTION__, ( LPID_FROM_PID( process->pid ) != 0 ),
    953940"process %x is not an user process\n", process->pid );
    954941
     
    10271014        xptr_t ref_xp = cluster_get_reference_process_from_pid( pid );
    10281015
    1029         assert( (ref_xp != XPTR_NULL) , "illegal pid\n" );
     1016        assert( __FUNCTION__, (ref_xp != XPTR_NULL) , "illegal pid\n" );
    10301017
    10311018        // allocate memory for local process descriptor
     
    10811068    switch( type )
    10821069    {
    1083         case INODE_TYPE_FILE : return "FILE";
    1084         case INODE_TYPE_DIR  : return "DIR";
    1085         case INODE_TYPE_FIFO : return "FIFO";
    1086         case INODE_TYPE_PIPE : return "PIPE";
    1087         case INODE_TYPE_SOCK : return "SOCK";
    1088         case INODE_TYPE_DEV  : return "DEV";
    1089         case INODE_TYPE_BLK  : return "BLK";
    1090         case INODE_TYPE_SYML : return "SYML";
     1070        case FILE_TYPE_REG : return "FILE";
     1071        case FILE_TYPE_DIR  : return "DIR";
     1072        case FILE_TYPE_FIFO : return "FIFO";
     1073        case FILE_TYPE_PIPE : return "PIPE";
     1074        case FILE_TYPE_SOCK : return "SOCK";
     1075        case FILE_TYPE_DEV  : return "DEV";
     1076        case FILE_TYPE_BLK  : return "BLK";
     1077        case FILE_TYPE_SYML : return "SYML";
    10911078       
    10921079        default              : return "undefined";
     
    11291116
    11301117// check target process is owner process
    1131 assert( (process_xp == hal_remote_l64( XPTR( process_cxy , &process_ptr->owner_xp ) ) ),
     1118assert( __FUNCTION__, (process_xp == hal_remote_l64( XPTR( process_cxy , &process_ptr->owner_xp ) ) ),
    11321119"process must be owner process\n" );
    11331120
     
    11451132    max_xp  = XPTR( process_cxy , &process_ptr->fd_array.max );
    11461133
    1147     // take lock protecting reference fd_array
     1134    // take lock protecting fd_array
    11481135        remote_queuelock_acquire( lock_xp );
    11491136
     
    11581145        entry_xp = hal_remote_l64( XPTR( process_cxy , &process_ptr->fd_array.array[id] ) );
    11591146       
     1147        // take the first empty slot
    11601148        if ( entry_xp == XPTR_NULL )
    11611149        {
     
    11651153            // update max when required
    11661154            if( id > max ) hal_remote_s32( max_xp , id );
    1167 
    1168             // increase file refcount
    1169             vfs_file_count_up( file_xp );
    11701155
    11711156            // exit loop
     
    12081193
    12091194// check target process is owner process
    1210 assert( (process_xp == hal_remote_l64( XPTR( process_cxy , &process_ptr->owner_xp ) ) ),
     1195assert( __FUNCTION__, (process_xp == hal_remote_l64( XPTR( process_cxy , &process_ptr->owner_xp ) ) ),
    12111196"process must be owner process\n" );
    12121197
     
    12531238        // release the fd_array entry in process copy
    12541239        hal_remote_s64( XPTR( copy_cxy , &copy_ptr->fd_array.array[fdid] ), XPTR_NULL );
    1255 
    1256         // decrease file refcount
    1257         vfs_file_count_down( file_xp );
    12581240    }
    12591241
     
    12611243    if( fdid == max ) hal_remote_s32( fd_max_xp , max-1 );
    12621244
    1263     // release the lock protecting reference fd_array
     1245    // release the lock protecting fd_array
    12641246        remote_queuelock_release( fd_lock_xp );
    12651247
     
    12791261void process_fd_clean_all( xptr_t process_xp )
    12801262{
    1281     uint32_t  id;
     1263    uint32_t  fdid;
    12821264    xptr_t    file_xp;         // one fd_array entry
    12831265    xptr_t    lock_xp;         // extendad pointer on lock protecting fd_array
    12841266    uint32_t  max;             // number of registered files
    1285     error_t   error;
    12861267
    12871268    // get process cluster, local pointer and PID
    12881269    process_t * process_ptr = GET_PTR( process_xp );
    12891270    cxy_t       process_cxy = GET_CXY( process_xp );
    1290     pid_t       pid         = hal_remote_l32( XPTR( process_cxy , &process_ptr->pid) );
    12911271
    12921272// check target process is owner process
    1293 assert( (process_xp == hal_remote_l64( XPTR( process_cxy , &process_ptr->owner_xp )) ),
     1273assert( __FUNCTION__, (process_xp == hal_remote_l64( XPTR( process_cxy , &process_ptr->owner_xp )) ),
    12941274"process must be owner process\n" );
    12951275
     
    12981278uint32_t   cycle = (uint32_t)hal_get_cycles();
    12991279if( DEBUG_PROCESS_FD_CLEAN_ALL < cycle )
    1300 printk("\n[%s] thread[%x,%x] enter for process %x / cycle %d\n",
    1301 __FUNCTION__, this->process->pid, this->trdid, pid, cycle );
     1280printk("\n[%s] thread[%x,%x] enter / cycle %d\n",
     1281__FUNCTION__, this->process->pid, this->trdid, cycle );
    13021282
    13031283process_fd_display( process_xp );
     
    13131293        remote_queuelock_acquire( lock_xp );
    13141294
    1315     for ( id = 0; id <= max ; id++ )
     1295    for( fdid = 0 ; fdid <= max ; fdid++ )
    13161296    {
    13171297        // get fd_array entry
    1318         file_xp = hal_remote_l64( XPTR( process_cxy , &process_ptr->fd_array.array[id] ) );
     1298        file_xp = hal_remote_l64( XPTR( process_cxy , &process_ptr->fd_array.array[fdid] ) );
    13191299       
    13201300        if ( file_xp != XPTR_NULL )
    13211301        {
    1322             // close the file or socket
    1323             error = sys_close( id );
    1324 
    1325             if( error )
    1326             printk("/n[ERROR] in %s : cannot close the file %d for process %x\n",
    1327             __FUNCTION__, id, pid );
     1302            vfs_file_t * file_ptr = GET_PTR( file_xp );
     1303            cxy_t        file_cxy = GET_CXY( file_xp );
     1304
     1305            // get file type
     1306            uint32_t file_type = hal_remote_l32( XPTR( file_cxy , &file_ptr->type ));
     1307 
     1308            if( file_type == FILE_TYPE_REG )
     1309            {
     1310                vfs_close( file_xp , fdid );
     1311            }
     1312            if( file_type == FILE_TYPE_SOCK )
     1313            {
     1314                socket_close( file_xp , fdid );
     1315            }
    13281316        }
    13291317    }
     
    13481336    process_t * process_ptr = GET_PTR( process_xp );
    13491337
    1350 assert( (hal_remote_l64( XPTR( process_cxy , &process_ptr->owner_xp )) == process_xp),
     1338assert( __FUNCTION__, (hal_remote_l64( XPTR( process_cxy , &process_ptr->owner_xp )) == process_xp),
    13511339"process_xp argument must be the owner process" );
    13521340
     
    13791367            remote_queuelock_acquire( lock_xp );
    13801368
    1381         // access reference process descriptor
     1369        // access owner process descriptor
    13821370        file_xp = hal_remote_l64( XPTR( owner_cxy , &owner_ptr->fd_array.array[fdid] ) );
    13831371
     
    13861374           // update local fd_array
    13871375            process->fd_array.array[fdid] = file_xp;
    1388        
    1389             // increase file refcount
    1390             vfs_file_count_up( file_xp );
    13911376        }
    13921377
     
    13991384}  // end process_fd_get_xptr_from_local()
    14001385
    1401 ///////////////////////////////////////////
    1402 void process_fd_remote_copy( xptr_t dst_xp,
    1403                              xptr_t src_xp )
    1404 {
    1405     uint32_t fd;
    1406     xptr_t   entry;
    1407 
    1408     // get cluster and local pointer for src fd_array
    1409     cxy_t        src_cxy = GET_CXY( src_xp );
    1410     fd_array_t * src_ptr = GET_PTR( src_xp );
    1411 
    1412     // get cluster and local pointer for dst fd_array
    1413     cxy_t        dst_cxy = GET_CXY( dst_xp );
    1414     fd_array_t * dst_ptr = GET_PTR( dst_xp );
     1386/////////////////////////////////////////
     1387void process_fd_replicate( xptr_t dst_xp,
     1388                           xptr_t src_xp )
     1389{
     1390    uint32_t fdid;      // current file descriptor index
     1391    xptr_t   old_xp;    // extended pointer on a file descriptor (stored in SRC fd_array)
     1392    xptr_t   new_xp;    // extended pointer on a file descriptor (stored in DST fd_array)
     1393    error_t  error;
     1394
     1395    // get cluster and local pointer for SRC process
     1396    cxy_t       src_cxy = GET_CXY( src_xp );
     1397    process_t * src_ptr = GET_PTR( src_xp );
     1398
     1399assert( __FUNCTION__, (src_xp == hal_remote_l64( XPTR( src_cxy , &src_ptr->owner_xp ))),
     1400"src_xp process not in owner cluster" );
     1401
     1402    // get cluster and local pointer for DST fd_array
     1403    cxy_t       dst_cxy = GET_CXY( dst_xp );
     1404    process_t * dst_ptr = GET_PTR( dst_xp );
     1405
     1406assert( __FUNCTION__, (dst_xp == hal_remote_l64( XPTR( dst_cxy , &dst_ptr->owner_xp ))),
     1407"dst_xp process not in owner cluster" );
     1408
     1409    // build extende pointers on SRC fd_array lock and max fields
     1410    xptr_t  src_lock_xp = XPTR( src_cxy , &src_ptr->fd_array.lock );
     1411    xptr_t  src_max_xp  = XPTR( src_cxy , &src_ptr->fd_array.max );
    14151412
    14161413    // get the remote lock protecting the src fd_array
    1417         remote_queuelock_acquire( XPTR( src_cxy , &src_ptr->lock ) );
    1418 
    1419     // loop on all fd_array entries
    1420     for( fd = 0 ; fd < CONFIG_PROCESS_FILE_MAX_NR ; fd++ )
     1414        remote_queuelock_acquire( src_lock_xp );
     1415 
     1416    // loop on fd_array entries
     1417    for( fdid = 0 ; fdid <= hal_remote_l32( src_max_xp ) ; fdid++ )
    14211418        {
    1422                 entry = (xptr_t)hal_remote_l64( XPTR( src_cxy , &src_ptr->array[fd] ) );
    1423 
    1424                 if( entry != XPTR_NULL )
     1419                old_xp = (xptr_t)hal_remote_l64( XPTR( src_cxy , &src_ptr->fd_array.array[fdid] ) );
     1420
     1421                if( old_xp != XPTR_NULL )
    14251422                {
    1426             // increment file descriptor refcount
    1427             vfs_file_count_up( entry );
    1428 
    1429                         // copy entry in destination process fd_array
    1430                         hal_remote_s64( XPTR( dst_cxy , &dst_ptr->array[fd] ) , entry );
     1423            // get the existing file descriptor cluster and local pointer
     1424            vfs_file_t * old_ptr = GET_PTR( old_xp );
     1425            cxy_t        old_cxy = GET_CXY( old_xp );
     1426
     1427            // get existing file attributes and local pointer on inode
     1428            uint32_t      attr      = hal_remote_l32( XPTR( old_cxy , &old_ptr->attr ) );
     1429            vfs_inode_t * inode_ptr = hal_remote_lpt( XPTR( old_cxy , &old_ptr->inode ) );
     1430
     1431            // create a new file descriptor in same cluster as the existing one
     1432            error = vfs_file_create( XPTR( old_cxy , inode_ptr ),
     1433                                     attr,
     1434                                     &new_xp );
     1435            if( error )
     1436            {
     1437                printk("\n[ERROR] in %s : cannot create new file\n", __FUNCTION__ );
     1438                return;
     1439            }
     1440
     1441                        // register new_xp in DST fd_array
     1442                        hal_remote_s64( XPTR( dst_cxy , &dst_ptr->fd_array.array[fdid] ) , new_xp );
    14311443                }
    14321444        }
    14331445
    14341446    // release lock on source process fd_array
    1435         remote_queuelock_release( XPTR( src_cxy , &src_ptr->lock ) );
    1436 
    1437 }  // end process_fd_remote_copy()
     1447        remote_queuelock_release( src_lock_xp );
     1448
     1449}  // end process_fd_replicate()
    14381450
    14391451
     
    14971509            file_type = hal_remote_l32( XPTR( file_cxy , &file_ptr->type ));
    14981510
    1499             // get file name for a true file
    1500             if( file_type == INODE_TYPE_FILE )
     1511            // get file name if inode exist
     1512            if( (file_type != FILE_TYPE_PIPE) && (file_type != FILE_TYPE_SOCK) )
    15011513            {
    15021514                // get inode pointers
     
    15071519                vfs_inode_get_name( inode_xp , name );
    15081520
    1509                 // display relevant file decriptor info
    1510                 printk(" - %d : type %s (%s)\n",
    1511                 fdid , process_fd_type_str(file_type), name );
     1521                // display relevant file descriptor info
     1522                printk(" - %d : type %s / ptr %x (%s)\n",
     1523                fdid, process_fd_type_str(file_type), file_ptr, name );
    15121524            }
    1513             else
     1525            else    // PIPE or SOCK types
    15141526            {
    15151527                // display relevant file decriptor info
    1516                 printk(" - %d : type %s\n",
    1517                 fdid , process_fd_type_str(file_type) );
     1528                printk(" - %d : type %s / ptr %x\n",
     1529                fdid , process_fd_type_str(file_type), file_ptr );
    15181530            }
    15191531        }
    15201532        else
    15211533        {
    1522             // display relevant file decriptor info
    15231534            printk(" - %d : empty slot\n",
    15241535            fdid );
     
    15401551 
    15411552// check arguments
    1542 assert( (process != NULL) , "process argument is NULL" );
    1543 assert( (thread != NULL) , "thread argument is NULL" );
     1553assert( __FUNCTION__, (process != NULL) , "process argument is NULL" );
     1554assert( __FUNCTION__, (thread != NULL) , "thread argument is NULL" );
    15441555
    15451556    // get the lock protecting th_tbl for all threads
     
    15801591
    15811592// check thread
    1582 assert( (thread != NULL) , "thread argument is NULL" );
     1593assert( __FUNCTION__, (thread != NULL) , "thread argument is NULL" );
    15831594
    15841595    process_t * process = thread->process;
     
    15941605
    15951606// check th_nr value
    1596 assert( (count > 0) , "process th_nr cannot be 0" );
     1607assert( __FUNCTION__, (count > 0) , "process th_nr cannot be 0" );
    15971608
    15981609    // remove thread from th_tbl[]
     
    16331644
    16341645// check parent process is the reference process
    1635 assert( (parent_process_xp == ref_xp ) ,
     1646assert( __FUNCTION__, (parent_process_xp == ref_xp ) ,
    16361647"parent process must be the reference process" );
    16371648
     
    17111722cycle = (uint32_t)hal_get_cycles();
    17121723if( DEBUG_PROCESS_MAKE_FORK < cycle )
    1713 printk("\n[%s] thread[%x,%x] copied VMM from parent to child / cycle %d\n",
    1714 __FUNCTION__, pid, trdid, cycle );
    1715 hal_vmm_display( XPTR( local_cxy , process ) , true );
     1724{
     1725    printk("\n[%s] thread[%x,%x] copied VMM from parent to child / cycle %d\n",
     1726    __FUNCTION__, pid, trdid, cycle );
     1727    hal_vmm_display( XPTR( local_cxy , process ) , true );
     1728}
    17161729#endif
    17171730
     
    17481761
    17491762// check main thread LTID
    1750 assert( (LTID_FROM_TRDID(thread->trdid) == 0) ,
     1763assert( __FUNCTION__, (LTID_FROM_TRDID(thread->trdid) == 0) ,
    17511764"main thread must have LTID == 0" );
    17521765
     
    18061819}   // end process_make_fork()
    18071820
    1808 /////////////////////////////////////////////////////
    1809 error_t process_make_exec( exec_info_t  * exec_info )
    1810 {
    1811     thread_t       * thread;                  // local pointer on this thread
     1821////////////////////////////////////////////////i//////////////////////////////////////
     1822// This static function is called by the thread_user_exec() function :
     1823// - to register the main() arguments (args) in the <exec_info> structure.
     1824// - to register the environment variables (envs) in the <exec_info> structure.
     1825// In both cases the input is an array of NULL terminated string pointers in user
     1826// space, and the strings can be dispatched anywhere in the user process space.
     1827// This array of pointers is defined by the <u_pointers> argument. The empty slots
     1828// contain the NULL value, and the N non-empty slots are indexed from 0 to (N-1).
     1829// - The max number of envs, and the max number of args are defined by the
     1830//   CONFIG_PROCESS_ARGS_NR and CONFIG_PROCESS_ENVS_MAX_NR parameters.
     1831// - The numbers of pages to store the (args) and (envs) strings are defined by the
     1832//   CONFIG_VMM_ENVS_SIZE and CONFIG_VMM_STACK_SIZE parameters.
     1833///////////////////////////////////////////////////////////////////////////////////////
     1834// Implementation note:
     1835// It allocates a kernel buffer to store a kernel copy of both the array of pointers,
     1836// and the strings. It set the pointers and copies the strings in this kernel buffer.
     1837// Finally, it registers the buffer & the actual number of strings in the process
     1838// exec_info structure  (defined in the <process.h> file).
     1839///////////////////////////////////////////////////////////////////////////////////////
     1840// @ is_args     : [in]    true if called for (args) / false if called for (envs).
     1841// @ u_pointers  : [in]    array of pointers on the strings (in user space).
     1842// @ exec_info   : [out]   pointer on the exec_info structure.
     1843// @ return 0 if success / non-zero if too many strings or no memory.
     1844///////////////////////////////////////////////////////////////////////////////////////
     1845error_t process_exec_get_strings( bool_t         is_args,
     1846                                  char        ** u_pointers,
     1847                                  exec_info_t  * exec_info )
     1848{
     1849    uint32_t     index;           // slot index in pointers array
     1850    uint32_t     length;          // string length (in bytes)
     1851    uint32_t     pointers_bytes;  // number of bytes to store pointers
     1852    uint32_t     max_index;       // max size of pointers array
     1853    char      ** k_pointers;      // base of kernel array of pointers
     1854    char       * k_buf_ptr;       // pointer on first empty slot in strings buffer
     1855    uint32_t     k_buf_space;     // number of bytes available in string buffer
     1856    kmem_req_t   req;             // kernel memory allocator request
     1857    char       * k_buf;           // kernel buffer for both pointers & strings
     1858
     1859#if DEBUG_PROCESS_EXEC_GET_STRINGS
     1860thread_t * this  = CURRENT_THREAD;
     1861uint32_t   cycle = (uint32_t)hal_get_cycles();
     1862#endif
     1863
     1864    // Allocate one block of physical memory for both the pointers and the strings
     1865    // as defined by the CONFIG_VMM_ARGS_SIZE and CONFIG_VMM_ENVS_SIZE parameters
     1866    // - the array of pointers is stored in the first bytes of the kernel buffer
     1867    // - the strings themselve are stored in the next bytes of this buffer
     1868    // Set the k_pointers, k_buf_ptr, k_buf_space, and max_index
     1869
     1870    if( is_args )
     1871    {
     1872        req.type   = KMEM_PPM;
     1873        req.order  = bits_log2( CONFIG_VMM_ARGS_SIZE );
     1874        req.flags  = AF_KERNEL | AF_ZERO;
     1875        k_buf      = kmem_alloc( &req );
     1876
     1877        pointers_bytes = CONFIG_PROCESS_ARGS_MAX_NR * sizeof(char *);
     1878        k_pointers     = (char **)k_buf;
     1879        k_buf_ptr      = k_buf + pointers_bytes;
     1880        k_buf_space    = (CONFIG_VMM_ARGS_SIZE * CONFIG_PPM_PAGE_SIZE) - pointers_bytes;
     1881        max_index      = CONFIG_PROCESS_ARGS_MAX_NR;
     1882
     1883#if DEBUG_PROCESS_EXEC_GET_STRINGS
     1884if( DEBUG_PROCESS_EXEC_GET_STRINGS < cycle )
     1885printk("\n[%s] thread[%x,%x] for args / u_buf %x / k_buf %x\n",
     1886__FUNCTION__, this->process->pid, this->trdid, u_pointers, k_buf );
     1887#endif
     1888
     1889    }
     1890    else
     1891    {
     1892        req.type   = KMEM_PPM;
     1893        req.order  = bits_log2( CONFIG_VMM_ENVS_SIZE );
     1894        req.flags  = AF_KERNEL | AF_ZERO;
     1895        k_buf      = kmem_alloc( &req );
     1896
     1897        pointers_bytes = CONFIG_PROCESS_ENVS_MAX_NR * sizeof(char *);
     1898        k_pointers     = (char **)k_buf;
     1899        k_buf_ptr      = k_buf + pointers_bytes;
     1900        k_buf_space    = (CONFIG_VMM_ENVS_SIZE * CONFIG_PPM_PAGE_SIZE) - pointers_bytes;
     1901        max_index      = CONFIG_PROCESS_ENVS_MAX_NR;
     1902
     1903#if DEBUG_PROCESS_EXEC_GET_STRINGS
     1904if( DEBUG_PROCESS_EXEC_GET_STRINGS < cycle )
     1905printk("\n[%s] thread[%x,%x] for envs / u_buf %x / k_buf %x\n",
     1906__FUNCTION__, this->process->pid, this->trdid, u_pointers, k_buf );
     1907#endif
     1908
     1909    }
     1910
     1911    // copy the user array of pointers to kernel buffer
     1912    hal_copy_from_uspace( XPTR( local_cxy , k_pointers ),
     1913                          u_pointers,
     1914                          pointers_bytes );
     1915
     1916    // WARNING : the pointers copied in the k_pointers[] array are user pointers,
     1917    // after the loop below, the k_pointers[] array contains kernel pointers.
     1918
     1919#if DEBUG_PROCESS_EXEC_GET_STRINGS
     1920if( DEBUG_PROCESS_EXEC_GET_STRINGS < cycle )
     1921printk("\n[%s] thread[%x,%x] copied u_ptr array to k_ptr array\n"
     1922"    p0 = %x / p1 = %x / p2 = %x / p3 = %x\n",
     1923__FUNCTION__, this->process->pid, this->trdid,
     1924k_pointers[0], k_pointers[1], k_pointers[2], k_pointers[3] );
     1925#endif
     1926
     1927    // scan kernel array of pointers to copy strings to kernel buffer
     1928    for( index = 0 ; index < max_index ; index++ )
     1929    {
     1930        // exit loop if (k_pointers[] == NUll)
     1931        if( k_pointers[index] == NULL ) break;
     1932
     1933        // compute string length
     1934        length = hal_strlen_from_uspace( k_pointers[index] ) + 1;
     1935
     1936        // return error if overflow in kernel buffer
     1937        if( length > k_buf_space ) return -1;
     1938
     1939        // copy the string to kernel buffer
     1940        hal_copy_from_uspace( XPTR( local_cxy , k_buf_ptr ),
     1941                              k_pointers[index],
     1942                              length );
     1943
     1944#if DEBUG_PROCESS_EXEC_GET_STRINGS
     1945if( DEBUG_PROCESS_EXEC_GET_STRINGS < cycle )
     1946printk("\n[%s] thread[%x,%x] copied string[%d] <%s> to kernel buffer / length %d\n",
     1947__FUNCTION__, this->process->pid, this->trdid, index, k_buf_ptr, length );
     1948#endif
     1949
     1950        // replace the user pointer by a kernel pointer in the k_pointer[] array
     1951        k_pointers[index] = k_buf_ptr;
     1952
     1953        // increment loop variables
     1954        k_buf_ptr   += length;
     1955        k_buf_space -= length;
     1956
     1957    }  // end loop on index
     1958
     1959    // update into exec_info structure
     1960    if( is_args )
     1961    {
     1962        exec_info->args_pointers  =  k_pointers;
     1963        exec_info->args_nr        =  index;
     1964    }
     1965    else
     1966    {
     1967        exec_info->envs_pointers  =  k_pointers;
     1968        exec_info->envs_buf_free  =  k_buf_ptr;
     1969        exec_info->envs_nr        =  index;
     1970    }
     1971
     1972#if DEBUG_PROCESS_EXEC_GET_STRINGS
     1973if( DEBUG_PROCESS_EXEC_GET_STRINGS < cycle )
     1974printk("\n[%s] thread[%x,%x] copied %d strings to kernel buffer\n",
     1975__FUNCTION__, this->process->pid, this->trdid, index );
     1976#endif
     1977
     1978    return 0;
     1979
     1980} // end process_exec_get_strings()
     1981
     1982/////////////////////////////////
     1983error_t process_make_exec( void )
     1984{
     1985    thread_t       * this;                    // local pointer on this thread
    18121986    process_t      * process;                 // local pointer on this process
    18131987    pid_t            pid;                     // this process identifier
     1988    trdid_t          trdid;                   // this thread identifier
    18141989    xptr_t           ref_xp;                  // reference process for this process
    18151990        error_t          error;                   // value returned by called functions
    1816     char           * path;                    // path to .elf file
     1991    char           * elf_path;                // path to .elf file
    18171992    xptr_t           file_xp;                 // extended pointer on .elf file descriptor
    18181993    uint32_t         file_id;                 // file index in fd_array
    1819     uint32_t         args_nr;                 // number of main thread arguments
    1820     char          ** args_pointers;           // array of pointers on main thread arguments
    1821 
    1822     // get calling thread, process, pid and ref_xp
    1823     thread  = CURRENT_THREAD;
    1824     process = thread->process;
     1994    vseg_t         * vseg;                    // local pointer on created vseg(s)
     1995    uint32_t         n;                       // index for loops
     1996
     1997    uint32_t         args_nr;                 // actual number of args (from exec_info)
     1998    intptr_t         args_base;               // args vseg base address in user space
     1999    uint32_t         args_size;               // args vseg size (bytes)
     2000
     2001    uint32_t         envs_nr;                 // actual number of envs (from exec_info)
     2002    intptr_t         envs_base;               // envs vseg base address in user space
     2003    uint32_t         envs_size;               // envs vseg size (bytes)
     2004
     2005    // get calling thread, process, pid, trdid, and ref_xp
     2006    this    = CURRENT_THREAD;
     2007    process = this->process;
    18252008    pid     = process->pid;
     2009    trdid   = this->trdid;
    18262010    ref_xp  = process->ref_xp;
    18272011
    1828         // get relevant infos from exec_info
    1829         path          = exec_info->path;
    1830     args_nr       = exec_info->args_nr;
    1831     args_pointers = exec_info->args_pointers;
     2012        // get .elf pathname from exec_info structure
     2013        elf_path      = process->exec_info.path;
    18322014
    18332015#if DEBUG_PROCESS_MAKE_EXEC
    18342016uint32_t cycle = (uint32_t)hal_get_cycles();
    18352017if( DEBUG_PROCESS_MAKE_EXEC < cycle )
    1836 printk("\n[%s] thread[%x,%x] enters for %s / cycle %d\n",
    1837 __FUNCTION__, pid, thread->trdid, path, cycle );
    1838 #endif
    1839 
    1840     // open the file identified by <path>
     2018printk("\n[%s] thread[%x,%x] enters for <%s> / cycle %d\n",
     2019__FUNCTION__, pid, trdid, elf_path, cycle );
     2020#endif
     2021
     2022    // 1. open the file identified by <path>
    18412023    file_xp = XPTR_NULL;
    18422024    file_id = 0xFFFFFFFF;
    18432025        error   = vfs_open( process->vfs_root_xp,
    1844                             path,
     2026                            elf_path,
    18452027                        ref_xp,
    18462028                            O_RDONLY,
     
    18502032        if( error )
    18512033        {
    1852                 printk("\n[ERROR] in %s : failed to open file <%s>\n", __FUNCTION__ , path );
     2034                printk("\n[ERROR] in %s : thread[%x,%x] failed to open file <%s>\n",
     2035        __FUNCTION__, pid, trdid, elf_path );
    18532036                return -1;
    18542037        }
    18552038
    18562039#if (DEBUG_PROCESS_MAKE_EXEC & 1)
    1857 cycle = (uint32_t)hal_get_cycles();
    18582040if( DEBUG_PROCESS_MAKE_EXEC < cycle )
    1859 printk("\n[%s] thread[%x,%x] opened file <%s> / cycle %d\n",
    1860 __FUNCTION__, pid, thread->trdid, path, cycle );
    1861 #endif
    1862 
    1863     // delete all threads other than this main thread in all clusters
     2041printk("\n[%s] thread[%x,%x] opened file <%s>\n",
     2042__FUNCTION__, pid, trdid, elf_path );
     2043#endif
     2044
     2045    // 2. delete all threads other than this main thread in all clusters
    18642046    process_sigaction( pid , DELETE_ALL_THREADS );
    18652047
    18662048#if (DEBUG_PROCESS_MAKE_EXEC & 1)
    1867 cycle = (uint32_t)hal_get_cycles();
    18682049if( DEBUG_PROCESS_MAKE_EXEC < cycle )
    1869 printk("\n[%s] thread[%x,%x] deleted existing threads / cycle %d\n",
    1870 __FUNCTION__, pid, thread->trdid, cycle );
    1871 #endif
    1872 
    1873     // reset calling process VMM
     2050printk("\n[%s] thread[%x,%x] deleted existing threads\n",
     2051__FUNCTION__, pid, trdid );
     2052#endif
     2053
     2054    // 3. reset calling process VMM
    18742055    vmm_user_reset( process );
    18752056
    18762057#if( DEBUG_PROCESS_MAKE_EXEC & 1 )
    1877 cycle = (uint32_t)hal_get_cycles();
    18782058if( DEBUG_PROCESS_MAKE_EXEC < cycle )
    1879 printk("\n[%s] thread[%x,%x] completed VMM reset / cycle %d\n",
    1880 __FUNCTION__, pid, thread->trdid, cycle );
    1881 #endif
    1882 
    1883     // re-initialize the VMM (args/envs vsegs registration)
    1884     error = vmm_user_init( process );
    1885     if( error )
    1886     {
    1887         printk("\n[ERROR] in %s : cannot initialise VMM for %s\n", __FUNCTION__ , path );
    1888         vfs_close( file_xp , file_id );
    1889         // FIXME restore old process VMM [AG]
    1890         return -1;
    1891     }
    1892    
     2059{
     2060    printk("\n[%s] thread[%x,%x] completed VMM reset\n",
     2061    __FUNCTION__, pid, trdid );
     2062    hal_vmm_display( ref_xp , true );
     2063}
     2064#endif
     2065
     2066    // 4. register the "args" vseg in VSL and map it in GPT, if required
     2067    // this vseg contains both the array of pointers and the strings
     2068    args_nr = process->exec_info.args_nr;
     2069
     2070    if( args_nr > 0 )
     2071    {
     2072        // get args vseg base and size in user space
     2073        args_base = CONFIG_VMM_UTILS_BASE << CONFIG_PPM_PAGE_SHIFT;
     2074        args_size = CONFIG_VMM_ARGS_SIZE << CONFIG_PPM_PAGE_SHIFT;
     2075
     2076        // create and register args vseg in VMM
     2077        vseg = vmm_create_vseg( process,
     2078                                VSEG_TYPE_DATA,
     2079                                args_base,
     2080                                args_size,
     2081                                0,                 // file_offset unused for DATA type
     2082                                0,                 // file_size unused for DATA type
     2083                                XPTR_NULL,         // mapper_xp unused for DATA type
     2084                                0 );               // cxy unused for DATA type
     2085        if( vseg == NULL )
     2086        {
     2087                 printk("\n[ERROR] in %s : thread[%x,%x] cannot get args vseg for <%s>\n",
     2088             __FUNCTION__, pid, trdid, elf_path );
     2089                     return -1;
     2090        }
     2091
    18932092#if( DEBUG_PROCESS_MAKE_EXEC & 1 )
    1894 cycle = (uint32_t)hal_get_cycles();
    18952093if( DEBUG_PROCESS_MAKE_EXEC < cycle )
    1896 printk("\n[%s] thread[%x,%x] registered args/envs vsegs / cycle %d\n",
    1897 __FUNCTION__, pid, thread->trdid, cycle );
    1898 #endif
    1899 
    1900     // register code & data vsegs as well as entry-point in process VMM,
    1901     // and register extended pointer on .elf file in process descriptor
     2094{
     2095    printk("\n[%s] thread[%x,%x] args vseg registered in new process VSL\n",
     2096    __FUNCTION__, pid, trdid );
     2097    hal_vmm_display( ref_xp , true );
     2098}
     2099#endif
     2100        // map all pages for this "args" vseg
     2101        uint32_t fake_attr;   // required for hal_gpt_lock_pte()
     2102        ppn_t    fake_ppn;    // required for hal_gpt_lock_pte()
     2103
     2104        xptr_t   gpt  = XPTR( local_cxy , &process->vmm.gpt );
     2105        uint32_t attr = GPT_MAPPED | GPT_SMALL | GPT_READABLE | GPT_USER | GPT_CACHABLE;
     2106        vpn_t    vpn  = CONFIG_VMM_UTILS_BASE;
     2107        ppn_t    ppn  = ((ppn_t)process->exec_info.args_pointers >> CONFIG_PPM_PAGE_SHIFT);
     2108
     2109        for( n = 0 ; n < CONFIG_VMM_ARGS_SIZE ; n++ ) 
     2110        {
     2111            // lock the PTE
     2112            if (hal_gpt_lock_pte( gpt , vpn , &fake_attr , &fake_ppn ) )
     2113            {
     2114                printk("\n[ERROR] in %s : thread[%x,%x] cannot map args vpn %x for <%s>\n",
     2115                __FUNCTION__, pid, trdid, vpn, elf_path );
     2116                        return -1;
     2117            }
     2118
     2119            // map and unlock the PTE
     2120            hal_gpt_set_pte( gpt , vpn + n , attr , ppn + n );
     2121        }
     2122
     2123#if( DEBUG_PROCESS_MAKE_EXEC & 1 )
     2124if( DEBUG_PROCESS_MAKE_EXEC < cycle )
     2125{
     2126    printk("\n[%s] thread[%x,%x] args vseg mapped in new process GPT\n",
     2127    __FUNCTION__, pid, trdid );
     2128    hal_vmm_display( ref_xp , true );
     2129}
     2130#endif
     2131
     2132        // set user space pointers in array of pointers
     2133        char  ** ptr    = process->exec_info.args_pointers;
     2134
     2135        for( n = 0 ; n < args_nr ; n++ )
     2136        {
     2137            ptr[n] = ptr[n] + args_base - (intptr_t)ptr;
     2138        }
     2139    }
     2140
     2141    // 5. register the "envs" vseg in VSL and map it in GPT, if required
     2142    // this vseg contains both the array of pointers and the strings
     2143    envs_nr = process->exec_info.envs_nr;
     2144
     2145    if( envs_nr > 0 )
     2146    {
     2147        // get envs vseg base and size in user space from config
     2148        envs_base = (CONFIG_VMM_UTILS_BASE + CONFIG_VMM_ARGS_SIZE) << CONFIG_PPM_PAGE_SHIFT;
     2149        envs_size = CONFIG_VMM_ENVS_SIZE << CONFIG_PPM_PAGE_SHIFT;
     2150
     2151        // TODO (inspired from args)
     2152    }
     2153
     2154
     2155    // 6. register code & data vsegs, and entry-point in process VMM,
     2156    // register extended pointer on .elf file in process descriptor
    19022157        error = elf_load_process( file_xp , process );
    19032158    if( error )
    19042159        {
    1905                 printk("\n[ERROR] in %s : failed to access <%s>\n", __FUNCTION__ , path );
    1906         vfs_close( file_xp , file_id );
    1907         // FIXME restore old process VMM [AG]
     2160                printk("\n[ERROR] in %s : thread[%x,%x] failed to access <%s>\n",
     2161        __FUNCTION__, pid, trdid, elf_path );
    19082162        return -1;
    19092163        }
    19102164
    19112165#if( DEBUG_PROCESS_MAKE_EXEC & 1 )
    1912 cycle = (uint32_t)hal_get_cycles();
    19132166if( DEBUG_PROCESS_MAKE_EXEC < cycle )
    1914 printk("\n[%s] thread[%x,%x] registered code/data vsegs / cycle %d\n",
    1915 __FUNCTION__, pid, thread->trdid, cycle );
    1916 #endif
    1917 
    1918     // update the existing main thread descriptor... and jump to user code
    1919     error = thread_user_exec( (void *)process->vmm.entry_point,
    1920                               args_nr,
    1921                               args_pointers );
     2167{
     2168    printk("\n[%s] thread[%x,%x] registered code/data vsegs / entry %x\n",
     2169    __FUNCTION__, pid, trdid, process->vmm.entry_point );
     2170    hal_vmm_display( ref_xp , true );
     2171}
     2172#endif
     2173
     2174    // 7. allocate an user stack vseg for main thread
     2175    vseg = vmm_create_vseg( process,
     2176                            VSEG_TYPE_STACK,
     2177                            LTID_FROM_TRDID( trdid ),
     2178                            0,                 // length unused
     2179                            0,                 // file_offset unused
     2180                            0,                 // file_size unused
     2181                            XPTR_NULL,         // mapper_xp unused
     2182                            local_cxy );
     2183    if( vseg == NULL )
     2184    {
     2185            printk("\n[ERROR] in %s : thread[%x,%x] cannot set u_stack vseg for <%s>\n",
     2186        __FUNCTION__, pid, trdid, elf_path );
     2187                return -1;
     2188    }
     2189
     2190#if( DEBUG_PROCESS_MAKE_EXEC & 1 )
     2191if( DEBUG_PROCESS_MAKE_EXEC < cycle )
     2192{
     2193    printk("\n[%s] thread[%x,%x] registered stack vseg\n",
     2194    __FUNCTION__, pid, trdid );
     2195    hal_vmm_display( ref_xp , true );
     2196}
     2197#endif
     2198
     2199    // update user stack in thread descriptor
     2200    this->user_stack_vseg = vseg;
     2201
     2202    // 8. update the main thread descriptor ... and jumps (one way) to user code
     2203    thread_user_exec( args_nr , args_base );
     2204
    19222205    if( error )
    19232206    {
    1924         printk("\n[ERROR] in %s : cannot update main thread for %s\n", __FUNCTION__ , path );
    1925         vfs_close( file_xp , file_id );
    1926         // FIXME restore old process VMM
     2207        printk("\n[ERROR] in %s : thread[%x,%x] cannot update thread for <%s>\n",
     2208        __FUNCTION__ , pid, trdid, elf_path );
    19272209        return -1;
    19282210    }
    19292211
    1930     assert( false, "we should not execute this code");
    1931  
    19322212        return 0;
    19332213
     
    21532433#if(DEBUG_PROCESS_INIT_CREATE & 1)
    21542434if( DEBUG_PROCESS_INIT_CREATE < cycle )
    2155 printk("\n[%s] thread[%x,%x] registered code/data vsegs in VMM\n",
    2156 __FUNCTION__, this->process->pid, this->trdid );
    2157 #endif
    2158 
    2159 #if (DEBUG_PROCESS_INIT_CREATE & 1)
    2160 hal_vmm_display( XPTR( local_cxy , process ) , true );
     2435{
     2436    printk("\n[%s] thread[%x,%x] registered code/data vsegs in VMM\n",
     2437    __FUNCTION__, this->process->pid, this->trdid );
     2438    hal_vmm_display( XPTR( local_cxy , process ) , true );
     2439}
    21612440#endif
    21622441
     
    22912570        txt_file_xp = hal_remote_l64( XPTR( owner_cxy , &owner_ptr->fd_array.array[0] ) );
    22922571
    2293         assert( (txt_file_xp != XPTR_NULL) ,
     2572        assert( __FUNCTION__, (txt_file_xp != XPTR_NULL) ,
    22942573        "process must be attached to one TXT terminal" );
    22952574
     
    23632642    }
    23642643
    2365     assert( false , "no free TXT terminal found" );
     2644    assert( __FUNCTION__, false , "no free TXT terminal found" );
    23662645
    23672646    return -1;
     
    23702649
    23712650/////////////////////////////////////////////
    2372 void process_txt_attach( process_t * process,
    2373                          uint32_t    txt_id )
     2651void process_txt_attach( xptr_t   process_xp,
     2652                         uint32_t txt_id )
    23742653{
    23752654    xptr_t      chdev_xp;     // extended pointer on TXT_RX chdev
     
    23792658    xptr_t      lock_xp;      // extended pointer on list lock in chdev
    23802659
     2660    process_t * process_ptr = GET_PTR(process_xp );
     2661    cxy_t       process_cxy = GET_CXY(process_xp );
     2662
    23812663// check process is in owner cluster
    2382 assert( (CXY_FROM_PID( process->pid ) == local_cxy) ,
     2664assert( __FUNCTION__, (process_xp == hal_remote_l64( XPTR( process_cxy , &process_ptr->owner_xp ))),
    23832665"process descriptor not in owner cluster" );
    23842666
    23852667// check terminal index
    2386 assert( (txt_id < LOCAL_CLUSTER->nb_txt_channels) ,
     2668assert( __FUNCTION__, (txt_id < LOCAL_CLUSTER->nb_txt_channels) ,
    23872669"illegal TXT terminal index" );
    23882670
     
    23992681    remote_busylock_acquire( lock_xp );
    24002682
    2401     // insert process in attached process list
    2402     xlist_add_last( root_xp , XPTR( local_cxy , &process->txt_list ) );
     2683    // insert owner process in list of attached processes to same TXT
     2684    xlist_add_last( root_xp , XPTR( process_cxy , &process_ptr->txt_list ) );
    24032685
    24042686    // release lock protecting list of processes attached to TXT
     
    24102692if( DEBUG_PROCESS_TXT < cycle )
    24112693printk("\n[%s] thread[%x,%x] attached process %x to TXT %d / cycle %d\n",
    2412 __FUNCTION__, this->process->pid, this->trdid, process->pid, txt_id , cycle );
     2694__FUNCTION__, this->process->pid, this->trdid,
     2695hal_remote_l32( XPTR( process_cxy , &process_ptr->pid, txt_id , cycle );
    24132696#endif
    24142697
     
    24332716
    24342717// check process descriptor in owner cluster
    2435 assert( (CXY_FROM_PID( process_pid ) == process_cxy ) ,
     2718assert( __FUNCTION__, (CXY_FROM_PID( process_pid ) == process_cxy ) ,
    24362719"process descriptor not in owner cluster" );
    24372720
     
    24712754
    24722755///////////////////////////////////////////////////
     2756uint32_t process_txt_get_index( xptr_t process_xp )
     2757{
     2758
     2759    // get target process cluster and local pointer
     2760    process_t * process_ptr = GET_PTR( process_xp );
     2761    cxy_t       process_cxy = GET_CXY( process_xp );
     2762
     2763assert( __FUNCTION__, (process_xp == hal_remote_l64( XPTR( process_cxy , &process_ptr->owner_xp))),
     2764"process descriptor not in owner cluster" );
     2765
     2766    // get extended pointer on STDIN pseudo file in owner process descriptor
     2767    xptr_t file_xp = hal_remote_l64( XPTR( process_cxy , &process_ptr->fd_array.array[0]));
     2768
     2769assert( __FUNCTION__, (file_xp != XPTR_NULL),
     2770"STDIN pseudo-file undefined in fd_array for process %x\n",
     2771hal_remote_l32( XPTR( process_cxy , &process_ptr->pid ) ) );
     2772
     2773    // get extended pointer on TXT chdev
     2774    xptr_t chdev_xp = chdev_from_file( file_xp );
     2775 
     2776assert( __FUNCTION__, (chdev_xp != XPTR_NULL),
     2777"chdev undefined for STDIN pseudo-file of process %x\n",
     2778hal_remote_l32( XPTR( process_cxy , &process_ptr->pid ) ) );
     2779
     2780    // get cluster and local pointer on chdev
     2781   cxy_t     chdev_cxy = GET_CXY( chdev_xp );
     2782   chdev_t * chdev_ptr = GET_PTR( chdev_xp );
     2783 
     2784   // get parent TXT terminal index
     2785   return hal_remote_l32( XPTR( chdev_cxy , &chdev_ptr->channel ) );
     2786
     2787}  // end process_txt_get_index()
     2788
     2789///////////////////////////////////////////////////
    24732790void process_txt_set_ownership( xptr_t process_xp )
    24742791{
    24752792    process_t * process_ptr;
    24762793    cxy_t       process_cxy;
    2477     pid_t       process_pid;
    24782794    xptr_t      file_xp;
    24792795    xptr_t      txt_xp;     
     
    24842800    process_cxy = GET_CXY( process_xp );
    24852801    process_ptr = GET_PTR( process_xp );
    2486     process_pid = hal_remote_l32( XPTR( process_cxy , &process_ptr->pid ) );
    24872802
    24882803    // check owner cluster
    2489     assert( (process_cxy == CXY_FROM_PID( process_pid )) ,
     2804    assert( __FUNCTION__, (process_xp == hal_remote_l64( XPTR( process_cxy , &process_ptr->owner_xp ))),
    24902805    "process descriptor not in owner cluster" );
    24912806
     
    25062821uint32_t txt_id = hal_remote_l32( XPTR( txt_cxy , &txt_ptr->channel ) );
    25072822if( DEBUG_PROCESS_TXT < cycle )
    2508 printk("\n[%s] thread[%x,%x] give TXT%d ownership to process %x / cycle %d\n",
    2509 __FUNCTION__, this->process->pid, this->trdid, txt_id, process_pid, cycle );
     2823printk("\n[%s] thread[%x,%x] give TXT%d ownership to process / cycle %d\n",
     2824__FUNCTION__, this->process->pid, this->trdid, txt_id, cycle );
    25102825#endif
    25112826
     
    25412856
    25422857// check owner cluster
    2543 assert( (process_cxy == CXY_FROM_PID( process_pid )) ,
     2858assert( __FUNCTION__, (process_cxy == CXY_FROM_PID( process_pid )) ,
    25442859"process descriptor not in owner cluster" );
    25452860
     
    25952910
    25962911// It must exist a KSH process for each user TXT channel
    2597 assert( (found == true), "KSH process not found for TXT%d", txt_id );
     2912assert( __FUNCTION__, (found == true), "KSH process not found for TXT%d", txt_id );
    25982913
    25992914        }
     
    26712986// check calling thread execute in target process owner cluster
    26722987pid_t process_pid = hal_remote_l32( XPTR( process_cxy , &process_ptr->pid ) );
    2673 assert( (process_cxy == CXY_FROM_PID( process_pid )) ,
     2988assert( __FUNCTION__, (process_cxy == CXY_FROM_PID( process_pid )) ,
    26742989"process descriptor not in owner cluster" );
    26752990
     
    27153030    xptr_t      txt0_lock_xp;
    27163031   
    2717     assert( (txt_id < LOCAL_CLUSTER->nb_txt_channels) ,
     3032    assert( __FUNCTION__, (txt_id < LOCAL_CLUSTER->nb_txt_channels) ,
    27183033    "illegal TXT terminal index" );
    27193034
Note: See TracChangeset for help on using the changeset viewer.