Changeset 407 for trunk/kernel/libk


Ignore:
Timestamp:
Nov 7, 2017, 3:08:12 PM (6 years ago)
Author:
alain
Message:

First implementation of fork/exec.

Location:
trunk/kernel/libk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/libk/elf.c

    r406 r407  
    175175                }
    176176
     177        // get .elf file descriptor cluster and local pointer
     178        cxy_t        file_cxy = GET_CXY( file_xp );
     179        vfs_file_t * file_ptr = (vfs_file_t *)GET_PTR( file_xp );
     180
     181        // get local pointer on .elf file mapper
     182        mapper_t * mapper_ptr = (mapper_t *)hal_remote_lpt( XPTR( file_cxy ,
     183                                                                  &file_ptr->mapper ) );
    177184                // register vseg in VMM
    178185                vseg = (vseg_t *)vmm_create_vseg( process,
     186                                          type,
    179187                                                  vbase,
    180188                                                  mem_size,
    181                                                   type );
     189                                          file_offset,
     190                                          file_size,
     191                                          XPTR( file_cxy , mapper_ptr ),
     192                                                  local_cxy ); 
    182193                if( vseg == NULL )
    183194                {
     
    187198                }
    188199
    189         // get .elf file descriptor cluster and local pointer
    190         cxy_t        file_cxy = GET_CXY( file_xp );
    191         vfs_file_t * file_ptr = (vfs_file_t *)GET_PTR( file_xp );
    192 
    193         // get local pointer on .elf file mapper
    194         mapper_t * mapper_ptr = (mapper_t *)hal_remote_lpt( XPTR( file_cxy ,
    195                                                                   &file_ptr->mapper ) );
    196 
    197         // initialize "file_mapper", "file_offset", "file_size" fields in vseg
    198         vseg->mapper_xp   = XPTR( file_cxy , mapper_ptr );
    199         vseg->file_offset = file_offset;
    200         vseg->file_size   = file_size;
    201 
    202200        // update reference counter in file descriptor
    203201                vfs_file_count_up( file_xp );
    204202
    205                 elf_dmsg("\n[DMSG] %s : found %s vseg / base = %x / size = %x\n"
     203                elf_dmsg("\n[DBG] %s : found %s vseg / base = %x / size = %x\n"
    206204                 "       file_size = %x / file_offset = %x / mapper_xp = %l\n",
    207205            __FUNCTION__ , vseg_type_str(vseg->type) , vseg->min , vseg->max - vseg->min ,
     
    225223        error_t      error;
    226224
    227     elf_dmsg("\n[DMSG] %s : core[%x,%d] enter for <%s>\n",
     225    elf_dmsg("\n[DBG] %s : core[%x,%d] enter for <%s>\n",
    228226    __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , pathname );
    229227
     
    233231
    234232        // open file
    235         error = vfs_open( process->vfs_cwd_xp,
     233        error = vfs_open( process,
    236234                          pathname,
    237235                          O_RDONLY,
     
    245243        }
    246244
    247     elf_dmsg("\n[DMSG] %s : open file <%s>\n", __FUNCTION__ , pathname );
     245    elf_dmsg("\n[DBG] %s : open file <%s>\n", __FUNCTION__ , pathname );
    248246
    249247        // load header in local buffer
     
    258256        }
    259257
    260         elf_dmsg("\n[DMSG] %s : loaded elf header for %s\n", __FUNCTION__ , pathname );
     258        elf_dmsg("\n[DBG] %s : loaded elf header for %s\n", __FUNCTION__ , pathname );
    261259
    262260        if( header.e_phnum == 0 )
     
    295293        }
    296294
    297         elf_dmsg("\n[DMSG] %s : segments array allocated for %s\n", __FUNCTION__ , pathname );
     295        elf_dmsg("\n[DBG] %s : segments array allocated for %s\n", __FUNCTION__ , pathname );
    298296
    299297        // load seg descriptors array to local buffer
     
    312310        }
    313311
    314         elf_dmsg("\n[DMSG] %s loaded segments descriptors for %s \n", __FUNCTION__ , pathname );
     312        elf_dmsg("\n[DBG] %s loaded segments descriptors for %s \n", __FUNCTION__ , pathname );
    315313
    316314        // register loadable segments in process VMM
     
    337335        kmem_free(&req);
    338336
    339     elf_dmsg("\n[DMSG] %s : core[%x,%d] exit for <%s> / entry_point = %x\n",
     337    elf_dmsg("\n[DBG] %s : core[%x,%d] exit for <%s> / entry_point = %x\n",
    340338    __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , pathname , header.e_entry );
    341339
  • trunk/kernel/libk/remote_barrier.c

    r296 r407  
    274274        // block & deschedule the calling thread
    275275        thread_block( thread_ptr , THREAD_BLOCKED_USERSYNC );
    276         sched_yield( NULL );
     276        sched_yield();
    277277
    278278        // restore interrupts
  • trunk/kernel/libk/remote_condvar.c

    r296 r407  
    189189    // block the calling thread
    190190    thread_block( CURRENT_THREAD , THREAD_BLOCKED_USERSYNC );
    191     sched_yield( NULL );
     191    sched_yield();
    192192
    193193    // lock the mutex before return
  • trunk/kernel/libk/remote_fifo.c

    r296 r407  
    3939    uint32_t  slot;
    4040
     41    fifo->owner     = 0;
    4142        fifo->wr_id     = 0;
    4243        fifo->rd_id     = 0;
     
    4748}
    4849
    49 //////////////////////////////////////////////
    50 error_t remote_fifo_put_item( xptr_t     fifo,
    51                               uint64_t   item,
    52                               bool_t   * first )
     50/////////////////////////////////////////////////
     51error_t remote_fifo_put_item( xptr_t     fifo_xp,
     52                              uint64_t   item )
    5353{
    5454    uint32_t        wr_id;
     
    5656    uint32_t        ptw;
    5757    uint32_t        watchdog;
    58     reg_t           save_sr;
    5958    uint32_t        nslots;
    6059
    6160    // get remote cluster identifier and pointer on FIFO
    62     cxy_t           cxy = (cxy_t)GET_CXY( fifo );
    63     remote_fifo_t * ptr = (remote_fifo_t *)GET_PTR( fifo );
     61    cxy_t           fifo_cxy = (cxy_t)GET_CXY( fifo_xp );
     62    remote_fifo_t * fifo_ptr = (remote_fifo_t *)GET_PTR( fifo_xp );
    6463
    6564    // initialise watchdog for contention detection
    6665    watchdog = 0;
    6766
    68     // no descheduling during put access
    69         hal_disable_irq( &save_sr );
    70        
    71     // get write slot index and atomic increment
    72         wr_id = hal_remote_atomic_add( XPTR( cxy , &ptr->wr_id ) , 1 );
     67    // get write slot index with atomic increment
     68        wr_id = hal_remote_atomic_add( XPTR( fifo_cxy , &fifo_ptr->wr_id ) , 1 );
    7369
    74     // check fifo state
     70    // wait until allocated slot is empty in remote FIFO
     71    // max retry = CONFIG_REMOTE_FIFO_MAX_ITERATIONS 
     72    // return error if watchdog is reached
    7573    while( 1 )
    7674    {
    7775        // return error if contention detected by watchdog
    78         if( watchdog > CONFIG_REMOTE_FIFO_MAX_ITERATIONS )
    79         {
    80             // restore scheduling
    81                 hal_restore_irq( save_sr );
    82 
    83             // return error
    84             return EBUSY;
    85         }
     76        if( watchdog > CONFIG_REMOTE_FIFO_MAX_ITERATIONS )  return EBUSY;
    8677
    8778        // read remote rd_id value
    88         rd_id = hal_remote_lw( XPTR( cxy , &ptr->rd_id ) );
     79        rd_id = hal_remote_lw( XPTR( fifo_cxy , &fifo_ptr->rd_id ) );
    8980
    9081        // compute number of full slots
     
    9283        else                 nslots = (0xFFFFFFFF - rd_id) + wr_id;
    9384
    94         // exit if fifo not full
     85        // exit waiting loop as soon as fifo not full
    9586        if ( nslots < CONFIG_REMOTE_FIFO_SLOTS )  break;
    9687       
    97         // restore interrupts
    98             hal_restore_irq( save_sr );
    99 
    100         // deschedule without blocking
    101         if( thread_can_yield() ) sched_yield( NULL );
    102 
    103         // disable interrupts
    104             hal_disable_irq( &save_sr );
     88        // retry later if fifo full:
     89        // - deschedule without blocking if possible
     90        // - wait ~1000 cycles otherwise
     91        if( thread_can_yield() ) sched_yield();
     92        else                     hal_fixed_delay( 1000 );
    10593
    10694        // increment watchdog
     
    112100
    113101    // copy item to fifo
    114         hal_remote_swd( XPTR( cxy , &ptr->data[ptw] ), item );
    115 
     102        hal_remote_swd( XPTR( fifo_cxy , &fifo_ptr->data[ptw] ), item );
    116103        hal_fence();
    117104
    118105    // set the slot valid flag
    119         hal_remote_sw( XPTR( cxy , &ptr->valid[ptw] ) , 1 );
     106        hal_remote_sw( XPTR( fifo_cxy , &fifo_ptr->valid[ptw] ) , 1 );
    120107        hal_fence();
    121 
    122     // return the first RPC flag
    123     *first = ( wr_id == rd_id );
    124    
    125     // restore scheduling
    126         hal_restore_irq( save_sr );
    127108
    128109    return 0;
  • trunk/kernel/libk/remote_fifo.h

    r279 r407  
    2828#include <kernel_config.h>
    2929#include <hal_types.h>
     30#include <printk.h>
    3031#include <errno.h>
    3132#include <hal_remote.h>
    3233
    3334/************************************************************************************
    34  * This structure defines a generic, single reader, multiple writers
    35  * remote FIFO, that is used by the RPCs for inter cluster communications.
    36  * The accesses are implemented using a lock-free algorithm, as it uses a ticket
    37  * based mechanism to handle concurrent access between multiple writers.
    38  * Each FIF0 slot can contain one 64 bits integer.
    39  * In case of FIFO full, the writer deschedule without blocking, to retry later.
    40  *
    41  * WARNING : the number of slots is statically defined by the global
    42  * configuration parameter CONFIG_REMOTE_FIFO_SLOTS for all fifos. requiring
    43  * Each FIFO requires 8 + (12 * CONFIG_REMOTE_FIFO_SLOTS) bytes.
     35 * This structure defines a generic, single reader, multiple writers FIFO,
     36 * that is used for - RPC based - inter cluster communications.
     37 * Each FIF0 slot can contain one 64 bits integer (or one extended pointer).
     38 * The number of slots is defined by the CONFIG_REMOTE_FIFO_SLOTS parameter.
     39 * - The write accesses are implemented using a lock-free algorithm, as it uses
     40 *   a ticket based mechanism to handle concurrent access between multiple writers.
     41 *   In case of FIFO full, the writer deschedule without blocking, to retry later.
     42 * - The reader must take the try_lock implemented by the "owner" field, using
     43 *   an atomic_add(). The TRDID is a good owner identifier, because all
     44 *   RPC threads in a given cluster belong to the same kernel process,
     45 *   and RPC threads cannot have local index LTID = 0.
     46*
     47 * WARNING : Each FIFO requires 12 + (12 * CONFIG_REMOTE_FIFO_SLOTS) bytes.
    4448 ***********************************************************************************/
    4549
    4650typedef struct remote_fifo_s
    4751{
     52    uint32_t           owner;                            /*! owner thread trdid    */
    4853        volatile uint32_t  wr_id;                            /*! write slot index      */
    4954        volatile uint32_t  rd_id;                            /*! read  slot index      */
     
    6368/************************************************************************************
    6469 * This non blocking function tries to get one item from the local fifo.
    65  * The reader must get exclusive access before calling this function. 
     70 * The reader must get exclusive access for read before calling this function. 
    6671 * The read slot index is incremented.
    6772 ************************************************************************************
     
    7580/************************************************************************************
    7681 * This blocking function puts one item to a remote fifo identified
    77  * by an extended pointer.
    78  * This function gets a write ticket using a remote_atomic_increment on the
    79  * write slot. Then, it waits until the slot is empty, using a descheduling
    80  * policy without blocking.
     82 * by an extended pointer. It gets a write ticket on the slot to be written,
     83 * using a remote_atomic_add() on the write slot index. Then, it waits until
     84 * the slot is empty, using a descheduling policy without blocking if required.
     85 * It implements a watchdog, returning when the item has been successfully
     86 * registered, or after CONFIG_REMOTE_FIFO_MAX_ITERATIONS failures.   
    8187 ************************************************************************************
    8288 * @ fifo    : extended pointer to the fifo in remote cluster.
    8389 * @ item    : item to be stored.
    84  * @ first   : [out] true if first item registered in remote fifo.
    8590 * @ return  0 on success / EBUSY if a contention has been detected.
    8691 ***********************************************************************************/
    8792error_t remote_fifo_put_item( xptr_t     fifo,
    88                               uint64_t   item,
    89                               bool_t   * first );
     93                              uint64_t   item );
    9094
    9195/************************************************************************************
  • trunk/kernel/libk/remote_mutex.c

    r296 r407  
    208208        // block & deschedule the calling thread   
    209209        thread_block( thread_ptr , THREAD_BLOCKED_USERSYNC );
    210         sched_yield( NULL );
     210        sched_yield();
    211211
    212212        // restore interrupts
  • trunk/kernel/libk/remote_sem.c

    r296 r407  
    219219        // block and deschedule
    220220        thread_block( this , THREAD_BLOCKED_SEM ); 
    221         sched_yield( NULL );
     221        sched_yield();
    222222        }
    223223}  // end remote_sem_wait()
  • trunk/kernel/libk/remote_spinlock.c

    r337 r407  
    179179                {
    180180                        hal_restore_irq( mode );
    181                         if( thread_can_yield() ) sched_yield( NULL );
     181                        if( thread_can_yield() ) sched_yield();
    182182                        hal_disable_irq( &mode );
    183183                        continue;
  • trunk/kernel/libk/spinlock.c

    r337 r407  
    111111        {
    112112            hal_restore_irq( mode );
    113             if( thread_can_yield() ) sched_yield( NULL );
     113            if( thread_can_yield() ) sched_yield();
    114114            hal_disable_irq( &mode );
    115115            continue;
Note: See TracChangeset for help on using the changeset viewer.