Ignore:
Timestamp:
Jun 18, 2017, 10:06:41 PM (7 years ago)
Author:
alain
Message:

Introduce syscalls.

File:
1 edited

Legend:

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

    r14 r23  
    44 * Authors  Ghassan Almaless (2008,2009,2010,2011,2012)
    55 *          Mohamed Lamine Karaoui (2015)
    6  *          Alain Greiner (2016)
     6 *          Alain Greiner (2016,2017)
    77 *
    88 * Copyright (c) UPMC Sorbonne Universites
     
    4747#include <process.h>
    4848#include <elf.h>
     49#include <syscalls.h>
    4950
    5051//////////////////////////////////////////////////////////////////////////////////////////
     
    103104                             pid_t       ppid )
    104105{
    105     // reset signal manager  TODO [AG]
    106 
    107     // reset the file descriptors array
     106    // reset reference process vmm
     107    vmm_init( process );
     108
     109    // reset reference process file descriptors array
    108110        process_fd_init( process );
    109111
    110     // reset the process files structures and cd_lock
     112    // reset reference process files structures and cd_lock
    111113        process->vfs_root_xp     = XPTR_NULL;
     114        process->vfs_bin_xp      = XPTR_NULL;
    112115        process->vfs_cwd_xp      = XPTR_NULL;
    113         process->vfs_bin_xp      = XPTR_NULL;
    114 
    115     spinlock_init( &process->cd_lock );
     116    remote_rwlock_init( XPTR( local_cxy , &process->cwd_lock ) );
    116117
    117118    // reset children list root
     
    119120        process->children_nr     = 0;
    120121
    121     // reset semaphore list root
     122    // reset semaphore / mutex / barrier / condvar list roots
    122123    xlist_root_init( XPTR( local_cxy , &process->sem_root ) );
    123         process->sem_nr          = 0;
     124    xlist_root_init( XPTR( local_cxy , &process->mutex_root ) );
     125    xlist_root_init( XPTR( local_cxy , &process->barrier_root ) );
     126    xlist_root_init( XPTR( local_cxy , &process->condvar_root ) );
     127    remote_spinlock_init( XPTR( local_cxy , &process->sync_lock ) );
    124128
    125129    // register new process in the parent children list
     
    128132    xlist_add_first( root , entry );
    129133   
    130     // reset th_tbl[] array
     134    // reset th_tbl[] array as empty
    131135    uint32_t i;
    132136    for( i = 0 ; i < CONFIG_THREAD_MAX_PER_CLUSTER ; i++ )
     
    137141    spinlock_init( &process->th_lock );
    138142
    139     // reset process VMM
    140         memset( &process->vmm , 0 , sizeof(vmm_t) );
    141 
    142143    // initialize PID and PPID
    143144        process->pid   = pid;
    144145    process->ppid  = ppid;
    145146
    146     // set ref_xp field and is_ref flag
    147     process->is_ref = true;
     147    // set ref_xp field
    148148    process->ref_xp = XPTR( local_cxy , process );
    149149
     
    153153    // register new process descriptor in owner cluster manager copies_list
    154154    cluster_process_copies_link( process );
     155
     156    // initalise signal manager TODO [AG]
    155157
    156158        hal_wbflush();
     
    162164                           xptr_t      reference_process_xp )
    163165{
    164     // replicate the remote process descriptor in new process descriptor
    165     xptr_t local_process_xp = XPTR( local_cxy , local_process );
    166     hal_remote_memcpy( local_process_xp , reference_process_xp , sizeof(process_t) );
    167 
    168     // initalise signal manager TODO [AG]
    169 
    170     // initialise file descriptors array TODO [AG]
    171 
    172     // initialise process files structures TODO [AG]
    173 
    174     // set the ref_xp field and clear the is_ref flag
     166    // get reference process cluster and local pointer
     167    cxy_t       ref_cxy = GET_CXY( reference_process_xp );
     168    process_t * ref_ptr = (process_t *)GET_PTR( reference_process_xp );
     169
     170    // reset local process vmm
     171    vmm_init( local_process );
     172
     173    // reset process file descriptors array
     174        process_fd_init( local_process );
     175
     176    // reset vfs_root_xp / vfs_bin_xp / vfs_cwd_xp fields
     177    local_process->vfs_root_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->vfs_root_xp ) );
     178    local_process->vfs_bin_xp  = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->vfs_bin_xp ) );
     179    local_process->vfs_cwd_xp  = XPTR_NULL;
     180
     181    // set the pid, ppid, ref_xp fields
     182    local_process->pid    = hal_remote_lw( XPTR( ref_cxy , &ref_ptr->pid ) );
     183    local_process->ppid   = hal_remote_lw( XPTR( ref_cxy , &ref_ptr->ppid ) );
    175184    local_process->ref_xp = reference_process_xp;
    176     local_process->is_ref = false;
    177185
    178186    // reset children list root (not used in a process descriptor copy)
     
    185193    // reset semaphores list root (not used in a process descriptor copy)
    186194    xlist_root_init( XPTR( local_cxy , &local_process->sem_root ) );
    187     local_process->sem_nr        = 0;           
    188 
    189     // initialize th_tbl[] array as empty
     195    xlist_root_init( XPTR( local_cxy , &local_process->mutex_root ) );
     196    xlist_root_init( XPTR( local_cxy , &local_process->barrier_root ) );
     197    xlist_root_init( XPTR( local_cxy , &local_process->condvar_root ) );
     198
     199    // reset th_tbl[] array as empty
    190200    uint32_t i;
    191201    for( i = 0 ; i < CONFIG_THREAD_MAX_PER_CLUSTER ; i++ )
     
    196206    spinlock_init( &local_process->th_lock );
    197207
    198     // initialise  process VMM TODO [AG]
    199 
    200208    // register new process descriptor in local cluster manager local_list
    201209    cluster_process_local_link( local_process );
     
    203211    // register new process descriptor in owner cluster manager copies_list
    204212    cluster_process_copies_link( local_process );
     213
     214    // initalise signal manager TODO [AG]
    205215
    206216        hal_wbflush();
     
    223233    pmgr_t * pmgr = &LOCAL_CLUSTER->pmgr;
    224234
     235    // get the lock protecting the list of local process descriptors
     236    remote_spinlock_lock( XPTR( local_cxy , &pmgr->local_lock ) );
     237
    225238    // remove the process descriptor from local_list in local cluster manager
    226     spinlock_lock( &pmgr->local_lock );
    227239    xlist_unlink( XPTR( local_cxy , &process->local_list ) );
    228     spinlock_unlock( &pmgr->local_lock );
     240
     241    // release the lock protecting the list of local process descriptors
     242    remote_spinlock_unlock( XPTR( local_cxy , &pmgr->local_lock ) );
    229243
    230244    // get extended pointer on copies_lock in owner cluster manager
     
    243257    // From this point, the process descriptor is unreachable
    244258
     259    // close all open files and update dirty TODO [AG]
     260
    245261    // release signal manager TODO [AG]
    246262
    247     // delete all open file descriptors
    248     process_fd_destroy( process );
    249 
    250     // Close bin file and decrease refcount for root and cwd
    251         if( process->vfs_bin_xp != XPTR_NULL ) vfs_close( process->vfs_bin_xp , NULL );
     263    // Decrease refcount for bin file, root file and cwd file
     264        vfs_file_count_down( process->vfs_bin_xp );
    252265    vfs_file_count_down( process->vfs_root_xp );
    253266    vfs_file_count_down( process->vfs_cwd_xp );
     
    325338
    326339
    327 
    328 
    329 
    330340///////////////////////////////////////////////
    331341process_t * process_get_local_copy( pid_t pid )
    332342{
    333343    error_t        error;
    334     bool_t         found;
    335     list_entry_t * iter;
    336     process_t    * process;     // pointer on local copy
     344    process_t    * process_ptr;   // local pointer on process
     345    xptr_t         process_xp;    // extended pointer on process
     346    pid_t          process_pid;   // process identifier
    337347
    338348    cluster_t * cluster = LOCAL_CLUSTER;
    339349
    340350    // get lock protecting local list of processes
    341     spinlock_lock( &cluster->pmgr.local_lock );
     351    remote_spinlock_lock( XPTR( local_cxy , &cluster->pmgr.local_lock ) );
    342352
    343353    // scan the local list of process descriptors to find the process
    344     found = false;
    345     LIST_FOREACH( &cluster->pmgr.local_root , iter )
    346     {
    347         process = LIST_ELEMENT( iter , process_t , local_list );
    348         if( process->pid == pid )
     354    xptr_t  iter;
     355    bool_t  found = false;
     356    XLIST_FOREACH( XPTR( local_cxy , &cluster->pmgr.local_root ) , iter )
     357    {
     358        process_xp  = XLIST_ELEMENT( iter , process_t , local_list );
     359        process_ptr = (process_t *)GET_PTR( process_xp );
     360        process_pid = hal_remote_lw( XPTR( local_cxy , &process_ptr->pid ) );
     361        if( process_ptr->pid == pid )
    349362        {
    350363            found = true;
     
    354367
    355368    // release lock protecting local list of processes
    356     spinlock_unlock( &cluster->pmgr.local_lock );
    357 
    358     // allocate memory for a local process descriptor
    359     // and initialise it from reference if required
     369    remote_spinlock_unlock( XPTR( local_cxy , &cluster->pmgr.local_lock ) );
     370
     371    // allocate memory for a new local process descriptor
     372    // and initialise it from reference cluster if required
    360373    if( !found )
    361374    {
    362375        // get extended pointer on reference process descriptor
    363         xptr_t reference = cluster_get_reference_process_from_pid( pid );
     376        xptr_t ref_xp = cluster_get_reference_process_from_pid( pid );
     377
     378        assert( (ref_xp != XPTR_NULL) , __FUNCTION__ , "illegal pid\n" );
    364379
    365380        // allocate memory for local process descriptor
    366         process = process_alloc();
    367         if( process == NULL )  return NULL;
     381        process_ptr = process_alloc();
     382        if( process_ptr == NULL )  return NULL;
    368383
    369384        // initialize local process descriptor copy
    370         error = process_copy_init( process, reference );
     385        error = process_copy_init( process_ptr , ref_xp );
    371386        if( error ) return NULL;
    372 
    373        
    374         // register process in global copies_list
    375     }
    376 
    377     return process;
     387    }
     388
     389    return process_ptr;
    378390} // end process_get_local_copy()
    379391
     
    389401
    390402    remote_spinlock_init( XPTR( local_cxy , &process->fd_array.lock ) );
    391     process->fd_array.max       = CONFIG_PROCESS_FILE_MAX_NR;
    392     process->fd_array.current   = 0;
     403
     404    process->fd_array.current = 0;
    393405
    394406    // initialize array
    395     for ( fd = 0 ; fd < process->fd_array.max ; fd++ )
     407    for ( fd = 0 ; fd < CONFIG_PROCESS_FILE_MAX_NR ; fd++ )
    396408    {
    397409        process->fd_array.array[fd] = XPTR_NULL;
     
    399411}
    400412
    401 //////////////////////////////////////////////
    402 void process_fd_destroy( process_t * process )
    403 {
    404     uint32_t fd;
    405 
    406     // loop on all open file descriptors to close all open files
    407     for( fd = 0 ; fd < process->fd_array.max ; fd++ )
    408     {
    409         xptr_t file_xp = process->fd_array.array[fd];
    410         if ( file_xp != XPTR_NULL ) vfs_close( file_xp , NULL );
    411     }
     413
     414//////////////////////////////
     415bool_t process_fd_array_full()
     416{
     417    // get extended pointer on reference process
     418    xptr_t ref_xp = CURRENT_THREAD->process->ref_xp;
     419
     420    // get reference process cluster and local pointer
     421    process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
     422    cxy_t       ref_cxy = GET_CXY( ref_xp );
     423
     424    // get number of open file descriptors from reference fd_array
     425    uint32_t current = hal_remote_lw( XPTR( ref_cxy , &ref_ptr->fd_array.current ) );
     426
     427        return ( current >= CONFIG_PROCESS_FILE_MAX_NR ); 
    412428}
    413429
    414 ///////////////////////////////////////////////////
    415 bool_t process_fd_array_full( process_t * process )
    416 {
    417         return ( process->fd_array.current >= process->fd_array.max); 
    418 }
    419 
    420430/////////////////////////////////////////////////
    421 error_t process_fd_allocate( process_t * process,
    422                              xptr_t      file_xp,
    423                              uint32_t   * ret_fd )
     431error_t process_fd_register(  xptr_t     file_xp,
     432                              uint32_t * file_id )
    424433{
    425434    bool_t    found;
    426     uint32_t  fd;
    427 
    428         remote_spinlock_lock( XPTR( local_cxy , &process->fd_array.lock ) );
     435    uint32_t  id;
     436    xptr_t    xp;
     437
     438    // get extended pointer on reference process
     439    xptr_t ref_xp = CURRENT_THREAD->process->ref_xp;
     440
     441    // get reference process cluster and local pointer
     442    process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
     443    cxy_t       ref_cxy = GET_CXY( ref_xp );
     444
     445    // take lock protecting reference fd_array
     446        remote_spinlock_lock( XPTR( ref_cxy , &ref_ptr->fd_array.lock ) );
    429447
    430448    found   = false;
    431449
    432     for ( fd = 0; fd < process->fd_array.max; fd++ )
    433     {
    434         if ( process->fd_array.array[fd] == XPTR_NULL )
     450    for ( id = 0; id < CONFIG_PROCESS_FILE_MAX_NR ; id++ )
     451    {
     452        xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->fd_array.array[id] ) );
     453        if ( xp == XPTR_NULL )
    435454        {
    436455            found = true;
    437             process->fd_array.array[fd] = file_xp;
    438                 process->fd_array.current++;
    439                         *ret_fd = fd;
     456            hal_remote_swd( XPTR( ref_cxy , &ref_ptr->fd_array.array[id] ) , file_xp );
     457                hal_remote_atomic_add( XPTR( ref_cxy , &ref_ptr->fd_array.current ) , 1 );
     458                        *file_id = id;
    440459            break;
    441460        }
    442461    }
    443462
    444         remote_spinlock_unlock( XPTR( local_cxy , &process->fd_array.lock ) );
     463    // release lock protecting reference fd_array
     464        remote_spinlock_unlock( XPTR( ref_cxy , &ref_ptr->fd_array.lock ) );
    445465
    446466    if ( !found ) return EMFILE;
    447467    else          return 0;
    448 }
    449 
    450 ////////////////////////////////////////////////
    451 error_t process_fd_release( process_t * process,
    452                             uint32_t    fd )
    453 {
    454     if ( (fd < 0) || (fd > process->fd_array.max) ) return EBADF;
    455 
    456     remote_spinlock_lock( XPTR( local_cxy , &process->fd_array.lock ) );
    457 
    458     process->fd_array.array[fd] = XPTR_NULL;
    459         process->fd_array.current--;
    460 
    461         remote_spinlock_unlock( XPTR( local_cxy , &process->fd_array.lock ) );
    462 
    463     return 0;
    464 }
    465 
    466 ///////////////////////////////////////
    467 void process_fd_copy( fd_array_t * dst,
    468                       fd_array_t * src )
    469 {
    470     uint32_t fd;
    471     xptr_t   entry;
    472 
    473     remote_spinlock_lock( XPTR( local_cxy , &src->lock ) );
    474 
    475     // loop on all entries in source process fd_array       
    476     for( fd = 0 ; fd < src->max ; fd++ )
    477         {
    478                 entry = src->array[fd];
    479 
    480                 if( entry != XPTR_NULL )
    481                 {
    482             // increment file descriptor ref count
    483             vfs_file_count_up( entry );
    484 
    485                         // copy entry in destination process fd_array
    486                         dst->array[fd] = entry;
    487                 }
    488         }
    489 
    490     // release lock on source process fd_array
    491         remote_spinlock_unlock( XPTR( local_cxy , &src->lock ) );
    492 }
     468
     469}  // end process_fd_register()
     470
     471////////////////////////////////////////////////
     472xptr_t process_fd_get_xptr( process_t * process,
     473                            uint32_t    file_id )
     474{
     475    xptr_t  file_xp;
     476
     477    // access local copy of process descriptor
     478    file_xp = process->fd_array.array[file_id];
     479
     480    if( file_xp == XPTR_NULL )
     481    {
     482        // get reference process cluster and local pointer
     483        xptr_t      ref_xp  = process->ref_xp;
     484        cxy_t       ref_cxy = GET_CXY( ref_xp );
     485        process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
     486
     487        // access reference process descriptor
     488        file_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->fd_array.array[file_id] ) );
     489
     490        // update local fd_array if found
     491        if( file_xp != XPTR_NULL )
     492        {
     493            process->fd_array.array[file_id] = file_xp;
     494        }
     495    }
     496
     497    return file_xp;
     498
     499}  // end process_fd_get_xptr()
    493500
    494501///////////////////////////////////////////
     
    510517        remote_spinlock_lock( XPTR( src_cxy , &src_ptr->lock ) );
    511518
    512     // get number of entries in fd_array
    513     uint32_t max = hal_remote_lw( XPTR( src_cxy , &src_ptr->max ) );
    514 
    515519    // loop on all entries in source process fd_array       
    516     for( fd = 0 ; fd < max ; fd++ )
     520    for( fd = 0 ; fd < CONFIG_PROCESS_FILE_MAX_NR ; fd++ )
    517521        {
    518522                entry = (xptr_t)hal_remote_lwd( XPTR( src_cxy , &src_ptr->array[fd] ) );
     
    609613    pid   = exec_info->pid;
    610614   
    611     if( CXY_FROM_PID( pid ) != local_cxy )
    612     {
    613         printk("\n[PANIC] in %s : illegal process PID %x in cluster %x\n",
    614                __FUNCTION__ , pid , local_cxy );
    615         hal_core_sleep();
    616     }
     615    assert( (CXY_FROM_PID( pid ) == local_cxy) , __FUNCTION__ , "illegal PID\n" );
    617616
    618617    exec_dmsg("\n[INFO] %s enters in cluster %x for process %x / path = %s\n",
     
    677676        }
    678677
    679     // create "stack" vseg descriptor for associated main thread
    680     vseg_t * stack_vseg = vmm_create_vseg( process,
    681                                            0,             // base defined by VMM
    682                                            0,             // size defined by VMM
    683                                            VSEG_TYPE_STACK );
    684     if( stack_vseg == NULL )
    685         {
    686                 printk("\n[ERROR] in %s : cannot create stack vseg for process %x / path = %s\n",
    687                        __FUNCTION__, pid , path );
    688         process_destroy( process );
    689         return error;
    690         }
    691 
    692678    // select a core in cluster
    693679    lid  = cluster_select_local_core();
     
    695681
    696682    // initialize pthread attributes for main thread
    697     attr.pid          = pid;
    698     attr.entry_func   = (void*)process->vmm.entry_point;
    699     attr.entry_args   = exec_info->args_pointers;
    700     attr.flags        = PT_FLAG_DETACH;             // main thread always detached
    701     attr.cxy          = local_cxy;
    702     attr.lid          = lid;
    703 
    704     // create and initialise thread descriptor, link thread & process
    705         error = thread_user_create( &thread,
     683    attr.attributes = PT_ATTR_DETACH | PT_ATTR_CLUSTER_DEFINED | PT_ATTR_CORE_DEFINED;
     684    attr.cxy        = local_cxy;
     685    attr.lid        = lid;
     686
     687    // create and initialise thread descriptor
     688        error = thread_user_create( pid,
     689                                (void *)process->vmm.entry_point,
     690                                exec_info->args_pointers,
    706691                                &attr,
    707                                 stack_vseg->min,
    708                                 stack_vseg->max - stack_vseg->min );
     692                                &thread );
    709693        if( error )
    710694        {
     
    732716{
    733717        process_t   * process_init;  // process_init descriptor
    734         thread_t    * thread_init;   // process_init main thread descriptor
    735718    pid_t         init_pid;      // process_init pid
    736719    exec_info_t   exec_info;     // structure to be passed to process_make_exec()
     
    779762        process_zero.children_nr = 1;
    780763
    781     // TODO open stdin / stdout / stderr pseudo-files
    782     xptr_t  stdin_xp;
    783     xptr_t  stdout_xp;
    784     xptr_t  stderr_xp;
    785 
    786         // error1 = vfs_open( process_init->vfs_cwd_xp, NULL, VFS_O_RDONLY, &stdin_xp );
    787         // error2 = vfs_open( process_init->vfs_cwd_xp, NULL, VFS_O_WRONLY, &stdout_xp );
    788         // error3 = vfs_open( process_init->vfs_cwd_xp, NULL, VFS_O_WRONLY, &stderr_xp );
     764    // TODO create inodes for stdin / stdout / stderr pseudo-files
     765    // these inodes should be created in the cluster containing the relevant TXT chdev
     766
     767    // open stdin / stdout / stderr pseudo-files
     768    xptr_t    stdin_xp;
     769    xptr_t    stdout_xp;
     770    xptr_t    stderr_xp;
     771    uint32_t  stdin_id;
     772    uint32_t  stdout_id;
     773    uint32_t  stderr_id;
     774
     775        error1 = vfs_open( XPTR_NULL, CONFIG_DEV_STDIN , O_RDONLY, 0, &stdin_xp , &stdin_id  );
     776        error2 = vfs_open( XPTR_NULL, CONFIG_DEV_STDOUT, O_WRONLY, 0, &stdout_xp, &stdout_id );
     777        error3 = vfs_open( XPTR_NULL, CONFIG_DEV_STDERR, O_WRONLY, 0, &stderr_xp, &stderr_id );
    789778
    790779        if( error1 || error2 || error3 )
    791780        {
    792                 if( !error1 ) vfs_close( stdin_xp  , NULL );
    793                 if( !error2 ) vfs_close( stdout_xp , NULL );
    794                 if( !error3 ) vfs_close( stderr_xp , NULL );
     781                if( !error1 ) vfs_close( stdin_xp  , stdin_id );
     782                if( !error2 ) vfs_close( stdout_xp , stdout_id );
     783                if( !error3 ) vfs_close( stderr_xp , stderr_id );
    795784   
    796785                printk("\n[PANIC] in %s : cannot open stdin/stdout/stderr in cluster %x\n",
     
    799788        }
    800789
    801     // register stdin / stdout / stderr in the fd_array 3 first slots
    802         process_init->fd_array.array[0] = stdin_xp;
    803         process_init->fd_array.array[1] = stdout_xp;
    804         process_init->fd_array.array[2] = stderr_xp;
    805     process_init->fd_array.current  = 3;
     790    // check stdin / stdout / stderr indexes
     791    if( (stdin_id != 0) || (stdout_id != 1) || (stderr_id != 2) )
     792    {
     793                printk("\n[PANIC] in %s : bad indexes for stdin/stdout/stderr in cluster %x\n",
     794            __FUNCTION__ , local_cxy );
     795        hal_core_sleep();
     796    }
    806797
    807798    // initialize the exec_info structure
Note: See TracChangeset for help on using the changeset viewer.