Changeset 23 for trunk/kernel


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

Introduce syscalls.

Location:
trunk/kernel
Files:
9 added
2 deleted
95 edited
4 copied
6 moved

Legend:

Unmodified
Added
Removed
  • trunk/kernel/devices/dev_dma.c

    r3 r23  
    4545void dev_dma_init( chdev_t * chdev )
    4646{
    47     // get implementation index from DMA chdev descriptor
    48     uint32_t impl = chdev->impl;
     47    // get implementation & channel from DMA chdev descriptor
     48    uint32_t impl    = chdev->impl;
     49    uint32_t channel = chdev->channel;
     50
     51    // set chdev name
     52    snprintf( chdev->name , 16 , "dma_%d_%x" , channel , local_cxy );
    4953
    5054    // set field "cmd", "isr", and call the relevant driver init function
     
    5963        assert( false , __FUNCTION__ , "undefined DMA implementation" );
    6064    }
    61 
    62     // get DMA channel index
    63     uint32_t channel = chdev->channel;
    6465
    6566    // get DMA HWI IRQ index
  • trunk/kernel/devices/dev_fbf.c

    r14 r23  
    5757    uint32_t  impl = chdev->impl;
    5858
     59    // set chdev name
     60    strcpy( chdev->name, "fbf" );
    5961    // call driver init function
    6062    if( impl == IMPL_FBF_SCL )
     
    136138    error_t     error;
    137139    paddr_t     buf_paddr;
    138     bool_t      ident = CONFIG_KERNEL_IDENTITY;
    139140
    140141    thread_t * this = CURRENT_THREAD;              // pointer on client thread
    141142
    142143    // Get buffer physical address
    143     error = vmm_v2p_translate( ident , buffer , &buf_paddr );
     144    error = vmm_v2p_translate( CONFIG_KERNEL_IDENTITY_MAP , buffer , &buf_paddr );
    144145 
    145146    if( error )
  • trunk/kernel/devices/dev_icu.c

    r14 r23  
    4747                   uint32_t  pti_nr )
    4848{
     49    // set chdev name
     50    snprintf( icu->name , 16 , "icu_%x" , local_cxy );
     51
    4952    // set ICU chdev extension fields
    5053    icu->ext.icu.hwi_nr     = hwi_nr;
  • trunk/kernel/devices/dev_iob.c

    r14 r23  
    3636    // get implementation
    3737    uint32_t  impl = chdev->impl;
     38
     39    // set chdev name
     40    strcpy( chdev->name , "iob" );
    3841
    3942    // call driver init function
  • trunk/kernel/devices/dev_ioc.c

    r14 r23  
    5555    uint32_t  channel = chdev->channel;
    5656
     57    // set chdev name
     58    strcpy( chdev->name , "ioc" );
     59
    5760    // set driver specific fields in chdev descriptor and call driver init function
    5861    if( impl == IMPL_IOC_BDV )
     
    6467    else if( impl == IMPL_IOC_HBA )
    6568    {
    66         chdev->cmd = &soclib_hba_command;
     69        chdev->cmd = &soclib_hba_cmd;
    6770        chdev->isr = &soclib_hba_isr;
    6871        soclib_hba_init( chdev );
     
    109112//////////////////////////////////////////////////////////////////////////////////
    110113// This static function is called by dev_ioc_read() & dev_ioc_write() functions.
    111 // It builds and registers the command in the calling thread descriptor, after
    112 // translation of buffer virtual address to physical address.
     114// It builds and registers the command in the calling thread descriptor.
    113115// Then, it registers the calling thead in chdev waiting queue.
    114116// Finally it blocks on the THREAD_BLOCKED_DEV condition and deschedule.
    115117////////////////////////////////////i/////////////////////////////////////////////
    116 static error_t dev_ioc_access( bool_t    to_mem,
    117                                char    * buffer,
    118                                uint32_t  lba,
    119                                uint32_t  count )
     118static error_t dev_ioc_access( uint32_t   cmd_type,
     119                               uint8_t  * buffer,
     120                               uint32_t   lba,
     121                               uint32_t   count )
    120122{
    121123    thread_t * this = CURRENT_THREAD;              // pointer on client thread
    122124
    123     error_t     error;
    124     paddr_t     buf_paddr;
    125 
    126     // Get buffer physical address
    127     error = vmm_v2p_translate( CONFIG_KERNEL_IDENTITY , buffer , &buf_paddr );
    128  
    129     if( error )  return EINVAL;
    130 
    131125    ioc_dmsg("\n[INFO] in %s : thread %x in process %x"
    132              " for lba = %x / vaddr = %x / paddr = %l / at cycle %d\n",
     126             " for lba = %x / buffer = %x / at cycle %d\n",
    133127             __FUNCTION__ , this->trdid , this->process->pid ,
    134              lba , (uint32_t)buffer , buf_paddr , hal_time_stamp() );
     128             lba , (intptr_t)buffer , hal_time_stamp() );
    135129
    136130#if USE_IOB    // software L2/L3 cache coherence for memory buffer
    137131
    138     if ( to_mem )  dev_mmc_inval( buf_paddr, count<<9 );
    139     else           dev_mmc_sync( buf_paddr, count<<9 );
     132    if ( type == IOC_READ )  dev_mmc_inval( XPTR( local_cxy , buffer ) , count<<9 );
     133    else                     dev_mmc_sync ( XPTR( local_cxy , buffer ) , count<<9 );
    140134
    141135#endif     // end software L2/L3 cache coherence
     
    148142    // register command in calling thread descriptor
    149143    this->command.ioc.dev_xp    = dev_xp;
    150     this->command.ioc.to_mem    = to_mem;
     144    this->command.ioc.type      = cmd_type;
    151145    this->command.ioc.buf_xp    = XPTR( local_cxy , buffer );
    152146    this->command.ioc.lba       = lba;
     
    169163
    170164////////////////////////////////////////////
    171 error_t dev_ioc_read( char         * buffer,
     165error_t dev_ioc_read( uint8_t      * buffer,
    172166                      uint32_t       lba,
    173167                      uint32_t       count )
    174168{
    175     return dev_ioc_access( true , buffer , lba , count );
     169    return dev_ioc_access( IOC_READ , buffer , lba , count );
    176170
    177171
    178172////////////////////////////////////////////
    179 error_t dev_ioc_write( char         * buffer,
    180                        uint32_t       lba,
    181                        uint32_t       count )
    182 {
    183     return dev_ioc_access( false , buffer , lba , count );
     173error_t dev_ioc_write( uint8_t     * buffer,
     174                       uint32_t      lba,
     175                       uint32_t      count )
     176{
     177    return dev_ioc_access( IOC_WRITE , buffer , lba , count );
    184178}
     179
     180/////////////////////////////////////////////
     181error_t dev_ioc_sync_read( uint8_t  * buffer,
     182                           uint32_t   lba,
     183                           uint32_t   count )
     184{
     185    // get pointer on calling thread
     186    thread_t * this = CURRENT_THREAD;
     187
     188#if USE_IOB    // software L2/L3 cache coherence for memory buffer
     189
     190    dev_mmc_inval( XPTR( local_cxy , buffer ) , count<<9 );
     191
     192#endif         // end software L2/L3 cache coherence
     193
     194    // get extended pointer on IOC[0] chdev
     195    xptr_t  dev_xp = chdev_dir.ioc[0];
     196
     197    assert( (dev_xp != XPTR_NULL) , __FUNCTION__ , "undefined IOC chdev descriptor" );
     198
     199    // register command in calling thread descriptor
     200    this->command.ioc.dev_xp    = dev_xp;
     201    this->command.ioc.type      = IOC_SYNC_READ;
     202    this->command.ioc.buf_xp    = XPTR( local_cxy , buffer );
     203    this->command.ioc.lba       = lba;
     204    this->command.ioc.count     = count;
     205
     206    // get driver command function
     207    cxy_t       dev_cxy = GET_CXY( dev_xp );
     208    chdev_t   * dev_ptr = (chdev_t *)GET_PTR( dev_xp );
     209    dev_cmd_t * cmd = (dev_cmd_t *)hal_remote_lpt( XPTR( dev_cxy , &dev_ptr->cmd ) );
     210
     211    // call directly driver command
     212    cmd( XPTR( local_cxy , this ) );
     213
     214    // return I/O operation status from calling thread descriptor
     215    return this->command.ioc.error;
     216}
     217
  • trunk/kernel/devices/dev_ioc.h

    r14 r23  
    3838 * magnetic hard disk or a SD card, that can store blocks of data in a linear array
    3939 * of sectors indexed by a simple lba (logic block address).
    40  * It supports two command types:
    41  * - READ  : move a given number of contiguous blocks from device to a memory buffer.
    42  * - WRITE : move a given number of contiguous blocks from a memory buffer to device.
    43  *
    44  * An I/O operation requires dynamic ressource allocation, and is always blocking for
    45  * the client thread. The general scenario is detailed below.
     40 * It supports three command types:
     41 * - READ      : move blocks from device to memory, with a descheduling policy.
     42 * - WRITE     : move blocks from memory to device, with a descheduling policy.
     43 * - SYNC_READ : move blocks from device to memory, with a busy waiting policy.
     44
     45 * A READ or WRITE operation requires dynamic ressource allocation. The calling thread
     46 * is descheduled, and the work is done by the server thread associated to IOC device.
     47 * The general scenario is detailed below.
    4648 * A) the client thread start the I/O operation, by calling the dev_ioc_read()
    4749 *    or the dev_ioc_write() kernel functions that perform the following actions:
     
    5052 *    3) it access the PIC to link the WTI mailbox to the IOC IRQ.
    5153 *    4) it builds the command descriptor.
    52  *    5) it registers in the IOCdevice waiting queue.
     54 *    5) it registers in the IOC device waiting queue.
    5355 *    6) itblock on the THREAD_BLOCKED_IO condition and deschedule.
    5456 * B) The server thread attached to the IOC device descriptor handles the commands
     
    6163 *    2) disable the WTI IRQ in the client cluster ICU and update interrupt vector.
    6264 *    3) release the WTI mailbox to the client cluster WTI allocator.
     65 *
     66 * The SYNC_READ operation is used by the kernel in the initialisation phase. It does
     67 * not uses the IOC device waiting queue and server thread, and does not use the IOC IRQ,
     68 * but implement a busy-waiting policy for the calling thread.
    6369 *****************************************************************************************/
    6470
     
    9399 *****************************************************************************************/
    94100
     101enum
     102{
     103    IOC_READ       = 0,
     104    IOC_WRITE      = 1,
     105    IOC_SYNC_READ  = 2,
     106};
     107
    95108typedef struct ioc_command_s
    96109{
    97     xptr_t      dev_xp;      /*! extended pointer on device descriptor                    */
    98     uint32_t    to_mem;     /*! requested operation (WRITE if zero / READ if non-zero)   */
     110    xptr_t      dev_xp;     /*! extended pointer on device descriptor                    */
     111    uint32_t    type;       /*! IOC_READ / IOC_WRITE / IOC_SYNC_READ                     */
    99112    uint32_t    lba;        /*! first block index                                        */
    100113    uint32_t    count;      /*! number of blocks                                         */
     
    119132/******************************************************************************************
    120133 * This blocking function try to tranfer one or several contiguous blocks of data
    121  * from the block device to a memory buffer. The corresponding request is actually
     134 * from the block device to a local memory buffer. The corresponding request is actually
    122135 * registered in the device pending request queue, and the calling thread is descheduled,
    123136 * waiting on transfer completion. It will be resumed by the IRQ signaling completion.
    124137 * It must be called in the client cluster.
    125138 ******************************************************************************************
    126  * @ buffer    : local pointer on target buffer in memory.
     139 * @ buffer    : local pointer on target buffer in memory (must be block aligned).
    127140 * @ lba       : first block index on device.
    128141 * @ count     : number of blocks to transfer.
    129142 * @ returns 0 if success / returns EINVAL if error.
    130143 *****************************************************************************************/
    131 error_t dev_ioc_read( char         * buffer,
     144error_t dev_ioc_read( uint8_t      * buffer,
    132145                      uint32_t       lba,
    133146                      uint32_t       count );
     
    135148/******************************************************************************************
    136149 * This blocking function try to tranfer one or several contiguous blocks of data
    137  * from a memory buffer to the block device. The corresponding request is actually
     150 * from a local memory buffer to the block device. The corresponding request is actually
    138151 * registered in the device pending request queue, and the calling thread is descheduled,
    139152 * waiting on transfer completion. It will be resumed by the IRQ signaling completion.
    140153 * It must be called in the client cluster.
    141154 ******************************************************************************************
    142  * @ buffer    : local pointer on source buffer in memory.
     155 * @ buffer    : local pointer on source buffer in memory (must be block aligned).
    143156 * @ lba       : first block index on device.
    144157 * @ count     : number of blocks to transfer.
    145158 * @ returns 0 if success / returns EINVAL if error.
    146159 *****************************************************************************************/
    147 error_t dev_ioc_write( char         * buffer,
     160error_t dev_ioc_write( uint8_t      * buffer,
    148161                       uint32_t       lba,
    149162                       uint32_t       count );
    150163
     164/******************************************************************************************
     165 * This blocking function try to tranfer one or several contiguous blocks of data
     166 * from the block device to a memory buffer.
     167 * It does  not uses the IOC device waiting queue and server thread, and does not use
     168 * the IOC IRQ, but call directly the relevant OIC driver, implementing a busy-waiting
     169 * policy for the calling thread.
     170 * It must be called in the client cluster.
     171 ******************************************************************************************
     172 * @ buffer    : local pointer on target buffer in memory (must be block aligned).
     173 * @ lba       : first block index on device.
     174 * @ count     : number of blocks to transfer.
     175 * @ returns 0 if success / returns EINVAL if error.
     176 *****************************************************************************************/
     177error_t dev_ioc_sync_read( uint8_t      * buffer,
     178                           uint32_t       lba,
     179                           uint32_t       count );
     180
    151181#endif  /* _DEV_IOC_H */
  • trunk/kernel/devices/dev_mmc.c

    r14 r23  
    4343    // get implementation from device descriptor
    4444    uint32_t  impl = chdev->impl;
     45
     46    // set chdev name
     47    snprintf( chdev->name , 16 , "mmc_%x" , local_cxy );
    4548
    4649    // set driver specific fields in device descriptor and call driver init function
     
    6568
    6669/////////////////////////////////////////////////////////////////////////////
    67 // This static function makes some checking, takes the lock granting
    68 // exclusive access to MMC peripheral, call the driver to execute the command
     70// This static function is called by all MMC device functions.
     71// It makes some checking, takes the lock granting exclusive
     72// access to MMC peripheral, call the driver to execute the command
    6973// registered in the calling thread descriptor, and releases the lock.
    7074/////////////////////////////////////////////////////////////////////////////
    71 static void dev_mmc_access( thread_t * this )
    72 {
    73     mmc_dmsg("\n[INFO] %s enters for thread %x in process %x : command = %d\n",
    74                  __FUNCTION__ , this->trdid , this->process->pid , this->command.mmc.type );
    75 
    76     // get extended pointer on MMC device
    77     xptr_t  dev_xp  = this->command.mmc.dev_xp;
    78 
    79     assert( (dev_xp != XPTR_NULL) , __FUNCTION__ , "undefined MMC device descriptor" );
     75static error_t dev_mmc_access( thread_t * this )
     76{
     77    // get extended pointer on MMC device descriptor
     78    xptr_t  dev_xp = this->command.mmc.dev_xp;
     79
     80    assert( (dev_xp != XPTR_NULL) , __FUNCTION__ , "target MMC device undefined" );
    8081
    8182    // get MMC device cluster identifier & local pointer
     
    9596    remote_spinlock_unlock( XPTR( dev_cxy , &dev_ptr->wait_lock ) ); 
    9697
    97     mmc_dmsg("\n[INFO] %s completes for thread %x in process %x / error = %d\n",
    98                  __FUNCTION__ , this->trdid , this->process->pid , this->dev.ioc.error );
     98    // return operation status
     99    return this->command.mmc.error; 
    99100
    100101}  // end dev_mmc_access()
    101102
    102 ////////////////////////////////////////////
    103 error_t dev_mmc_inval( paddr_t    buf_paddr,
     103/////////////////////////////////////////
     104error_t dev_mmc_inval( xptr_t     buf_xp,
    104105                       uint32_t   buf_size )
    105106{
    106     // get calling thread local pointer
    107     thread_t * this = CURRENT_THREAD;
    108 
    109     // get target cluster from paddr
    110     cxy_t cxy = CXY_FROM_PADDR( buf_paddr );
    111 
    112     assert( ((buf_paddr & (CONFIG_CACHE_LINE_SIZE -1)) == 0) , __FUNCTION__ ,
     107    error_t error;
     108
     109    // get calling thread local pointer
     110    thread_t * this = CURRENT_THREAD;
     111
     112    mmc_dmsg("\n[INFO] %s enters for thread %x in process %x / buf_xp = %l\n",
     113                 __FUNCTION__ , this->trdid , this->process->pid , buf_xp );
     114
     115    // get buffer cluster and local pointer
     116    cxy_t  buf_cxy = GET_CXY( buf_xp );
     117    void * buf_ptr = GET_PTR( buf_xp );
     118   
     119    assert( (((intptr_t)buf_ptr & (CONFIG_CACHE_LINE_SIZE -1)) == 0) , __FUNCTION__ ,
    113120             "buffer not aligned on cache line" );
    114121
    115     // get extended pointer on MMC device descriptor
    116     xptr_t  dev_xp = chdev_dir.mmc[cxy];
    117 
    118     // store command arguments in thread descriptor
    119     this->command.mmc.dev_xp    = dev_xp;
     122    // get buffer physical address
     123    paddr_t  buf_paddr;
     124    error = vmm_v2p_translate( CONFIG_KERNEL_IDENTITY_MAP , buf_ptr , &buf_paddr );
     125
     126    assert( (error == 0) , __FUNCTION__ , "cannot get buffer paddr" );
     127
     128    // store command arguments in thread descriptor
     129    this->command.mmc.dev_xp    = chdev_dir.mmc[buf_cxy];
    120130    this->command.mmc.type      = MMC_CC_INVAL;
    121131    this->command.mmc.buf_paddr = buf_paddr;
    122132    this->command.mmc.buf_size  = buf_size;
    123133
    124     // execute operation
    125     dev_mmc_access( this );
    126 
    127     // return operation status
    128     return this->command.mmc.error; 
    129 
    130 
    131 /////////////////////////////////////
    132 error_t dev_mmc_sync( paddr_t    buf_paddr,
     134    // call MMC driver
     135    error = dev_mmc_access( this );
     136
     137    mmc_dmsg("\n[INFO] %s completes for thread %x in process %x / error = %d\n",
     138             __FUNCTION__ , this->trdid , this->process->pid , error );
     139
     140    return error;
     141}
     142
     143////////////////////////////////////////
     144error_t dev_mmc_sync( xptr_t     buf_xp,
    133145                      uint32_t   buf_size )
    134146{
    135     // get calling thread local pointer
    136     thread_t * this = CURRENT_THREAD;
    137 
    138     // get target cluster from paddr
    139     cxy_t cxy = CXY_FROM_PADDR( buf_paddr );
    140 
    141     assert( ((buf_paddr & (CONFIG_CACHE_LINE_SIZE -1)) == 0) , __FUNCTION__ ,
     147    error_t error;
     148
     149    // get calling thread local pointer
     150    thread_t * this = CURRENT_THREAD;
     151
     152    mmc_dmsg("\n[INFO] %s enters for thread %x in process %x / buf_xp = %l\n",
     153                 __FUNCTION__ , this->trdid , this->process->pid , buf_xp );
     154
     155    // get buffer cluster and local pointer
     156    cxy_t  buf_cxy = GET_CXY( buf_xp );
     157    void * buf_ptr = GET_PTR( buf_xp );
     158   
     159    assert( (((intptr_t)buf_ptr & (CONFIG_CACHE_LINE_SIZE -1)) == 0) , __FUNCTION__ ,
    142160             "buffer not aligned on cache line" );
    143161
    144     // store command arguments in thread descriptor
    145     this->command.mmc.dev_xp    = chdev_dir.mmc[cxy];
     162    // get  buffer physical address
     163    paddr_t  buf_paddr;
     164    error = vmm_v2p_translate( CONFIG_KERNEL_IDENTITY_MAP , buf_ptr , &buf_paddr );
     165
     166    assert( (error == 0) , __FUNCTION__ , "cannot get buffer paddr" );
     167
     168    // store command arguments in thread descriptor
     169    this->command.mmc.dev_xp    = chdev_dir.mmc[buf_cxy];
    146170    this->command.mmc.type      = MMC_CC_SYNC;
    147171    this->command.mmc.buf_paddr = buf_paddr;
    148172    this->command.mmc.buf_size  = buf_size;
    149173
    150     // execute operation
    151     dev_mmc_access( this );
    152 
    153     // return operation status
    154     return this->command.mmc.error; 
    155 
     174    // call MMC driver
     175    error = dev_mmc_access( this );
     176
     177    mmc_dmsg("\n[INFO] %s completes for thread %x in process %x / error = %d\n",
     178                 __FUNCTION__ , this->trdid , this->process->pid , error );
     179
     180    return error;
     181}
    156182
    157183/////////////////////////////////////////
     
    170196
    171197    // execute operation
    172     dev_mmc_access( this );
    173 
    174     // return operation status
    175     return this->command.mmc.error; 
     198    return dev_mmc_access( this );
    176199}
    177200                       
     
    191214
    192215    // execute operation
    193     dev_mmc_access( this );
    194 
    195     // return operation status
    196     return this->command.mmc.error; 
     216    return dev_mmc_access( this );
    197217}
    198218                       
     
    212232
    213233    // execute operation
    214     dev_mmc_access( this );
    215 
    216     // return operation status
    217     return this->command.mmc.error; 
    218 }
    219 
     234    return dev_mmc_access( this );
     235}
     236
  • trunk/kernel/devices/dev_mmc.h

    r14 r23  
    8181typedef struct mmc_command_s
    8282{
    83     xptr_t      dev_xp;     /*! extended pointer on the relevant MMC device descriptor  */
     83    xptr_t      dev_xp;     /*! extended pointer on target MMC device descriptor        */
    8484    uint32_t    type;       /*! CC_INVAL / CC_SYNC / GET_ERROR / SET_ERROR / GET_INSTRU */
    85     paddr_t     buf_paddr;  /*! buffer physical address          (used by INVAL/SYNC)   */
    86     uint32_t    buf_size;   /*! buffer size in bytes             (used by INVAL/SYNC)   */
    87     uint32_t    reg_index;  /*! register index in MMC peripheral (used by SET/GET)      */
    88     uint32_t  * reg_ptr;    /*! local pointer on src/dst buffer  (used by SET/GET)      */
     85    paddr_t     buf_paddr;  /*! physical address of memory buffer (used by INVAL/SYNC)  */
     86    uint32_t    buf_size;   /*! buffer size in bytes              (used by INVAL/SYNC)  */
     87    uint32_t    reg_index;  /*! register index in MMC peripheral  (used by SET/GET)     */
     88    uint32_t  * reg_ptr;    /*! local pointer on src/dst buffer   (used by SET/GET)     */
    8989    error_t     error;      /*! operation status (0 if success)                         */
    9090}
     
    106106 * to access both the MMC device descriptor, and the L2 cache configuration interface.
    107107 *****************************************************************************************
    108  * @ buf_paddr  : buffer local physical addresse.
     108 * @ buf_xp     : extended pointer on memory buffer.
    109109 * @ buf_size   : buffer size (bytes).
    110110 * @ return 0 if success / return EINVAL if failure
    111111 ****************************************************************************************/
    112 error_t dev_mmc_inval( paddr_t   buf_paddr,
    113                        uint32_t  buf_size );
     112error_t dev_mmc_inval( xptr_t     buf_xp,
     113                       uint32_t   buf_size );
    114114
    115115/*****************************************************************************************
     
    119119 * to access both the MMC device descriptor, and the L2 cache configuration interface.
    120120 *****************************************************************************************
    121  * @ buf_paddr  : buffer local physical addresse.
     121 * @ buf_xp     : extended pointer on memory buffer.
    122122 * @ buf_size   : buffer size (bytes).
    123123 * @ return 0 if success / return EINVAL if failure
    124124 ****************************************************************************************/
    125 error_t dev_mmc_sync( paddr_t    buf_paddr,
     125error_t dev_mmc_sync( xptr_t     buf_xp,
    126126                      uint32_t   buf_size );
    127127                       
  • trunk/kernel/devices/dev_nic.c

    r3 r23  
    5151    uint32_t  channel = chdev->channel;
    5252
     53    // set chdev name
     54    snprintf( chdev->name , 16 , "nic_%d" , chdev->channel );
     55
    5356    // set driver specific fields in chdev descriptor and call driver init function
    5457    if( impl == IMPL_NIC_SOC )
  • trunk/kernel/devices/dev_pic.c

    r3 r23  
    4949    uint32_t impl = chdev->impl;
    5050
     51    // set chdev name
     52    strcpy( chdev->name , "pic" );
     53 
    5154    // call the relevant driver init function
    5255    if( impl == IMPL_PIC_SOC )
  • trunk/kernel/devices/dev_txt.c

    r16 r23  
    5050    uint32_t  impl    = chdev->impl;
    5151    uint32_t  channel = chdev->channel;
     52
     53    // set chdev name
     54    snprintf( chdev->name , 16 , "txt_%d" , chdev->channel );
    5255
    5356    // set fields "cmd", "isr", and call driver init function
     
    164167    xptr_t  dev_xp = chdev_dir.txt[channel];
    165168
     169    assert( (dev_xp != XPTR_NULL) , __FUNCTION__ , "undefined TXT0 chdev descriptor" );
     170
    166171    // register command in calling thread
    167172    this->command.txt.dev_xp  = dev_xp;
  • trunk/kernel/devices/dev_txt.h

    r14 r23  
    106106
    107107/******************************************************************************************
    108  * This blocking function writes a character string on the terminal identified
     108 * This blocking function writes  characters on the terminal identified
    109109 * by the "channel" argument. The corresponding request is actually registered in the
    110110 * chdev requests queue, and the calling thread is descheduled, blocked until
  • trunk/kernel/drivers/soclib/soclib_bdv.c

    r4 r23  
    5353void __attribute__ ((noinline)) soclib_bdv_cmd( xptr_t th_xp )
    5454{
    55     uint32_t   to_mem;       // command argument
     55    uint32_t   cmd_type;     // IOC_READ / IOC_WRITE / IOC_SYNC_READ
    5656    uint32_t   lba;          // command argument
    5757    uint32_t   count;        // command argument
     
    6464
    6565    // get command arguments and extended pointer on IOC device
    66     to_mem =         hal_remote_lw ( XPTR( th_cxy , &th_ptr->command.ioc.to_mem ) );
    67     lba    =         hal_remote_lw ( XPTR( th_cxy , &th_ptr->command.ioc.lba    ) );
    68     count  =         hal_remote_lw ( XPTR( th_cxy , &th_ptr->command.ioc.count  ) );
    69     buf_xp = (xptr_t)hal_remote_lwd( XPTR( th_cxy , &th_ptr->command.ioc.buf_xp ) );
    70     dev_xp = (xptr_t)hal_remote_lwd( XPTR( th_cxy , &th_ptr->command.ioc.dev_xp ) );
     66    cmd_type =         hal_remote_lw ( XPTR( th_cxy , &th_ptr->command.ioc.type  ) );
     67    lba      =         hal_remote_lw ( XPTR( th_cxy , &th_ptr->command.ioc.lba    ) );
     68    count    =         hal_remote_lw ( XPTR( th_cxy , &th_ptr->command.ioc.count  ) );
     69    buf_xp   = (xptr_t)hal_remote_lwd( XPTR( th_cxy , &th_ptr->command.ioc.buf_xp ) );
     70    dev_xp   = (xptr_t)hal_remote_lwd( XPTR( th_cxy , &th_ptr->command.ioc.dev_xp ) );
    7171
    7272    // get IOC device cluster and local pointer
     
    8585    uint32_t   buf_msb = (uint32_t)(buf_xp>>32);
    8686
    87     // get access type
    88     uint32_t   type =  to_mem ? BDV_OP_READ : BDV_OP_WRITE;
     87    // set operation
     88    uint32_t   op;
     89    if( cmd_type == IOC_WRITE ) op = BDV_OP_WRITE;
     90    else                        op = BDV_OP_READ;
    8991
    9092    // set SOCLIB_BDV registers to start one I/O operation
     
    9496    hal_remote_sw( XPTR( bdv_cxy , bdv_ptr + BDV_LBA_REG        ) , lba     );
    9597    hal_remote_sw( XPTR( bdv_cxy , bdv_ptr + BDV_COUNT_REG      ) , count   );
    96     hal_remote_sw( XPTR( bdv_cxy , bdv_ptr + BDV_OP_REG         ) , type    );
     98    hal_remote_sw( XPTR( bdv_cxy , bdv_ptr + BDV_OP_REG         ) , op      );
    9799
    98     // Block and deschedule server thread
    99     thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR );
    100     sched_yield();
     100    // waiting policy  depends on the command type
     101
     102    if( cmd_type == IOC_SYNC_READ )                  // polling policy
     103    {
     104        uint32_t status;
     105        while (1)
     106        {
     107            status = hal_remote_lw( XPTR( bdv_cxy , bdv_ptr + BDV_STATUS_REG ) );
     108
     109            if( status == BDV_READ_SUCCESS ) // successfully completed
     110            {
     111                hal_remote_sw( XPTR( th_cxy , &th_ptr->command.ioc.error ) , 0 );
     112                break;
     113            }
     114            else if( status == BDV_BUSY )   // non completed
     115            {
     116                continue;
     117            }
     118            else                            // error reported
     119            {
     120                hal_remote_sw( XPTR( th_cxy , &th_ptr->command.ioc.error ) , 1 );
     121                break;
     122            }
     123        }
     124    }
     125    else                                            // descheduling + IRQ policy
     126    {
     127        thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR );
     128        sched_yield();
     129    }
    101130   
    102131} // end soclib_bdv_cmd()
  • trunk/kernel/drivers/soclib/soclib_hba.c

    r4 r23  
    7272    chdev->ext.ioc.count = block_count;
    7373
    74         // reset SOCLIB_HBA driver global variables
     74    // activate HBA interrupts
     75    hal_remote_sw( XPTR( hba_cxy , hba_ptr + HBA_PXIE_REG ) , 0x1 );
     76
     77        // reset SOCLIB_HBA driver global variable
    7578    hba_active_slots = 0;
    7679
     
    7881
    7982
    80 //////////////////////////////////////////////////////////////////
    81 void __attribute__ ((noinline)) soclib_hba_command( xptr_t th_xp )
     83//////////////////////////////////////////////////////////////
     84void __attribute__ ((noinline)) soclib_hba_cmd( xptr_t th_xp )
    8285{
    8386
    84     uint32_t           to_mem;       // to_mem : command argument
     87    uint32_t           cmd_type;     // IOC_READ / IOC_WRITE / IOC_SYNC_READ
    8588    uint32_t           lba;          // lba    : command argument
    8689    uint32_t           count;        // count  : command argument
    8790    xptr_t             buf_xp;       // buffer : command argument
    8891    xptr_t             dev_xp;       // device : command argument
     92
    8993    uint32_t           cmd_id;       // current slot index in command bit_vector
    9094    hba_cmd_desc_t   * cmd_desc;     // command descriptor pointer   
    9195    hba_cmd_table_t  * cmd_table;    // command table pointer
     96
    9297    bool_t             found;
    9398    uint32_t           iter;
     
    98103
    99104    // get command arguments and extended pointer on IOC device
    100     to_mem    =         hal_remote_lw ( XPTR( th_cxy , &th_ptr->command.ioc.to_mem ) );
     105    cmd_type  =         hal_remote_lw ( XPTR( th_cxy , &th_ptr->command.ioc.type  ) );
    101106    lba       =         hal_remote_lw ( XPTR( th_cxy , &th_ptr->command.ioc.lba    ) );
    102107    count     =         hal_remote_lw ( XPTR( th_cxy , &th_ptr->command.ioc.count  ) );
     
    135140        }
    136141
    137         if( found )  // register and starts the I/O operation
     142        if( found )  // slot available in SOCLIB_HBA
    138143        {
    139144            // compute pointers on command descriptor and command table   
     
    157162            cmd_desc->prdtl[0] = 1;
    158163            cmd_desc->prdtl[1] = 0;
    159             if( to_mem ) cmd_desc->flag[0] = 0x00;
    160             else         cmd_desc->flag[0] = 0x40;     
     164            if( cmd_type == IOC_WRITE ) cmd_desc->flag[0] = 0x40;
     165            else                        cmd_desc->flag[0] = 0x00;     
    161166
    162167#if USE_IOB // software L2/L3 cache coherence
    163168
    164             // compute physical addresses
    165             paddr_t   cmd_desc_paddr;    // command descriptor physical address
    166             paddr_t   cmd_table_paddr;   // command table header physical address
    167             bool_t    ident = CONFIG_KERNEL_IDENTITY;
    168            
    169             error = vmm_v2p_translate( ident , cmd_table , &cmd_table_paddr );
    170             if( error )
    171             {
    172                 printk("\n[PANIC] in %s : cannot get paddr fo cmd_table\n", __FUNCTION__ );
    173                 hal_core_sleep()
    174             }
    175 
    176             error = vmm_v2p_translate( ident , cmd_desc , &cmd_desc_paddr );
    177             if( error )
    178             {
    179                 printk("\n[PANIC] in %s : cannot get paddr fo cmd_desc\n", __FUNCTION__ );
    180                 hal_core_sleep()
    181             }
    182 
    183             // update L3 for command table
    184             dev_mmc_sync( cmd_table_paddr , sizeof(hba_cmd_table_t) );
    185 
    186             // update L3 for command descriptor
    187             dev_mmc_sync( cmd_desc_paddr , sizeof(hba_cmd_desc_t) );
     169            dev_mmc_sync( cmd_table , sizeof(hba_cmd_table_t) );
     170            dev_mmc_sync( cmd_desc , sizeof(hba_cmd_desc_t) );
    188171
    189172#endif // end software L2/L3 cache coherence
    190 
    191             // activates HBA interrupts
    192             hal_remote_sw( XPTR( hba_cxy , hba_ptr + HBA_PXIE_REG ) , 0x1 );
    193173
    194174            // set hba_owner_thread[slot]
    195175            hba_owner_thread[cmd_id] = th_xp;
    196176
     177            // register slot in bit_vector
     178            hba_active_slots |= 1<<cmd_id;
     179 
    197180            // set HBA_PXCI_REG to start transfer
    198181            hal_remote_sw( XPTR( hba_cxy , hba_ptr + HBA_PXCI_REG ) , 1<<cmd_id );
    199182
    200             ioc_dmsg("INFO in %s : thread %x / buffer = %llx at cycle %d\n",
    201             __FUNCTION__ , hal_remote_lw( XPTR( th_cxy , &th_ptr->trdid ) ) ,
    202             buf_xp , hal_time_stamp() );
    203 
    204183            // exit the while
    205184            break;
    206185        }
    207         else   // deschedule if no slot available in SOCLIB_HBA
    208         {
    209             sched_yield();
    210         }
    211     }  // end while
     186        else   // no slot available in SOCLIB_HBA
     187        {
     188            if( cmd_type == IOC_SYNC_READ )     // fatal if synchronous access
     189            {
     190                printk("\n[PANIC] in %s : no slot available for a SYNC_READ\n", __FUNCTION__ );
     191                hal_core_sleep();
     192            }
     193            else                                // retry if asynchronous access.
     194            {
     195                sched_yield();
     196            }
     197        }
     198    }  // end while to get a slot
     199
     200    // waiting policy depends on the command type
     201
     202    if( cmd_type == IOC_SYNC_READ )                // polling, busy waiting
     203    {
     204        uint32_t  pxis;
     205        uint32_t  pxci;
     206        uint32_t  error;
     207        uint32_t  fault_id;
     208        while(1)
     209        {
     210            pxis     = hal_remote_lw( XPTR( hba_cxy , hba_ptr + HBA_PXIS_REG ) );
     211            pxci     = hal_remote_lw( XPTR( hba_cxy , hba_ptr + HBA_PXCI_REG ) );
     212            error    = (pxis & 0x40000000) >> 30;
     213            fault_id = (pxis & 0x1F000000) >> 24;
     214
     215            if( (pxci & (1<<cmd_id)) == 0 )  // completed
     216            {
     217                // release slot
     218                hba_active_slots &= ~(1<<cmd_id);
     219
     220                // set operation status in client thread command
     221                if( error && (fault_id == cmd_id) )
     222                {
     223                    hal_remote_sw( XPTR( th_cxy , &th_ptr->command.ioc.error ) , 1 );
     224                }
     225                else
     226                {
     227                    hal_remote_sw( XPTR( th_cxy , &th_ptr->command.ioc.error ) , 0 );
     228                }
     229
     230                // exit while
     231                break;
     232            }   
     233        }
     234    }
     235    else                                           // descheduling + IRQ
     236    {
     237        thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR );
     238        sched_yield();
     239    }
    212240           
    213241} // end soclib_hba_cmd()
     
    229257    uint32_t * hba_ptr  = (uint32_t *)GET_PTR( chdev->base );
    230258
    231     // get HBA_PXIS_REG and HBA_PXIS_REG current values
     259    // get HBA_PXIS_REG and HBA_PXCI_REG current values
    232260    uint32_t current_pxis = hal_remote_lw( XPTR( hba_cxy , hba_ptr + HBA_PXIS_REG ) );
    233261    uint32_t current_pxci = hal_remote_lw( XPTR( hba_cxy , hba_ptr + HBA_PXCI_REG ) );
  • trunk/kernel/drivers/soclib/soclib_hba.h

    r4 r23  
    145145 * @ xp_thread  : extended pointer on the client thread.
    146146 *******************************************************************************************/
    147 extern void soclib_hba_command( xptr_t  thread_xp );
     147extern void soclib_hba_cmd( xptr_t  thread_xp );
    148148
    149149/********************************************************************************************
  • trunk/kernel/kern/chdev.c

    r16 r23  
    3232#include <rpc.h>
    3333#include <chdev.h>
     34#include <devfs.h>
    3435
    3536////////////////////////////////////////////
  • trunk/kernel/kern/chdev.h

    r16 r23  
    4141 * This file defines the kernel representation of a generic (i.e. implementation
    4242 * independant) Channel Device descriptor (in brief "chdev").
    43  * ALMOS-MKH supports multi-channels peripherals, and defines one separated descriptor
    44  * for each channel (and for each RX/TX direction for the NIC device).
     43 * ALMOS-MKH supports multi-channels peripherals, and defines one separated chdev
     44 * descriptor for each channel (and for each RX/TX direction for the NIC device).
    4545 * Each chdev contains a waiting queue, registering the "client threads" requests,
    4646 * and an associated "server thread", handling these requests.
     
    107107/******************************************************************************************
    108108 * This structure defines a chdev descriptor.
    109  * There is one chdev descriptor per channel.
     109 * For multi-channels device, there is one chdev descriptor per channel.
    110110 * This structure is NOT replicated, and can be located in any cluster.
    111111 * One kernel thread, in charge of handling the commands registered in the waiting queue
     
    120120    uint32_t             channel;     /*! channel index                                  */
    121121    bool_t               is_rx;       /*! relevant for NIC peripheral channels only      */
    122         xptr_t               base;        /*! extended pointer on channel segment            */
     122        xptr_t               base;        /*! extended pointer on channel segment paddr      */
     123    char                 name[16];    /*! name (required by DEVFS)                       */
    123124
    124125    dev_cmd_t          * cmd;         /*! local pointer on driver command function       */
  • trunk/kernel/kern/cluster.c

    r19 r23  
    44 * Author  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
     
    4949///////////////////////////////////////////////////////////////////////////////////////////
    5050
    51 process_t process_zero;     // allocated in kernel_init.c file
     51extern process_t process_zero;     // allocated in kernel_init.c file
    5252
    5353
     
    121121
    122122    // initialise local_list in process manager
    123         spinlock_init( &cluster->pmgr.local_lock );
    124     list_root_init( &cluster->pmgr.local_root );
     123        remote_spinlock_init( XPTR( local_cxy , &cluster->pmgr.local_lock ) );
     124    xlist_root_init( XPTR( local_cxy , &cluster->pmgr.local_root ) );
    125125    cluster->pmgr.local_nr = 0;
    126126
     
    162162{
    163163    cluster_t * cluster = LOCAL_CLUSTER;
    164         hal_atomic_inc( &cluster->cores_in_kernel );
     164        hal_atomic_add( &cluster->cores_in_kernel , 1 );
    165165}
    166166
     
    169169{
    170170    cluster_t * cluster = LOCAL_CLUSTER;
    171         hal_atomic_dec( &cluster->cores_in_kernel );
     171        hal_atomic_add( &cluster->cores_in_kernel , -1 );
    172172}
    173173
     
    199199xptr_t cluster_get_reference_process_from_pid( pid_t pid )
    200200{
    201     xptr_t xp;   // extended pointer on process descriptor
     201    xptr_t ref_xp;   // extended pointer on reference process descriptor
    202202
    203203    cluster_t * cluster = LOCAL_CLUSTER;
     
    208208
    209209    // Check valid PID
    210     if( lpid >= CONFIG_MAX_PROCESS_PER_CLUSTER )
    211     {
    212         printk("\n[PANIC] in %s : illegal PID\n", __FUNCTION__ );
    213         hal_core_sleep();
    214     }
     210    if( lpid >= CONFIG_MAX_PROCESS_PER_CLUSTER )  return XPTR_NULL;
    215211
    216212    if( local_cxy == owner_cxy )   // local cluster is owner cluster
    217213    {
    218         xp = cluster->pmgr.pref_tbl[lpid];
     214        ref_xp = cluster->pmgr.pref_tbl[lpid];
    219215    }
    220216    else                              // use a remote_lwd to access owner cluster
    221217    {
    222         xp = (xptr_t)hal_remote_lwd( XPTR( owner_cxy , &cluster->pmgr.pref_tbl[lpid] ) );
    223     }
    224 
    225     return xp;
     218        ref_xp = (xptr_t)hal_remote_lwd( XPTR( owner_cxy , &cluster->pmgr.pref_tbl[lpid] ) );
     219    }
     220
     221    return ref_xp;
    226222}
    227223
     
    303299process_t * cluster_get_local_process_from_pid( pid_t pid )
    304300{
    305     process_t    * ret     = NULL;
    306     list_entry_t * root    = &LOCAL_CLUSTER->pmgr.local_root;
    307     list_entry_t * iter;
    308     process_t    * process;
    309 
    310     LIST_FOREACH( root , iter )
    311     {
    312         process = LIST_ELEMENT( iter , process_t , local_list );
    313         if( process->pid == pid )
     301    xptr_t         process_xp;
     302    process_t    * process_ptr;
     303    xptr_t         root_xp;
     304    xptr_t         iter_xp;
     305    bool_t         found;
     306
     307    found   = false;
     308    root_xp = XPTR( local_cxy , &LOCAL_CLUSTER->pmgr.local_root );
     309
     310    XLIST_FOREACH( root_xp , iter_xp )
     311    {
     312        process_xp  = XLIST_ELEMENT( iter_xp , process_t , local_list );
     313        process_ptr = (process_t *)GET_PTR( process_xp );
     314        if( process_ptr->pid == pid )
    314315        {
    315             ret = process;
     316            found = true;
    316317            break;
    317318        }
    318319    }
    319     return ret;
     320
     321    if (found ) return process_ptr;
     322    else        return NULL;
    320323
    321324}  // end cluster_get_local_process_from_pid()
     
    327330
    328331    // get lock protecting the process manager local list
    329     spinlock_lock( &pm->local_lock );
    330 
    331     list_add_first( &pm->local_root , &process->local_list );
     332    remote_spinlock_lock( XPTR( local_cxy , &pm->local_lock ) );
     333
     334    xlist_add_first( XPTR( local_cxy , &pm->local_root ),
     335                     XPTR( local_cxy , &process->local_list ) );
    332336    pm->local_nr++;
    333337
    334338    // release lock protecting the process manager local list
    335     spinlock_unlock( &pm->local_lock );
     339    remote_spinlock_unlock( XPTR( local_cxy , &pm->local_lock ) );
    336340}
    337341
     
    342346
    343347    // get lock protecting the process manager local list
    344     spinlock_lock( &pm->local_lock );
    345 
    346     list_unlink( &process->local_list );
     348    remote_spinlock_lock( XPTR( local_cxy , &pm->local_lock ) );
     349
     350    xlist_unlink( XPTR( local_cxy , &process->local_list ) );
    347351    pm->local_nr--;
    348352
    349353    // release lock protecting the process manager local list
    350     spinlock_unlock( &pm->local_lock );
     354    remote_spinlock_unlock( XPTR( local_cxy , &pm->local_lock ) );
    351355}
    352356
  • trunk/kernel/kern/cluster.h

    r19 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
     
    4949struct core_s;
    5050struct process_s;
    51 struct device_s;
    5251
    5352
     
    5655 * For any process P, the process descriptor is replicated in all clusters containing
    5756 * at least one thread of process P, but only the "reference" cluster descriptor contains
    58  * the reference (complete) structures such as the GPT, the VSL, or the FDT.
    59  * The "owner" cluster is in charge to allocate a lpid (local process index),
    60  * for all process owned by a cluster K, and to register the "reference" cluster for
    61  * all process owned by K.
     57 * the reference (complete) GPT, VSL, and FDT structures.
     58 * The "owner" cluster K is in charge to allocate a lpid (local process index),
     59 * to the owned processes, and to register the "reference" cluster for these processes.
    6260 *
    6361 * Warning : the "owner" cluster, and the "reference" cluster can be different clusters.
    6462 *
    6563 * The process manager of a cluster K maintains three structures:
    66  * 1) The pref_tbl[] is an array indexed by lpid, for all processes owned by cluster K.
     64 * 1) The pref_tbl[] is an array indexed by lpid. There is one entry per owned process.
    6765 *    Each entry contains an extended pointer on the reference process descriptor.
     66 *
    6867 * 2) The local_root is the root of the local list of process descriptors in cluster K.
    6968 *    A process descriptor P is present in K, as soon as P has a thread in cluster K.
    70  * 3) The copies_root[] array is indexed by lpid. Each entry contains the root of
    71  *    the xlist of copies for a given process owned by cluster K.
     69 *
     70 * 3) The copies_root[] array is indexed by lpid. There is one entry per owned process,
     71 *    and each each entry contains the root of the xlist of copies for this process.
    7272 ******************************************************************************************/
    7373
     
    7878    uint32_t          pref_nr;                /*! number of processes owned by cluster    */
    7979
    80     list_entry_t      local_root;             /*! root of list of process in cluster      */
    81     spinlock_t        local_lock;             /*! lock protecting access to local list    */
     80    xlist_entry_t     local_root;             /*! root of list of process in cluster      */
     81    remote_spinlock_t local_lock;             /*! lock protecting access to local list    */
    8282    uint32_t          local_nr;               /*! number of process in cluster            */
    8383
     
    9696typedef struct cluster_s
    9797{
    98         spinlock_t        kcm_lock;           /*! local, protect creation of KCM allocators   */
     98        spinlock_t        kcm_lock;        /*! local, protect creation of KCM allocators      */
    9999
    100100    // global parameters
    101101
    102         uint32_t          paddr_width;        /*! numer of bits in physical address           */
    103     uint32_t          x_width;            /*! number of bits to code x_size  (can be 0)   */
    104     uint32_t          y_width;            /*! number of bits to code y_size  (can be 0)   */
    105         uint32_t          x_size;             /*! number of clusters in a row    (can be 1)   */
    106         uint32_t          y_size;             /*! number of clusters in a column (can be 1)   */
    107         cxy_t             io_cxy;             /*! io cluster identifier                       */
    108     uint32_t          dqdt_root_level;    /*! index of root node in dqdt_tbl[]            */
     102        uint32_t          paddr_width;     /*! numer of bits in physical address              */
     103    uint32_t          x_width;         /*! number of bits to code x_size  (can be 0)      */
     104    uint32_t          y_width;         /*! number of bits to code y_size  (can be 0)      */
     105        uint32_t          x_size;          /*! number of clusters in a row    (can be 1)      */
     106        uint32_t          y_size;          /*! number of clusters in a column (can be 1)      */
     107        cxy_t             io_cxy;          /*! io cluster identifier                          */
     108    uint32_t          dqdt_root_level; /*! index of root node in dqdt_tbl[]               */
    109109
    110110    // local parameters
    111111
    112         uint32_t          cores_nr;           /*! number of cores in cluster                  */
    113     uint32_t          cores_in_kernel;    /*! number of cores currently in kernel mode    */
     112        uint32_t          cores_nr;        /*! number of cores in cluster                     */
     113    uint32_t          cores_in_kernel; /*! number of cores currently in kernel mode       */
    114114
    115115        core_t            core_tbl[CONFIG_MAX_LOCAL_CORES];         /*! embedded cores        */
    116116
    117         ppm_t             ppm;                /*! embedded kernel page manager                */
    118         khm_t             khm;                /*! embedded kernel heap manager                */
    119         kcm_t             kcm;                /*! embedded kernel cache manager (for KCMs)    */
     117        ppm_t             ppm;             /*! embedded kernel page manager                   */
     118        khm_t             khm;             /*! embedded kernel heap manager                   */
     119        kcm_t             kcm;             /*! embedded kernel cache manager (for KCMs)       */
    120120
    121121    kcm_t           * kcm_tbl[KMEM_TYPES_NR];         /*! pointers on allocated KCMs      */
    122122
    123     uint32_t          ram_size;           /*! physical memory size                        */
    124     uint32_t          ram_base;           /*! physical memory base (local address)        */
    125 
    126         rpc_fifo_t        rpc_fifo;           /*! cluster RPC fifo (shared)                   */
    127         list_entry_t      devlist;            /*! root of list of devices in cluster          */
    128     struct device_s * icu;                /*! pointer on local XCU device                 */
    129 
    130     int32_t           pages_var;          /*! pages number increment from last update     */
    131     int32_t           threads_var;        /*! threads number increment from last update   */
     123    uint32_t          ram_size;        /*! physical memory size                           */
     124    uint32_t          ram_base;        /*! physical memory base (local address)           */
     125
     126        rpc_fifo_t        rpc_fifo;        /*! cluster RPC fifo (shared)                      */
     127        list_entry_t      devlist;         /*! root of list of devices in cluster             */
     128
     129    int32_t           pages_var;       /*! pages number increment from last DQQT update   */
     130    int32_t           threads_var;     /*! threads number increment from last DQDT update */
    132131
    133132        dqdt_node_t       dqdt_tbl[CONFIG_MAX_DQDT_DEPTH];     /*! embedded DQDT nodes        */
    134133
    135     pmgr_t            pmgr;               /*! embedded process manager                    */
     134    pmgr_t            pmgr;            /*! embedded process manager                       */
    136135
    137136        char              name[CONFIG_SYSFS_NAME_LEN];
     
    192191/******************************************************************************************
    193192 * This function returns an extended pointer on the reference process descriptor
    194  * from the process PID.  It can be called by any thread running in any cluster,
    195  * as it uses a RPC to the owner cluster if the current cluster is not the owner.
     193 * from the process PID. This PID can be be different from the calling thread process.
     194 * It can be called by any thread running in any cluster,
    196195 ******************************************************************************************
    197196 * @ pid  : process identifier.
    198  * @ return extended pointer on the reference process descriptor.
     197 * @ return extended pointer on reference process if success / return XPTR_NULL if error.
    199198 *****************************************************************************************/
    200199xptr_t cluster_get_reference_process_from_pid( pid_t pid );
  • trunk/kernel/kern/core.c

    r19 r23  
    3838#include <core.h>
    3939
    40 // TODO #include <sysfs.h>
    41 
    4240/////////////////////////////////
    4341void core_init( core_t    * core,
     
    10098////////////////////////////////////
    10199void core_get_time( core_t   * core,
    102                     uint32_t * tm_ms,
     100                    uint32_t * tm_s,
    103101                    uint32_t * tm_us )
    104102{
  • trunk/kernel/kern/do_syscall.c

    r16 r23  
    22 * do_syscall.c - architecture independant entry-point for system calls.
    33 *
    4  * AUthor    Alain Greiner (2016)
     4 * Author    Alain Greiner (2016)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    3131
    3232/////////////////////////////////////////////////////////////////////////////////////////////
    33 // This array of pointers define the kernel functions for syscalls.
     33/////////////////////////////////////////////////////////////////////////////////////////////
     34static inline int sys_undefined()
     35{
     36    printk("\n[PANIC] in %s : undefined system call\n", __FUNCTION__ );
     37    hal_core_sleep();
     38    return 0;
     39}
     40
     41/////////////////////////////////////////////////////////////////////////////////////////////
     42// This array of pointers define the kernel functions implementing the syscalls.
    3443// It must be kept consistent with the enum in syscalls.h
    3544/////////////////////////////////////////////////////////////////////////////////////////////
     
    3948static const sys_func_t syscall_tbl[SYSCALLS_NR] =
    4049{
    41         sys_thread_exit,        // 0
    42         sys_mmap,               // 1
    43         sys_thread_create,      // 2
    44         sys_thread_join,        // 3
    45         sys_thread_detach,      // 4
    46         sys_thread_yield,       // 5
    47         sys_sem,                // 6
    48         sys_cond_var,           // 7
    49         sys_barrier,            // 8
    50         sys_rwlock,             // 9
    51         sys_thread_sleep,       // 10
    52         sys_thread_wakeup,      // 11
    53         sys_open,               // 12
    54         sys_creat,              // 13
    55         sys_read,               // 14
    56         sys_write,              // 15
    57         sys_lseek,              // 16
    58         sys_close,              // 17
    59         sys_unlink,             // 18
    60         sys_pipe,               // 19
    61         sys_chdir,              // 20
    62         sys_mkdir,              // 21
    63         sys_mkfifo,             // 22
    64         sys_opendir,            // 23
    65         sys_readdir,            // 24
    66         sys_closedir,           // 25
    67         sys_getcwd,             // 26
    68         sys_clock,              // 27
    69         sys_alarm,              // 28
    70         sys_dma_memcpy,         // 29
    71         sys_utls,               // 30
    72         sys_notAvailable,               // 31        Reserved for sigreturn TODO  ???
    73         sys_signal,             // 32
    74         sys_sigreturn_setup,    // 33
    75         sys_kill,               // 34
    76         sys_getpid,             // 35
    77         sys_fork,               // 36
    78         sys_exec,               // 37
    79         sys_thread_getattr,     // 38
    80         sys_ps,                 // 39
    81         sys_madvise,            // 40
    82         sys_mcntl,              // 41
    83         sys_stat,               // 42
    84         sys_thread_migrate,     // 43
    85         sys_sbrk,               // 44
    86         sys_rmdir,              // 45
    87         sys_ftime,              // 46
    88         sys_chmod,              // 47
    89         sys_fsync,              // 48
    90         sys_gettimeofday,       // 49
    91         sys_times               // 50
     50    sys_thread_exit,        // 0
     51    sys_mmap,               // 1
     52    sys_thread_create,      // 2
     53    sys_thread_join,        // 3
     54    sys_thread_detach,      // 4
     55    sys_thread_yield,       // 5
     56    sys_sem,                // 6
     57    sys_condvar,            // 7
     58    sys_barrier,            // 8
     59    sys_mutex,              // 9
     60    sys_thread_sleep,       // 10
     61    sys_thread_wakeup,      // 11
     62    sys_open,               // 12
     63    sys_creat,              // 13
     64    sys_read,               // 14
     65    sys_write,              // 15
     66    sys_lseek,              // 16
     67    sys_close,              // 17
     68    sys_unlink,             // 18
     69    sys_pipe,               // 19
     70    sys_chdir,              // 20
     71    sys_mkdir,              // 21
     72    sys_mkfifo,             // 22
     73    sys_opendir,            // 23
     74    sys_readdir,            // 24
     75    sys_closedir,           // 25
     76    sys_getcwd,             // 26
     77    sys_clock,              // 27
     78    sys_alarm,              // 28
     79    sys_rmdir,              // 29
     80    sys_utls,               // 30
     81    sys_chmod,              // 31
     82    sys_signal,             // 32
     83    sys_gettimeofday,       // 33
     84    sys_kill,               // 34
     85    sys_getpid,             // 35
     86    sys_fork,               // 36
     87    sys_exec,               // 37
     88    sys_stat,               // 38
     89    sys_trace,              // 39
    9290};
    9391
  • trunk/kernel/kern/dqdt.c

    r19 r23  
    150150
    151151            // set child[3] extended pointer (coordinates may overflow)
    152             if ( (level > 0) && ((x + (1<<(level-1))) < x_size)  && ((y + (1<<(level-1))) < y_size) )
     152            if ( (level > 0) &&
     153                 ((x + (1<<(level-1))) < x_size) &&
     154                 ((y + (1<<(level-1))) < y_size) )
    153155            {
    154156                c_cxy = local_cxy + ((1<<(level-1))<<y_width) + (1<<(level-1));
  • trunk/kernel/kern/kernel_init.c

    r19 r23  
    22 * kernel_init.c - kernel parallel initialization
    33 *
    4  * Authors :  Alain Greiner  (2016)
    5  *            Mohamed Lamine Karaoui (2016)
     4 * Authors :  Mohamed Lamine Karaoui (2015)
     5 *            Alain Greiner  (2016,2017)
    66 *
    77 * Copyright (c) Sorbonne Universites
     
    5353#include <vfs.h>
    5454#include <soclib_tty.h>
    55 
    56 // TODO #include <devfs.h>
     55#include <devfs.h>
     56
    5757// TODO #include <sysfs.h>
    5858
     
    601601// @ return 0 if success / return EINVAL if not found.
    602602///////////////////////////////////////////////////////////////////////////////////////////
    603 static error_t core_get_identifiers( boot_info_t * info,
    604                                      uint32_t    * lid,
     603static error_t get_core_identifiers( boot_info_t * info,
     604                                     lid_t       * lid,
    605605                                     cxy_t       * cxy,
    606606                                     gid_t       * gid )
     
    637637void kernel_init( boot_info_t * info )
    638638{
    639     uint32_t     core_lid = -1;      // running core local index
     639    lid_t        core_lid = -1;      // running core local index
    640640    cxy_t        core_cxy = -1;      // running core cluster identifier
    641641    gid_t        core_gid;           // running core hardware identifier
     
    646646
    647647    // all cores get core identifiers
    648     error = core_get_identifiers( info,
     648    error = get_core_identifiers( info,
    649649                                  &core_lid,
    650650                                  &core_cxy,
     
    664664    /////////////////////////////////////////////////////////////////////////////////
    665665
    666     kinit_dmsg("\n[INFO] %s : core[%x][%d] exit barrier 0\n",
    667                __FUNCTION__ , core_cxy , core_lid );
     666    kinit_dmsg("\n[INFO] %s : core[%x][%d] exit barrier 0 at cycle %d\n",
     667               __FUNCTION__ , core_cxy , core_lid , hal_time_stamp() );
    668668
    669669    // all cores check core identifiers
     
    675675        hal_core_sleep();
    676676    }
    677     else
    678     {
    679         kinit_dmsg("\n[INFO] %s : core[%x][%d] enters at cycle %d / sp = %x\n",
    680                    __FUNCTION__ , core_cxy , core_lid , hal_time_stamp() , hal_get_stack() );
    681     }
    682677
    683678    // CP0 initializes the local cluster manager (cores and memory allocators)
     
    691686                   __FUNCTION__ , local_cxy );
    692687            hal_core_sleep();
    693         }
    694         else
    695         {
    696             kinit_dmsg("\n[INFO] %s : core[%x][%d] initialised cluster at cycle %d\n",
    697                        __FUNCTION__ , core_cxy , core_lid , hal_time_stamp());
    698688        }
    699689    }
     
    706696    /////////////////////////////////////////////////////////////////////////////////
    707697
    708     kinit_dmsg("\n[INFO] %s : core[%x][%d] exit barrier 1\n",
    709                __FUNCTION__ , core_cxy , core_lid );
     698    kinit_dmsg("\n[INFO] %s : core[%x][%d] exit barrier 1 at cycle %d\n",
     699               __FUNCTION__ , core_cxy , core_lid , hal_time_stamp() );
    710700
    711701    // all cores get pointer on local cluster manager and on core descriptor
     
    756746    /////////////////////////////////////////////////////////////////////////////////
    757747
    758     kinit_dmsg("\n[INFO] %s : core[%x][%d] exit barrier 2\n",
    759                __FUNCTION__ , core_cxy , core_lid );
     748    kinit_dmsg("\n[INFO] %s : core[%x][%d] exit barrier 2 at cycle %d\n",
     749               __FUNCTION__ , core_cxy , core_lid , hal_time_stamp() );
    760750
    761751    // all cores initialize the private idle thread descriptor
     
    789779    }
    790780
    791     // TODO CP0 in IO cluster initialize VFS, devFS and sysFS
    792     {
    793             // devfs_root_init();
    794             // sysfs_root_init();
    795             // clusters_sysfs_register();
    796         // vfs_init();
    797             // sysconf_init();
    798     }
     781printk("\n bloup 0\n");
     782
     783    // CP0 in all clusters initializes cooperatively VFS and DEVFS
     784    if( (core_lid == 0)  )
     785    {
     786        xptr_t  root_inode_xp;
     787
     788        // initialize root File System
     789        if( CONFIG_VFS_ROOT_IS_FATFS )
     790        {
     791            root_inode_xp = fatfs_init();
     792        }
     793        else
     794        {
     795            printk("\n[PANIC] in %s : root FS must be FATFS\n", __FUNCTION__ );
     796            hal_core_sleep();
     797        }
     798
     799        if( root_inode_xp == XPTR_NULL )
     800        {
     801            printk("\n[PANIC] in %s : core[%x][%d] cannot initialize file system\n",
     802                   __FUNCTION__ , local_cxy , core_lid );
     803            hal_core_sleep();
     804        }
     805
     806printk("\n bloup 1\n");
     807
     808        // mount the DEVFS File system
     809            devfs_mount( root_inode_xp , "dev" );
     810    }
     811
     812printk("\n bloup 2\n");
    799813
    800814    // CP0 in I/O cluster print banner
     
    811825    /////////////////////////////////////////////////////////////////////////////////
    812826
    813     kinit_dmsg("\n[INFO] %s : core[%x][%d] exit barrier 3\n",
    814                __FUNCTION__ , core_cxy , core_lid );
     827    kinit_dmsg("\n[INFO] %s : core[%x][%d] exit barrier 3 at cycle %d\n",
     828               __FUNCTION__ , core_cxy , core_lid , hal_time_stamp() );
    815829
    816830    // each core activates its private PTI IRQ
  • trunk/kernel/kern/printk.c

    r14 r23  
    3737extern chdev_t            txt0_chdev;        // allocated in kernel_init.c
    3838
     39/////////////////////////////////////
     40uint32_t snprintf( char     * string,
     41                   uint32_t   length,
     42                   char     * format, ... )
     43{
     44
     45#define TO_STREAM(x) do { string[ps] = (x); ps++; if(ps==length) return -1; } while(0);
     46
     47    va_list    args;      // printf arguments
     48    uint32_t   ps;        // write pointer to the string buffer
     49
     50    ps = 0;   
     51    va_start( args , format );
     52
     53xprintf_text:
     54
     55    while ( *format != 0 )
     56    {
     57
     58        if (*format == '%')   // copy argument to string
     59        {
     60            format++;
     61            goto xprintf_arguments;
     62        }
     63        else                  // copy one char to string
     64        {
     65            TO_STREAM( *format );
     66            format++;
     67        }
     68    }
     69
     70    va_end( args );
     71   
     72    // add terminating NUL chracter
     73    TO_STREAM( 0 );
     74    return ps;
     75
     76xprintf_arguments:
     77
     78    {
     79        char              buf[30];    // buffer to display one number
     80        char *            pbuf;       // pointer on first char to display
     81        uint32_t          len = 0;    // number of char to display
     82        static const char HexaTab[] = "0123456789ABCDEF";
     83        uint32_t          i;
     84       
     85        // Ignore fields width and precision
     86        for ( ; (*format >= '0' && *format <= '9') || (*format == '.') ; format++ );
     87
     88        switch (*format)
     89        {
     90            case ('c'):             // char conversion
     91            {
     92                int val = va_arg( args, int );
     93                buf[0] = val;
     94                pbuf   = buf;
     95                len    = 1;
     96                break;
     97            }
     98            case ('d'):             // decimal signed integer
     99            {
     100                int val = va_arg( args, int );
     101                if (val < 0)
     102                {
     103                    TO_STREAM( '-' );
     104                    val = -val;
     105                }
     106                for(i = 0; i < 10; i++)
     107                {
     108
     109                    buf[9 - i] = HexaTab[val % 10];
     110                    if (!(val /= 10)) break;
     111                }
     112                len =  i + 1;
     113                pbuf = &buf[9 - i];
     114                break;
     115            }
     116            case ('u'):             // decimal unsigned integer
     117            {
     118                uint32_t val = va_arg( args, uint32_t );
     119                for(i = 0; i < 10; i++)
     120                {
     121                    buf[9 - i] = HexaTab[val % 10];
     122                    if (!(val /= 10)) break;
     123                }
     124                len =  i + 1;
     125                pbuf = &buf[9 - i];
     126                break;
     127            }
     128            case ('x'):             // 32 bits hexadecimal
     129            case ('l'):             // 64 bits hexadecimal
     130            {
     131                uint32_t       imax;
     132                uint64_t val;
     133               
     134                if ( *format == 'l' )   // 64 bits
     135                {
     136                    val = va_arg( args, uint64_t);
     137                    imax = 16;
     138                }
     139                else                    // 32 bits
     140                {
     141                    val = va_arg( args, uint32_t);
     142                    imax = 8;
     143                }
     144               
     145                TO_STREAM( '0' );
     146                TO_STREAM( 'x' );
     147               
     148                for(i = 0; i < imax; i++)
     149                {
     150                    buf[(imax-1) - i] = HexaTab[val % 16];
     151                    if (!(val /= 16))  break;
     152                }
     153                len =  i + 1;
     154                pbuf = &buf[(imax-1) - i];
     155                break;
     156            }
     157            case ('s'):             /* string */
     158            {
     159                char* str = va_arg( args, char* );
     160                while (str[len]) { len++; }
     161                pbuf = str;
     162                break;
     163            }
     164            default:       // unsupported argument type
     165            {
     166                return -1;
     167            }
     168        }  // end switch on  argument type
     169
     170        format++;
     171
     172        // copy argument to string
     173        for( i = 0 ; i < len ; i++ )
     174        {
     175            TO_STREAM( pbuf[i] );
     176        }
     177       
     178        goto xprintf_text;
     179    }
     180} // end xprintf()
     181
    39182///////////////////////////////////////////////////////////////////////////////////
    40183// This static function is called by kernel_printf() to display a string on the
     
    47190///////////////////////////////////////////////////////////////////////////////////
    48191// @ channel  : TXT channel.
    49 // @ busy     : TXT device acces mode.
     192// @ busy     : TXT device acces mode (busy waiting if non zero).
    50193// @ buf      : buffer containing the characters.
    51194// @ nc       : number of characters.
     
    66209//////////////////////////////////////////////////////////////////////////////////////
    67210// @ channel   : channel index.
    68 // @ busy      : TXT device access mode.
     211// @ busy      : TXT device access mode (busy waiting if non zero).
    69212// @ format    : printf like format.
    70213// @ args      : format arguments.
     
    267410}
    268411
     412
    269413// Local Variables:
    270414// tab-width: 4
  • trunk/kernel/kern/printk.h

    r16 r23  
    4646
    4747/**********************************************************************************
     48 * This function build a formated string.
     49 * The supported formats are defined below :
     50 *   %c : single character
     51 *   %d : signed decimal 32 bits integer
     52 *   %u : unsigned decimal 32 bits integer
     53 *   %x : hexadecimal 32 bits integer
     54 *   %l : hexadecimal 64 bits integer
     55 *   %s : NUL terminated character string
     56 **********************************************************************************
     57 * @ string     : pointer on target buffer (allocated by caller).
     58 * @ length     : target buffer length (number of bytes).
     59 * @ format     : format respecting the printf syntax.
     60 * @ returns the string length (including NUL) if success / return -1 if error.
     61 *********************************************************************************/
     62uint32_t snprintf( char     * string,
     63                   uint32_t   length,
     64                   char     * format, ... );
     65
     66/**********************************************************************************
    4867 * This function displays a formated string on the kernel terminal TXT0,
    4968 * using a busy waiting policy: It calls directly the relevant TXT driver,
     
    5271 * @ format     : formated string.
    5372 *********************************************************************************/
    54 extern void         printk( char* format, ... );
     73void         printk( char* format, ... );
    5574
    5675/**********************************************************************************
     
    6281 * @ format     : formated string.
    6382 *********************************************************************************/
    64 extern void         user_printk( char* format, ... );
     83void         user_printk( char* format, ... );
    6584
    6685/**********************************************************************************
     
    211230#else
    212231#define sched_dmsg(...)
     232#endif
     233
     234#if CONFIG_SIGNAL_DEBUG
     235#define signal_dmsg(...)   printk(__VA_ARGS__)
     236#else
     237#define signal_dmsg(...)
    213238#endif
    214239
  • 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
  • trunk/kernel/kern/process.h

    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
     
    5454
    5555/*********************************************************************************************
    56  * These macros are used to compose or decompose global thread identifier (TRDID)
    57  * to or from cluster identifier / local thread index (CXY , LTID)
    58  ********************************************************************************************/
    59 
    60 #define LTID_FROM_TRDID( trdid )   (ltid_t)(trdid & 0x0000FFFF)
    61 #define CXY_FROM_TRDID( trdid )    (cxy_t)(trdid >> 16)
    62 #define TRDID( cxy , ltid )        (trdid_t)((cxy << 16) | ltid )
    63 
    64 /*********************************************************************************************
    6556 * This structure defines an array of extended pointers on the open file descriptors
    6657 * for a given process. We use an extended pointer because the open file descriptor
     
    6859 * A free entry in this array contains the XPTR_NULL value.
    6960 * The array size is defined by a the CONFIG_PROCESS_FILE_MAX_NR parameter.
    70  * All modifications (open/close) must be done by the reference cluster, and reported
     61 * All modifications (open/close) in this structure must be done by the reference cluster,
     62 * and reported in process copies.
    7163 ********************************************************************************************/
    7264
     
    7567        remote_spinlock_t lock;             /*! lock protecting fd_array[] change.              */
    7668    uint32_t          current;          /*! current number of open files                    */
    77     uint32_t          max;              /*! max number of open files (can be increased)     */
    7869        xptr_t            array[CONFIG_PROCESS_FILE_MAX_NR]; 
    7970}
     
    8879 * allocated to this cluster.
    8980 * The process descriptor for a PID process is replicated in all clusters containing
    90  * at least one thread of the PID process, with some restrictions:
    91  * - The list of registered vsegs, the page table (contained in vmm), and the fd_array[]
    92  *   are only complete in the reference process descriptor, other copies are read-only caches.
    93  * - The following fields are NOT defined in copies other than the reference:
    94  *   children_root , children_list , children_nr , sig_mgr
     81 * at least one thread of the PID process, with the following rules :
     82 *
     83 * 1) The <pid>, <ppid>, <ref_xp>, <vfs_root_xp>, <vfs_bin_xp>  fields are defined
     84 *    in all process descriptor copies.
     85 * 2) The <vfs_cwd_xp> and associated <cwd_lock>, that can be dynamically modified,
     86 *    are only defined in the reference process descriptor.
     87 * 2) The <vmm>, containing the list of registered vsegs, and the page table, are only
     88 *    complete in the reference process cluster, other copies are read-only caches.
     89 * 3) the <fd_array>, containing extended pointers on the open file descriptors, is only
     90 *    complete in the reference process cluster, other copies are read-only caches.
     91 * 4) The <sem_root>, <mutex_root>, <barrier_root>, <condvar_root>, and the associated
     92 *    <sync_lock>, that are dynamically allocated, are only defined in the reference cluster.
     93 * 5) The <children_root>, and <children_nr> fields are only defined in the reference
     94 *    cluster, and are undefined in other clusters.
     95 * 6) The <brothers_list>, <local_list>, <copies_list>, <th_tbl>, <th_nr>, <th_lock> fields
     96 *    are defined in all process descriptors copies.
     97 * 7) The <sig_mgr> field is only defined in the reference cluster. TODO
    9598 ********************************************************************************************/
    9699
    97100typedef struct process_s
    98101{
    99         vmm_t            vmm;               /*! embedded virtual memory manager                 */
    100 
    101         fd_array_t       fd_array;          /*! embedded file descriptors array                 */
    102 
    103         xptr_t           vfs_root_xp;       /*! extende pointer on current file system root     */
    104         xptr_t           vfs_cwd_xp;        /*! extended pointer on current working directory   */
    105         xptr_t           vfs_bin_xp;        /*! extended pointer on associate .elf file         */
    106 
    107         spinlock_t       cd_lock;           /*! lock protecting working directory changes       */
     102        vmm_t             vmm;              /*! embedded virtual memory manager                 */
     103
     104        fd_array_t        fd_array;         /*! embedded open file descriptors array            */
     105
     106        xptr_t            vfs_root_xp;      /*! extende pointer on current VFS root inode       */
     107        xptr_t            vfs_bin_xp;       /*! extended pointer on .elf file inode             */
     108        pid_t             pid;              /*! process identifier                              */
     109        pid_t             ppid;             /*! parent process identifier                       */
     110    xptr_t            ref_xp;           /*! extended pointer on reference process           */
     111
     112        xptr_t            vfs_cwd_xp;       /*! extended pointer on current working dir inode   */
     113        remote_rwlock_t   cwd_lock;         /*! lock protecting working directory changes       */
    108114 
    109         pid_t            pid;               /*! process identifier                              */
    110         pid_t            ppid;              /*! parent process identifier                       */
    111         bool_t           is_ref;            /*! this is the reference process if true           */
    112     xptr_t           ref_xp;            /*! extended pointer on reference process           */
    113 
    114         xlist_entry_t    children_root;     /*! root of the children process xlist              */
    115     uint32_t         children_nr;       /*! number of children processes                    */
    116 
    117         xlist_entry_t    brothers_list;     /*! member of list of children of same parent       */
    118 
    119     list_entry_t     local_list;        /*! member of list of process in same cluster       */
    120 
    121     xlist_entry_t    copies_list;       /*! member of list of copies of same process        */
    122 
    123         spinlock_t       th_lock;           /*! lock protecting th_tbl[] concurrent access      */
    124         uint32_t         th_nr;             /*! number of threads in this cluster               */
    125 
     115        xlist_entry_t     children_root;    /*! root of the children process xlist              */
     116    uint32_t          children_nr;      /*! number of children processes                    */
     117
     118        xlist_entry_t     brothers_list;    /*! member of list of children of same parent       */
     119    xlist_entry_t     local_list;       /*! member of list of process in same cluster       */
     120    xlist_entry_t     copies_list;      /*! member of list of copies of same process        */
     121
     122        spinlock_t        th_lock;          /*! lock protecting th_tbl[] concurrent access      */
     123        uint32_t          th_nr;            /*! number of threads in this cluster               */
    126124        struct thread_s * th_tbl[CONFIG_THREAD_MAX_PER_CLUSTER]; /*! pointers on local threads  */
    127125
    128     xlist_entry_t    sem_root;          /*! root of the process semaphores list             */
    129     uint32_t         sem_nr;            /*! number of semaphores                            */
    130 
    131         sig_mgr_t        sig_mgr;           /*! embedded signal manager TODO [AG]               */
     126    xlist_entry_t     sem_root;         /*! root of the process semaphore list              */
     127    xlist_entry_t     mutex_root;       /*! root of the process mutex list                  */
     128    xlist_entry_t     barrier_root;     /*! root of the process barrier list                */
     129    xlist_entry_t     condvar_root;     /*! root of the process condvar list                */
     130
     131    remote_spinlock_t sync_lock;        /*! lock protecting sem,mutex,barrier,condvar lists */
     132
     133        sig_mgr_t         sig_mgr;          /*! embedded signal manager TODO [AG]               */
    132134}
    133135process_t;
     
    149151    xptr_t             vfs_bin_xp;     /*! extended pointer on process .elf file            */
    150152
    151     char               path[256];      /*! pathname for  .elf file                          */
     153    char               path[CONFIG_VFS_MAX_PATH_LENGTH];   /*!  .elf file path              */
    152154
    153155    char            ** args_pointers;  /*! physical base address of array of pointers       */
     
    162164exec_info_t;
    163165
    164 /*********************************************************************************************
    165  * This macro returns a pointer on the process descriptor for the calling thread.
    166  ********************************************************************************************/
    167 
    168 #define CURRENT_PROCESS (hal_get_current_thread()->process)
    169 
    170166/***************   Process Descriptor Operations    *****************************************/
    171167
     
    204200 * The PID value must have been defined previously by the owner cluster manager.
    205201 * The reference cluster can be different from the owner cluster.
    206  * It set the pid / ppid / is_ref / pref / fields.
     202 * It set the pid / ppid / ref_xp fields.
    207203 * It registers this process descriptor in three lists:
    208204 * - the children_list in the parent process descriptor.
     
    232228/*********************************************************************************************
    233229 * This function releases all memory allocated for a process descriptor in the local cluster,
    234  * after releasing memory allocated for embedded substructures (fd_array, vmm, etc).
     230 * including memory allocated for embedded substructures (fd_array, vmm, etc).
    235231 * The local th_tbl[] array must be empty.
    236232 *********************************************************************************************
     
    255251 * If this local copy does not exist yet, it is dynamically created, from the reference
    256252 * process descriptor, registered in the global copies_list, and registered in the local_list.
    257  * This function is used by both thread_user_create() and thread_user_copy() functions.
     253 * This function is used by the thread_user_create() function.
    258254 *********************************************************************************************
    259255 * @ pid     : searched process identifier.
     
    288284
    289285/*********************************************************************************************
    290  * This function reset the file descriptor array for a given process: no open file.
     286 * This function initialises all entries of the local fd_array as empty.
    291287 *********************************************************************************************
    292288 * @ process  : pointer on the local process descriptor.
     
    295291
    296292/*********************************************************************************************
    297  * This function closes all open files and releases all file descriptors.
     293 * This function uses as many remote accesses as required, to reset an entry in fd_array[],
     294 * in all clusters containing a copy. The entry is identified by the <file_id> argument.
     295 * This function must be executed by a thread running reference cluster, that contain
     296 * the complete list of process descriptors copies.
    298297 *********************************************************************************************
    299298 * @ process  : pointer on the local process descriptor.
    300  ********************************************************************************************/
    301 void process_fd_destroy( process_t * process );
     299 * @ file_id  : file descriptor index in the fd_array.
     300 ********************************************************************************************/
     301void process_fd_remove( process_t * process,
     302                        uint32_t    file_id );
     303
     304/*********************************************************************************************
     305 * This function returns an extended pointer on a file descriptor identified by its index
     306 * in fd_array. It can be called by any thread running in any cluster.
     307 * It access first the local process descriptor. In case of local miss, it uses remote access
     308 * to access the reference process descriptor.
     309 * It updates the local fd_array when the file descriptor exist in reference cluster.
     310 * The file descriptor refcount is not incremented.
     311 *********************************************************************************************
     312 * @ process  : pointer on the local process descriptor.
     313 * @ file_id  : file descriptor index in the fd_array.
     314 * @ return extended pointer on file descriptor if success / return XPTR_NULL if not found.
     315 ********************************************************************************************/
     316xptr_t process_fd_get_xptr( process_t * process,
     317                            uint32_t    file_id );
    302318
    303319/*********************************************************************************************
    304320 * This function checks the number of open files for a given process.
    305  *********************************************************************************************
    306  * @ process  : pointer on the local process descriptor.
     321 * It can be called by any thread in any cluster, because it uses portable remote access
     322 * primitives to access the reference process descriptor.
     323 *********************************************************************************************
    307324 * @ returns true if file descriptor array full.
    308325 ********************************************************************************************/
    309 bool_t process_fd_array_full( process_t * process );
    310 
    311 /*********************************************************************************************
    312  * These functions allocates a slot in the fd_array for a given process,
    313  * and returns the file descriptor index.
    314  *********************************************************************************************
    315  * @ process  : pointer on the local process descriptor.
    316  * @ file     : extended pointer on the file descriptor.
    317  * @ fd       : [out] file descriptor index
     326bool_t process_fd_array_full();
     327
     328/*********************************************************************************************
     329 * This function allocates a free slot in the fd_array of the reference process,
     330 * register the <file_xp> argument in the allocated slot, and return the slot index.
     331 * It can be called by any thread in any cluster, because it uses portable remote access
     332 * primitives to access the reference process descriptor.
     333 *********************************************************************************************
     334 * @ file_xp  : extended pointer on the file descriptor to be registered.
     335 * @ file_id  : [out] buffer for fd_array slot index.
    318336 * @ return 0 if success / return EMFILE if array full.
    319337 ********************************************************************************************/
    320 error_t process_fd_allocate( process_t * process,
    321                              xptr_t      file_xp,
    322                              uint32_t  * fd );
    323 
    324 /*********************************************************************************************
    325  * This function releases an existing file descriptor from the process fd_array.
    326  *********************************************************************************************
    327  * @ process  : pointer on the local process descriptor.
    328  * @ return 0 if success / return EBADF if illegal file descriptor.
    329  ********************************************************************************************/
    330 error_t process_fd_release( process_t * process,
    331                             uint32_t    fd );
    332 
    333 /*********************************************************************************************
    334  * This function copies all non-zero entries from a local <src> fd_array,
    335  * embedded in a process descriptor, to another local <dst_xp> fd_array, embedded
    336  * in another process descriptor.
    337  * It takes the remote lock protecting the <src> fd_array during the copy.
    338  * For each involved file descriptor, the refcount is incremented.
    339  *********************************************************************************************
    340  * @ dst   : pointer on the destination fd_array_t.
    341  * @ src   : pointer on the source fd_array_t.
    342  ********************************************************************************************/
    343 void process_fd_local_copy( fd_array_t * dst,
    344                             fd_array_t * src );
     338error_t process_fd_register( xptr_t      file_xp,
     339                             uint32_t  * file_id );
    345340
    346341/*********************************************************************************************
     
    358353
    359354
     355
    360356/********************   Thread Related Operations   *****************************************/
    361357
  • trunk/kernel/kern/rpc.c

    r16 r23  
    22 * rpc.c - RPC related operations implementation.
    33 *
    4  * Authors Mohamed Lamine Karaoui (2015)
    5  *         Alain Greiner (2016)
     4 * Author    Alain Greiner (2016,2017)
    65 *
    76 * Copyright (c)  UPMC Sorbonne Universites
     
    4039#include <vfs.h>
    4140#include <fatfs.h>
     41#include <signal.h>
    4242#include <dev_icu.h>
    4343#include <rpc.h>
     
    5555    &rpc_thread_user_create_server,     // 4
    5656    &rpc_thread_kernel_create_server,   // 5
    57     &rpc_undefined,                     // 6                       
     57    &rpc_signal_rise_server,            // 6                       
    5858    &rpc_undefined,                     // 7
    5959    &rpc_undefined,                     // 8
     
    6464    &rpc_vfs_dentry_create_server,      // 12 
    6565    &rpc_vfs_dentry_destroy_server,     // 13 
    66     &rpc_undefined,                     // 14
    67     &rpc_undefined,                     // 15
    68     &rpc_undefined,                     // 16
     66    &rpc_vfs_file_create_server,        // 14
     67    &rpc_vfs_file_destroy_server,       // 15
     68    &rpc_fatfs_get_cluster_server,      // 16
    6969    &rpc_undefined,                     // 17
    7070    &rpc_undefined,                     // 18
     
    7373    &rpc_vmm_get_ref_vseg_server,       // 20
    7474    &rpc_vmm_get_pte_server,            // 21
    75     &rpc_semaphore_alloc_server,        // 22
    76     &rpc_semaphore_free_server,         // 23
     75    &rpc_kcm_alloc_server,              // 22
     76    &rpc_kcm_free_server,               // 23
    7777    &rpc_mapper_move_server,            // 24
    7878    &rpc_undefined,                     // 25
     
    8181    &rpc_undefined,                     // 28
    8282    &rpc_undefined,                     // 29
    83 
    84     &rpc_fatfs_get_cluster_server       // 30
    8583};
    8684
     
    9391
    9492/////////////////////////////////////////////////////////////////////////////////////////
    95 //               Marshaling functions attached to RPC_PMEM_GET_PAGES
     93// [0]           Marshaling functions attached to RPC_PMEM_GET_PAGES
    9694/////////////////////////////////////////////////////////////////////////////////////////
    9795
     
    150148
    151149/////////////////////////////////////////////////////////////////////////////////////////
    152 //               Marshaling functions attached to RPC_PROCESS_PID_ALLOC
     150// [1]           Marshaling functions attached to RPC_PROCESS_PID_ALLOC
    153151/////////////////////////////////////////////////////////////////////////////////////////
    154152
     
    207205
    208206/////////////////////////////////////////////////////////////////////////////////////////
    209 //               Marshaling functions attached to RPC_PROCESS_EXEC
     207// [2]           Marshaling functions attached to RPC_PROCESS_EXEC
    210208/////////////////////////////////////////////////////////////////////////////////////////
    211209
     
    265263
    266264/////////////////////////////////////////////////////////////////////////////////////////
    267 //               Marshaling functions attached to RPC_PROCESS_KILL
     265// [3]           Marshaling functions attached to RPC_PROCESS_KILL
    268266/////////////////////////////////////////////////////////////////////////////////////////
    269267
     
    272270{
    273271    // only reference cluster can send this RPC
    274     if( !process->is_ref )
     272    if( GET_CXY( process->ref_xp ) != local_cxy )
    275273    {
    276274        printk("PANIC in %s : caller is not the reference process\n", __FUNCTION__ );
     
    334332
    335333/////////////////////////////////////////////////////////////////////////////////////////
    336 //               Marshaling functions attached to RPC_THREAD_USER_CREATE               
     334// [4]           Marshaling functions attached to RPC_THREAD_USER_CREATE               
    337335/////////////////////////////////////////////////////////////////////////////////////////
    338336
    339337/////////////////////////////////////////////////////////
    340338void rpc_thread_user_create_client( cxy_t            cxy, 
     339                                    pid_t            pid,         // in
     340                                    void           * start_func,  // in
     341                                    void           * start_arg,   // in
    341342                                    pthread_attr_t * attr,        // in
    342343                                    xptr_t         * thread_xp,   // out
     
    356357
    357358    // set input arguments in RPC descriptor
    358     rpc.args[0] = (uint64_t)(intptr_t)attr;
     359    rpc.args[0] = (uint64_t)pid;
     360    rpc.args[1] = (uint64_t)(intptr_t)start_func;
     361    rpc.args[2] = (uint64_t)(intptr_t)start_arg;
     362    rpc.args[3] = (uint64_t)(intptr_t)attr;
    359363
    360364    // register RPC request in remote RPC fifo
     
    362366
    363367    // get output arguments from RPC descriptor
    364     *thread_xp = (xptr_t)rpc.args[1];
    365     *error     = (error_t)rpc.args[2];
     368    *thread_xp = (xptr_t)rpc.args[4];
     369    *error     = (error_t)rpc.args[5];
    366370}
    367371
     
    373377    thread_t       * thread_ptr; // local pointer on thread descriptor
    374378    xptr_t           thread_xp;  // extended pointer on thread descriptor
     379
    375380    pid_t            pid;        // process identifier
    376     process_t      * process;    // local pointer on process descriptor
    377     vseg_t         * vseg;       // local pointer on stack vseg
    378 
    379     error_t          error = 0;
     381    void           * start_func;
     382    void           * start_arg;
     383    error_t          error;
    380384
    381385    // get client cluster identifier and pointer on RPC descriptor
     
    384388
    385389    // get pointer on attributes structure in client cluster from RPC descriptor
    386     attr_ptr = (pthread_attr_t *)(intptr_t)hal_remote_lwd( XPTR(client_cxy , &desc->args[0]) );
     390
     391    // get input arguments from RPC descriptor
     392    pid        = (pid_t)                     hal_remote_lwd(XPTR(client_cxy , &desc->args[0]));
     393    start_func = (void *)(intptr_t)          hal_remote_lwd(XPTR(client_cxy , &desc->args[1]));
     394    start_arg  = (void *)(intptr_t)          hal_remote_lwd(XPTR(client_cxy , &desc->args[2]));
     395    attr_ptr   = (pthread_attr_t *)(intptr_t)hal_remote_lwd(XPTR(client_cxy , &desc->args[3]));
    387396
    388397    // makes a local copy of attributes structure
     
    391400                       sizeof(pthread_attr_t) );
    392401   
    393     if( attr_copy.cxy != local_cxy )
    394     {
    395         printk("\n[PANIC] in %s : target cluster = %X / local_cluster = %x\n",
    396                __FUNCTION__ , attr_copy.cxy , local_cxy );
    397         hal_core_sleep();
    398     }
    399 
    400     // get local process descriptor
    401     pid     = attr_copy.pid;
    402     process = cluster_get_local_process_from_pid( pid );
    403 
    404     if( process == NULL )
    405     {
    406         printk("\n[ERROR] in %s : no process descriptor in cluster %x for pid = %x\n",
    407                __FUNCTION__ , local_cxy , pid );
    408         error = ENOMEM;
    409        
    410     }
    411 
    412     // allocate a stack from local VMM
    413     vseg = vmm_create_vseg( process,
    414                             0,
    415                             0,
    416                             VSEG_TYPE_STACK );
    417     if( vseg == NULL )
    418     {
    419         printk("\n[ERROR] in %s : cannot create stack vseg in cluster %x for pid %x\n",
    420                __FUNCTION__ , local_cxy , pid );
    421         error = ENOMEM;
    422     }
    423 
    424     // create thread in local cluster
    425     if( thread_user_create( &thread_ptr,
    426                             &attr_copy,
    427                             vseg->min,
    428                             vseg->max - vseg->min ) ) error = ENOMEM;
    429 
     402    assert( (attr_copy.cxy == local_cxy) , __FUNCTION__ , "bad target cluster\n" );
     403
     404    // call kernel function
     405    error = thread_user_create( pid,
     406                                start_func,
     407                                start_arg,
     408                                &attr_copy,
     409                                &thread_ptr );
    430410
    431411    // set output arguments
     
    436416
    437417/////////////////////////////////////////////////////////////////////////////////////////
    438 //               Marshaling functions attached to RPC_THREAD_KERNEL_CREATE
     418// [5]           Marshaling functions attached to RPC_THREAD_KERNEL_CREATE
    439419/////////////////////////////////////////////////////////////////////////////////////////
    440420
     
    502482
    503483/////////////////////////////////////////////////////////////////////////////////////////
    504 //               Marshaling functions attached to RPC_VFS_INODE_CREATE
     484// [6]           Marshaling functions attached to RPC_SIGNAL_RISE
     485/////////////////////////////////////////////////////////////////////////////////////////
     486
     487/////////////////////////////////////////////
     488void rpc_signal_rise_client( cxy_t       cxy,
     489                             process_t * process,    // in
     490                             uint32_t    sig_id )    // in
     491{
     492    // RPC must be remote
     493    if( cxy == local_cxy )
     494    {
     495        printk("PANIC in %s : target is not remote\n", __FUNCTION__ );
     496        hal_core_sleep();
     497    }
     498
     499    // initialise RPC descriptor header
     500    rpc_desc_t  rpc;
     501    rpc.index    = RPC_SIGNAL_RISE;
     502    rpc.response = 1;
     503
     504    // set input arguments in RPC descriptor
     505    rpc.args[0] = (uint64_t)(intptr_t)process;
     506    rpc.args[1] = (uint64_t)sig_id;
     507   
     508    // register RPC request in remote RPC fifo
     509    rpc_send_sync( cxy , &rpc );
     510}
     511
     512////////////////////////////////////////                             
     513void rpc_signal_rise_server( xptr_t xp )
     514{
     515    process_t  * process;  // local pointer on process descriptor
     516    uint32_t     sig_id;   // signal index
     517
     518    // get client cluster identifier and pointer on RPC descriptor
     519    cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
     520    rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );
     521
     522    // get attributes from RPC descriptor
     523    process = (process_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
     524    sig_id  = (uint32_t)             hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
     525
     526    // call local kernel function
     527    signal_rise( process , sig_id );
     528}
     529
     530/////////////////////////////////////////////////////////////////////////////////////////
     531// [10]          Marshaling functions attached to RPC_VFS_INODE_CREATE
    505532/////////////////////////////////////////////////////////////////////////////////////////
    506533
     
    508535void rpc_vfs_inode_create_client( cxy_t          cxy,     
    509536                                  xptr_t         dentry_xp,  // in
    510                                   uint32_t       type,       // in
     537                                  uint32_t       fs_type,    // in
     538                                  uint32_t       inode_type, // in
    511539                                  uint32_t       attr,       // in
    512                                   uint32_t       mode,       // in
     540                                  uint32_t       rights,     // in
    513541                                  uint32_t       uid,        // in
    514542                                  uint32_t       gid,        // in
     
    530558    // set input arguments in RPC descriptor
    531559    rpc.args[0] = (uint64_t)dentry_xp;
    532     rpc.args[1] = (uint64_t)type;
    533     rpc.args[2] = (uint64_t)attr;
    534     rpc.args[3] = (uint64_t)mode;
    535     rpc.args[4] = (uint64_t)uid;
    536     rpc.args[5] = (uint64_t)gid;
     560    rpc.args[1] = (uint64_t)fs_type;
     561    rpc.args[2] = (uint64_t)inode_type;
     562    rpc.args[3] = (uint64_t)attr;
     563    rpc.args[4] = (uint64_t)rights;
     564    rpc.args[5] = (uint64_t)uid;
     565    rpc.args[6] = (uint64_t)gid;
    537566
    538567    // register RPC request in remote RPC fifo (blocking function)
     
    540569
    541570    // get output values from RPC descriptor
    542     *inode_xp = (xptr_t)rpc.args[6];
    543     *error    = (error_t)rpc.args[7];
     571    *inode_xp = (xptr_t)rpc.args[7];
     572    *error    = (error_t)rpc.args[8];
    544573}
    545574
     
    548577{
    549578    xptr_t           dentry_xp;
    550     uint32_t         type;
     579    uint32_t         fs_type;
     580    uint32_t         inode_type;
    551581    uint32_t         attr;
    552     uint32_t         mode;
     582    uint32_t         rights;
    553583    uint32_t         uid;
    554584    uint32_t         gid;
     
    561591
    562592    // get input arguments from client rpc descriptor
    563     dentry_xp = (xptr_t)  hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
    564     type      = (uint32_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
    565     attr      = (uint32_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[2] ) );
    566     mode      = (uint32_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[3] ) );
    567     uid       = (uid_t)   hal_remote_lwd( XPTR( client_cxy , &desc->args[4] ) );
    568     gid       = (gid_t)   hal_remote_lwd( XPTR( client_cxy , &desc->args[5] ) );
     593    dentry_xp  = (xptr_t)  hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
     594    fs_type    = (uint32_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
     595    inode_type = (uint32_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[2] ) );
     596    attr       = (uint32_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[3] ) );
     597    rights     = (uint32_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[4] ) );
     598    uid        = (uid_t)   hal_remote_lwd( XPTR( client_cxy , &desc->args[5] ) );
     599    gid        = (gid_t)   hal_remote_lwd( XPTR( client_cxy , &desc->args[6] ) );
    569600
    570601    // call local kernel function
    571602    error = vfs_inode_create( dentry_xp,
    572                               type,
     603                              fs_type,
     604                              inode_type,
    573605                              attr,
    574                               mode,
     606                              rights,
    575607                              uid,
    576608                              gid,
     
    578610
    579611    // set output arguments
    580     hal_remote_swd( XPTR( client_cxy , &desc->args[6] ) , (uint64_t)inode_xp );
    581     hal_remote_swd( XPTR( client_cxy , &desc->args[7] ) , (uint64_t)error );
    582 }
    583 
    584 /////////////////////////////////////////////////////////////////////////////////////////
    585 //               Marshaling functions attached to RPC_VFS_INODE_DESTROY
     612    hal_remote_swd( XPTR( client_cxy , &desc->args[7] ) , (uint64_t)inode_xp );
     613    hal_remote_swd( XPTR( client_cxy , &desc->args[8] ) , (uint64_t)error );
     614}
     615
     616/////////////////////////////////////////////////////////////////////////////////////////
     617// [11]          Marshaling functions attached to RPC_VFS_INODE_DESTROY
    586618/////////////////////////////////////////////////////////////////////////////////////////
    587619
     
    626658
    627659/////////////////////////////////////////////////////////////////////////////////////////
    628 //               Marshaling functions attached to RPC_VFS_DENTRY_CREATE
     660// [12]          Marshaling functions attached to RPC_VFS_DENTRY_CREATE
    629661/////////////////////////////////////////////////////////////////////////////////////////
    630662
     
    701733
    702734/////////////////////////////////////////////////////////////////////////////////////////
    703 //               Marshaling functions attached to RPC_VFS_DENTRY_DESTROY
     735// [13]          Marshaling functions attached to RPC_VFS_DENTRY_DESTROY
    704736/////////////////////////////////////////////////////////////////////////////////////////
    705737
     
    745777
    746778/////////////////////////////////////////////////////////////////////////////////////////
    747 //               Marshaling functions attached to RPC_VMM_GET_REF_VSEG
     779// [14]          Marshaling functions attached to RPC_VFS_FILE_CREATE
     780/////////////////////////////////////////////////////////////////////////////////////////
     781
     782//////////////////////////////////////////////////////////////
     783void rpc_vfs_file_create_client( cxy_t                  cxy,
     784                                 struct vfs_inode_s   * inode,       // in
     785                                 uint32_t               file_attr,   // in
     786                                 xptr_t               * file_xp,     // out
     787                                 error_t              * error )      // out
     788{
     789    // RPC must be remote
     790    if( cxy == local_cxy )
     791    {
     792        printk("PANIC in %s : target cluster is not remote\n", __FUNCTION__ );
     793        hal_core_sleep();
     794    }
     795
     796    // initialise RPC descriptor header
     797    rpc_desc_t  rpc;
     798    rpc.index    = RPC_VFS_FILE_CREATE;
     799    rpc.response = 1;
     800
     801    // set input arguments in RPC descriptor
     802    rpc.args[0] = (uint64_t)(intptr_t)inode;
     803    rpc.args[1] = (uint64_t)file_attr;
     804
     805    // register RPC request in remote RPC fifo (blocking function)
     806    rpc_send_sync( cxy , &rpc );
     807
     808    // get output values from RPC descriptor
     809    *file_xp = (xptr_t)rpc.args[2];
     810    *error   = (error_t)rpc.args[3];
     811}
     812
     813////////////////////////////////////////////
     814void rpc_vfs_file_create_server( xptr_t xp )
     815{
     816    uint32_t      file_attr;
     817    vfs_inode_t * inode;
     818    xptr_t        file_xp;
     819    error_t       error;
     820
     821    // get client cluster identifier and pointer on RPC descriptor
     822    cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
     823    rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp );
     824
     825    // get arguments "file_attr" and "inode" from client RPC descriptor
     826    inode     = (vfs_inode_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
     827    file_attr = (uint32_t)               hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
     828                       
     829    // call local kernel function
     830    error = vfs_file_create( inode,
     831                             file_attr,
     832                             &file_xp );
     833 
     834    // set output arguments
     835    hal_remote_swd( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)file_xp );
     836    hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
     837}
     838
     839/////////////////////////////////////////////////////////////////////////////////////////
     840// [15]          Marshaling functions attached to RPC_VFS_FILE_DESTROY
     841/////////////////////////////////////////////////////////////////////////////////////////
     842
     843///////////////////////////////////////////////////
     844void rpc_vfs_file_destroy_client( cxy_t        cxy,
     845                                  vfs_file_t * file )
     846{
     847    // RPC must be remote
     848    if( cxy == local_cxy )
     849    {
     850        printk("PANIC in %s : target cluster is not remote\n", __FUNCTION__ );
     851        hal_core_sleep();
     852    }
     853
     854    // initialise RPC descriptor header
     855    rpc_desc_t  rpc;
     856    rpc.index    = RPC_VFS_FILE_DESTROY;
     857    rpc.response = 1;
     858
     859    // set input arguments in RPC descriptor
     860    rpc.args[0] = (uint64_t)(intptr_t)file;
     861   
     862    // register RPC request in remote RPC fifo (blocking function)
     863    rpc_send_sync( cxy , &rpc );
     864}
     865
     866/////////////////////////////////////////////
     867void rpc_vfs_file_destroy_server( xptr_t xp )
     868{
     869    vfs_file_t * file;
     870
     871    // get client cluster identifier and pointer on RPC descriptor
     872    cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
     873    rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp );
     874
     875    // get arguments "dentry" from client RPC descriptor
     876    file = (vfs_file_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
     877                       
     878    // call local kernel function
     879    vfs_file_destroy( file );
     880}
     881
     882/////////////////////////////////////////////////////////////////////////////////////////
     883// [16]          Marshaling functions attached to RPC_FATFS_GET_CLUSTER
     884/////////////////////////////////////////////////////////////////////////////////////////
     885
     886//////////////////////////////////////////////////
     887void rpc_fatfs_get_cluster_client( cxy_t      cxy,
     888                                   mapper_t * mapper,    // in
     889                                   uint32_t   first,     // in
     890                                   uint32_t   page,      // in
     891                                   uint32_t * cluster,   // out
     892                                   error_t  * error )    // out
     893{
     894    // RPC must be remote
     895    if( cxy == local_cxy )
     896    {
     897        printk("PANIC in %s : target is not remote\n", __FUNCTION__ );
     898        hal_core_sleep();
     899    }
     900
     901    // initialise RPC descriptor header
     902    rpc_desc_t  rpc;
     903    rpc.index    = RPC_FATFS_GET_CLUSTER;
     904    rpc.response = 1;
     905
     906    // set input arguments in RPC descriptor
     907    rpc.args[0] = (uint64_t)(intptr_t)mapper;
     908    rpc.args[1] = (uint64_t)first;
     909    rpc.args[2] = (uint64_t)page;
     910
     911    // register RPC request in remote RPC fifo
     912    rpc_send_sync( cxy , &rpc );
     913
     914    // get output argument from rpc descriptor
     915    *cluster = (uint32_t)rpc.args[3];
     916    *error   = (error_t)rpc.args[4];
     917}
     918
     919//////////////////////////////////////////////
     920void rpc_fatfs_get_cluster_server( xptr_t xp )
     921{
     922    mapper_t    * mapper;
     923    uint32_t      first;
     924    uint32_t      page;
     925    uint32_t      cluster;
     926    error_t       error;
     927
     928    // get client cluster identifier and pointer on RPC descriptor
     929    cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
     930    rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );
     931
     932    // get input arguments
     933    mapper = (mapper_t *)(intptr_t)hal_remote_lpt( XPTR( client_cxy , &desc->args[0] ) );
     934    first  = (uint32_t)            hal_remote_lw ( XPTR( client_cxy , &desc->args[1] ) );
     935    page   = (uint32_t)            hal_remote_lw ( XPTR( client_cxy , &desc->args[2] ) );
     936
     937    // call the kernel function
     938    error = fatfs_get_cluster( mapper , first , page , &cluster );
     939
     940    // set output argument
     941    hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)cluster );
     942    hal_remote_swd( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)error );
     943}
     944
     945/////////////////////////////////////////////////////////////////////////////////////////
     946// [20]          Marshaling functions attached to RPC_VMM_GET_REF_VSEG
    748947/////////////////////////////////////////////////////////////////////////////////////////
    749948
     
    8041003
    8051004/////////////////////////////////////////////////////////////////////////////////////////
    806 //               Marshaling functions attached to RPC_VMM_GET_PTE
     1005// [21]          Marshaling functions attached to RPC_VMM_GET_PTE
    8071006/////////////////////////////////////////////////////////////////////////////////////////
    8081007
     
    8671066
    8681067/////////////////////////////////////////////////////////////////////////////////////////
    869 //               Marshaling functions attached to RPC_SEMAPHORE_ALLOC
    870 /////////////////////////////////////////////////////////////////////////////////////////
    871 
    872 //////////////////////////////////////////////
    873 void rpc_semaphore_alloc_client( cxy_t    cxy,
    874                                  xptr_t * sem_xp )     // out
     1068// [22]          Marshaling functions attached to RPC_KCM_ALLOC
     1069/////////////////////////////////////////////////////////////////////////////////////////
     1070
     1071//////////////////////////////////////////
     1072void rpc_kcm_alloc_client( cxy_t      cxy,
     1073                           uint32_t   kmem_type,   // in
     1074                           xptr_t *   buf_xp )     // out
    8751075{
    8761076    // RPC must be remote
     
    8861086    rpc.response = 1;
    8871087
     1088    // set input arguments in RPC descriptor
     1089    rpc.args[0] = (uint64_t)kmem_type;
     1090
    8881091    // register RPC request in remote RPC fifo
    8891092    rpc_send_sync( cxy , &rpc );
    8901093
    8911094    // get output arguments from RPC descriptor
    892     *sem_xp = (xptr_t)rpc.args[0];
    893 }
    894 
    895 ////////////////////////////////////////////
    896 void rpc_semaphore_alloc_server( xptr_t xp )
     1095    *buf_xp = (xptr_t)rpc.args[1];
     1096}
     1097
     1098//////////////////////////////////////
     1099void rpc_kcm_alloc_server( xptr_t xp )
    8971100{
    8981101    // get client cluster identifier and pointer on RPC descriptor
     
    9001103    rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );
    9011104
    902     // allocates memory for semaphore
     1105    // get input argument "kmem_type" from client RPC descriptor
     1106    uint32_t kmem_type = (uint32_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
     1107
     1108    // allocates memory for kcm
    9031109    kmem_req_t  req;
    904     req.type  = KMEM_SEM;
     1110    req.type  = kmem_type;
    9051111    req.flags = AF_ZERO;
    906     remote_sem_t * sem_ptr = kmem_alloc( &req );
     1112    void * buf_ptr = kmem_alloc( &req );
    9071113
    9081114    // set output argument
    909     xptr_t sem_xp = XPTR( local_cxy , sem_ptr );
    910     hal_remote_swd( XPTR( client_cxy , &desc->args[0] ) , (uint64_t)sem_xp );
     1115    xptr_t buf_xp = XPTR( local_cxy , buf_ptr );
     1116    hal_remote_swd( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)buf_xp );
    9111117}   
    9121118
    9131119/////////////////////////////////////////////////////////////////////////////////////////
    914 //               Marshaling functions attached to RPC_SEMAPHORE_FREE
    915 /////////////////////////////////////////////////////////////////////////////////////////
    916 
    917 ///////////////////////////////////////////////////
    918 void rpc_semaphore_free_client( cxy_t          cxy,
    919                                 remote_sem_t * sem )   // in
     1120// [23]          Marshaling functions attached to RPC_KCM_FREE
     1121/////////////////////////////////////////////////////////////////////////////////////////
     1122
     1123/////////////////////////////////////////
     1124void rpc_kcm_free_client( cxy_t      cxy,
     1125                          void     * buf,          // in
     1126                          uint32_t   kmem_type )   // in
    9201127{
    9211128    // RPC must be remote
     
    9321139
    9331140    // set input arguments in RPC descriptor
    934     rpc.args[0] = (uint64_t)(intptr_t)sem;
     1141    rpc.args[0] = (uint64_t)(intptr_t)buf;
     1142    rpc.args[1] = (uint64_t)kmem_type;
    9351143
    9361144    // register RPC request in remote RPC fifo
     
    9381146}
    9391147
    940 ///////////////////////////////////////////
    941 void rpc_semaphore_free_server( xptr_t xp )
     1148/////////////////////////////////////
     1149void rpc_kcm_free_server( xptr_t xp )
    9421150{
    9431151    // get client cluster identifier and pointer on RPC descriptor
     
    9451153    rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );
    9461154
    947     // get input argument "sem_ptr" from client RPC descriptor
    948     void * sem = (void *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
     1155    // get input arguments "buf" and "kmem_type" from client RPC descriptor
     1156    void     * buf = (void *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
     1157    uint32_t   kmem_type = (uint32_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
    9491158
    9501159    // releases memory
    9511160    kmem_req_t  req;
    952     req.type = KMEM_SEM;
    953     req.ptr  = sem;
    954     kmem_free(&req);
     1161    req.type = kmem_type;
     1162    req.ptr  = buf;
     1163    kmem_free( &req );
    9551164}   
    9561165
    9571166/////////////////////////////////////////////////////////////////////////////////////////
    958 //               Marshaling functions attached to RPC_MAPPER_MOVE
    959 /////////////////////////////////////////////////////////////////////////////////////////
    960 
    961 //////////////////////////////////////////////
    962 void rpc_mapper_move_client( cxy_t        cxy,
    963                              mapper_t   * mapper,      // in
    964                              bool_t       read,        // in
    965                              uint32_t     nb_frags,    // in
    966                              fragment_t * frags,       // in
    967                              error_t    * error )      // out
    968 {
    969     // RPC must be remote
    970     if( cxy == local_cxy )
    971     {
    972         printk("PANIC in %s : target is not remote\n", __FUNCTION__ );
     1167// [24]          Marshaling functions attached to RPC_MAPPER_MOVE
     1168/////////////////////////////////////////////////////////////////////////////////////////
     1169
     1170///////////////////////////////////////////
     1171void rpc_mapper_move_client( cxy_t      cxy,
     1172                             mapper_t * mapper,        // in
     1173                             uint32_t   to_buffer,     // in
     1174                             uint32_t   file_offset,   // in
     1175                             void     * buffer,        // in
     1176                             uint32_t   size,          // in
     1177                             error_t  * error )        // out
     1178{
     1179    // RPC must be remote
     1180    if( cxy == local_cxy )
     1181    {
     1182        printk("PANIC in %s : target cluster is not remote\n", __FUNCTION__ );
    9731183        hal_core_sleep();
    9741184    }
     
    9811191    // set input arguments in RPC descriptor
    9821192    rpc.args[0] = (uint64_t)(intptr_t)mapper;
    983     rpc.args[1] = (uint64_t)read;
    984     rpc.args[2] = (uint64_t)nb_frags;
    985     rpc.args[3] = (uint64_t)(intptr_t)frags;
    986 
    987     // register RPC request in remote RPC fifo
    988     rpc_send_sync( cxy , &rpc );
    989 
    990     // get output argument from rpc descriptor
    991     *error = (error_t)rpc.args[4];
     1193    rpc.args[1] = (uint64_t)to_buffer;
     1194    rpc.args[2] = (uint64_t)file_offset;
     1195    rpc.args[3] = (uint64_t)(intptr_t)buffer;
     1196    rpc.args[4] = (uint64_t)size;
     1197
     1198    // register RPC request in remote RPC fifo (blocking function)
     1199    rpc_send_sync( cxy , &rpc );
     1200
     1201    // get output values from RPC descriptor
     1202    *error     = (error_t)rpc.args[5];
    9921203}
    9931204
     
    9951206void rpc_mapper_move_server( xptr_t xp )
    9961207{
    997     mapper_t    * mapper;
    998     bool_t        read;
    999     uint32_t      nb;
    1000     void        * frags;
    1001     error_t       error;
    1002 
    1003     // get client cluster identifier and pointer on RPC descriptor
    1004     cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
    1005     rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );
    1006 
    1007     // get input arguments
    1008     mapper = (mapper_t*)(intptr_t)hal_remote_lpt( XPTR( client_cxy , &desc->args[0] ) );
    1009     read   = (bool_t)             hal_remote_lw ( XPTR( client_cxy , &desc->args[1] ) );
    1010     nb     = (uint32_t)           hal_remote_lw ( XPTR( client_cxy , &desc->args[2] ) );
    1011     frags  = (void*)(intptr_t)    hal_remote_lpt( XPTR( client_cxy , &desc->args[3] ) );
    1012 
    1013     // call the mapper_move_fragments() function
    1014     error = mapper_move_fragments( mapper , read , nb , XPTR( client_cxy , frags ) );
    1015 
    1016     // set output argument
    1017     hal_remote_swd( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)error );
    1018 }
    1019 
    1020 /////////////////////////////////////////////////////////////////////////////////////////
    1021 //               Marshaling functions attached to RPC_FATFS_GET_CLUSTER
    1022 /////////////////////////////////////////////////////////////////////////////////////////
    1023 
    1024 //////////////////////////////////////////////////
    1025 void rpc_fatfs_get_cluster_client( cxy_t      cxy,
    1026                                    mapper_t * mapper,    // in
    1027                                    uint32_t   first,     // in
    1028                                    uint32_t   page,      // in
    1029                                    uint32_t * cluster,   // out
    1030                                    error_t  * error )    // out
    1031 {
    1032     // RPC must be remote
    1033     if( cxy == local_cxy )
    1034     {
    1035         printk("PANIC in %s : target is not remote\n", __FUNCTION__ );
    1036         hal_core_sleep();
    1037     }
    1038 
    1039     // initialise RPC descriptor header
    1040     rpc_desc_t  rpc;
    1041     rpc.index    = RPC_FATFS_GET_CLUSTER;
    1042     rpc.response = 1;
    1043 
    1044     // set input arguments in RPC descriptor
    1045     rpc.args[0] = (uint64_t)(intptr_t)mapper;
    1046     rpc.args[1] = (uint64_t)first;
    1047     rpc.args[2] = (uint64_t)page;
    1048 
    1049     // register RPC request in remote RPC fifo
    1050     rpc_send_sync( cxy , &rpc );
    1051 
    1052     // get output argument from rpc descriptor
    1053     *cluster = (uint32_t)rpc.args[3];
    1054     *error   = (error_t)rpc.args[4];
    1055 }
    1056 
    1057 //////////////////////////////////////////////
    1058 void rpc_fatfs_get_cluster_server( xptr_t xp )
    1059 {
    1060     mapper_t    * mapper;
    1061     uint32_t      first;
    1062     uint32_t      page;
    1063     uint32_t      cluster;
    1064     error_t       error;
    1065 
    1066     // get client cluster identifier and pointer on RPC descriptor
    1067     cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
    1068     rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );
    1069 
    1070     // get input arguments
    1071     mapper = (mapper_t*)(intptr_t)hal_remote_lpt( XPTR( client_cxy , &desc->args[0] ) );
    1072     first  = (uint32_t)           hal_remote_lw ( XPTR( client_cxy , &desc->args[1] ) );
    1073     page   = (uint32_t)           hal_remote_lw ( XPTR( client_cxy , &desc->args[2] ) );
    1074 
    1075     // call the kernel function
    1076     error = fatfs_get_cluster( mapper , first , page , &cluster );
    1077 
    1078     // set output argument
    1079     hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)cluster );
    1080     hal_remote_swd( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)error );
     1208    mapper_t * mapper;
     1209    uint32_t   to_buffer;
     1210    uint32_t   file_offset;
     1211    void     * buffer;
     1212    uint32_t   size;
     1213    error_t    error;
     1214
     1215    // get client cluster identifier and pointer on RPC descriptor
     1216    cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
     1217    rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp );
     1218
     1219    // get arguments from client RPC descriptor
     1220    mapper      = (mapper_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
     1221    to_buffer   =                       hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
     1222    file_offset =                       hal_remote_lwd( XPTR( client_cxy , &desc->args[2] ) );
     1223    buffer      = (void     *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[3] ) );
     1224    size        =                       hal_remote_lwd( XPTR( client_cxy , &desc->args[4] ) );
     1225
     1226    // call local kernel function
     1227    error = mapper_move( mapper,
     1228                         to_buffer,
     1229                         file_offset,
     1230                         buffer,
     1231                         size );
     1232
     1233    // set output argument to client RPC descriptor
     1234    hal_remote_swd( XPTR( client_cxy , &desc->args[5] ) , (uint64_t)error );
    10811235}
    10821236
  • trunk/kernel/kern/rpc.h

    r16 r23  
    22 * rpc.h - RPC (Remote Procedure Call) operations definition.
    33 *
    4  * Authors Mohamed Karaoui (2015)
    5  *         Alain Greiner (2016)
     4 * Author  Alain Greiner (2016,2017)
    65 *
    76 * Copyright (c) UPMC Sorbonne Universites
     
    4342struct vfs_inode_s;
    4443struct vfs_dentry_s;
     44struct vfs_file_s;
    4545struct thread_s;
    4646struct mapper_s;
     
    6363    RPC_THREAD_USER_CREATE     = 4,
    6464    RPC_THREAD_KERNEL_CREATE   = 5,
     65    RPC_SIGNAL_RISE            = 6,
    6566
    6667    RPC_VFS_INODE_CREATE       = 10,
     
    6869    RPC_VFS_DENTRY_CREATE      = 12,
    6970    RPC_VFS_DENTRY_DESTROY     = 13,
     71    RPC_VFS_FILE_CREATE        = 14,
     72    RPC_VFS_FILE_DESTROY       = 15,
     73    RPC_FATFS_GET_CLUSTER      = 16,
    7074
    7175    RPC_VMM_GET_REF_VSEG       = 20,
    7276    RPC_VMM_GET_PTE            = 21,
    73     RPC_SEMAPHORE_ALLOC        = 22,
    74     RPC_SEMAPHORE_FREE         = 23,
     77    RPC_KCM_ALLOC              = 22,
     78    RPC_KCM_FREE               = 23,
    7579    RPC_MAPPER_MOVE            = 24,
    7680
    77     RPC_FATFS_GET_CLUSTER      = 30,
    78 
    79     RPC_MAX_INDEX              = 31,
     81    RPC_MAX_INDEX              = 30,
    8082}
    8183rpc_index_t;
     
    9698        rpc_index_t       index;       // index of requested RPC service
    9799        volatile uint32_t response;    // response valid when 0
    98     uint64_t          args[8];     // input/output arguments buffer
     100    uint64_t          args[10];    // input/output arguments buffer
    99101}
    100102rpc_desc_t;
     
    192194void __attribute__((noinline)) rpc_undefined();
    193195
     196
     197
     198
    194199/**********************************************************************************/
    195200/******* Marshalling functions attached to the various RPCs ***********************/
     
    197202
    198203/***********************************************************************************
    199  * The RPC_PMEM_GET_PAGES allocates one or several pages in a remote cluster,
     204 * [0] The RPC_PMEM_GET_PAGES allocates one or several pages in a remote cluster,
    200205 * and returns the PPN of the first allocated page.
    201206 ***********************************************************************************
     
    213218
    214219/***********************************************************************************
    215  * The RPC_PROCESS_PID_ALLOC allocates one new PID in a remote cluster, registers
     220 * [1] The RPC_PROCESS_PID_ALLOC allocates one new PID in a remote cluster, registers
    216221 * the new process in the remote cluster, and returns the PID, and an error code.
    217222 ***********************************************************************************
     
    229234
    230235/***********************************************************************************
    231  * The RPC_PROCESS_EXEC creates a process descriptor copy, in a remote cluster
     236 * [2] The RPC_PROCESS_EXEC creates a process descriptor copy, in a remote cluster
    232237 * and initializes if from information found in the reference process descriptor.
    233238 * This remote cluster becomes the new reference cluster.
     
    244249
    245250/***********************************************************************************
    246  * The RPC_PROCESS_KILL is actually a multicast RPC sent by the reference cluster
     251 * [3] The RPC_PROCESS_KILL is actually a multicast RPC sent by the reference cluster
    247252 * to other clusters containing a process descriptor copy, to destroy these copies.
    248253 ***********************************************************************************
     
    254259
    255260/***********************************************************************************
    256  * The RPC_THREAD_USER_CREATE creates an user thread in the server cluster,
    257  * as specified by the pthread_attr_t argument. It returns the local pointer
    258  * on the thread descriptor in server cluster, and an error code.
    259  * It is called by the pthread_create system call.
     261 * [4] The RPC_THREAD_USER_CREATE creates an user thread in the server cluster,
     262 * as specified by the arguments. It returns an extended pointer on the new
     263 * thread descriptor in server cluster, and an error code.
     264 * It is called by the sys_thread_create() system call.
    260265 ***********************************************************************************
    261266 * @ cxy       : server cluster identifier.
     
    265270 **********************************************************************************/
    266271void rpc_thread_user_create_client( cxy_t                   cxy,
     272                                    pid_t                   pid,
     273                                    void                  * start_func,
     274                                    void                  * start_arg,
    267275                                    struct pthread_attr_s * attr,
    268276                                    xptr_t                * thread_xp,
     
    272280
    273281/***********************************************************************************
    274  * The RPC_THREAD_KERNEL_CREATE creates a kernel thread in the server cluster,
     282 * [5] The RPC_THREAD_KERNEL_CREATE creates a kernel thread in the server cluster,
    275283 * as specified by the type, func and args arguments. It returns the local pointer
    276284 * on the thread descriptor in server cluster and an error code.
    277  * It is used by the dev_init() function to cretae the device server thread.
     285 * It is used by the dev_init() function to create the device server thread.
    278286 ***********************************************************************************
    279287 * @ cxy       : server cluster identifier.
     
    293301void rpc_thread_kernel_create_server( xptr_t xp );
    294302
     303/***********************************************************************************
     304 * [6] The RPC_SIGNAL_RISE ask a target cluster to register a given signal in
     305 * all threads descriptors of a given process.
     306 * It is used by the sys_kill() function.
     307 ***********************************************************************************
     308 * @ cxy       : server cluster identifier.
     309 * @ process   : [in]  local pointer on target process descriptor in server.
     310 * @ sig_id    : [in]  signal index.
     311 **********************************************************************************/
     312void rpc_signal_rise_client( cxy_t              cxy,
     313                             struct process_s * process,
     314                             uint32_t           sig_id );
     315                             
     316void rpc_signal_rise_server( xptr_t xp );
     317
    295318/***********************************************************************************
    296  * The RPC_VFS_INODE_CREATE creates an inode and the associated mapper in a
     319 * [10] The RPC_VFS_INODE_CREATE creates an inode and the associated mapper in a
    297320 * remote cluster. The parent dentry must have been previously created.
    298321 * It returns an extended pointer on the created inode.
    299322 ***********************************************************************************
    300  * @ cxy       :  server cluster identifier
    301  * @ dentry_xp : [in]  extended pointer on parent dentry.
    302  * @ type      : [in]  file system type.
    303  * @ attr      : [in]  TODO ???
    304  * @ mode      : [in]  access mode.
    305  * @ uid       : [in]  user ID
    306  * @ gid       : [in]  group ID
    307  * @ inode_xp  : [out] buffer for extended pointer on created inode.
    308  * @ error     : [out] error status (0 if success).
     323 * @ cxy        :  server cluster identifier.
     324 * @ dentry_xp  : [in]  extended pointer on parent dentry.
     325 * @ fs_type    : [in]  file system type.
     326 * @ inode_type : [in]  file system type.
     327 * @ attr       : [in]  inode attributes.
     328 * @ rights     : [in]  access rights
     329 * @ uid        : [in]  user ID
     330 * @ gid        : [in]  group ID
     331 * @ inode_xp   : [out] buffer for extended pointer on created inode.
     332 * @ error      : [out] error status (0 if success).
    309333 **********************************************************************************/
    310334void rpc_vfs_inode_create_client( cxy_t      cxy,
    311335                                  xptr_t     dentry_xp,
    312                                   uint32_t   type,
     336                                  uint32_t   fs_type,
     337                                  uint32_t   inode_type,
    313338                                  uint32_t   attr,   
    314                                   uint32_t   mode
     339                                  uint32_t   rights
    315340                                  uint32_t   uid,
    316341                                  uint32_t   gid,
     
    321346
    322347/***********************************************************************************
    323  * The RPC_VFS_INODE_DESTROY releases memory allocated for an inode descriptor
     348 * [11] The RPC_VFS_INODE_DESTROY releases memory allocated for an inode descriptor
    324349 * and for the associated mapper in a remote cluster.
    325350 ***********************************************************************************
     
    333358
    334359/***********************************************************************************
    335  * The RPC_VFS_DENTRY_CREATE creates a dentry in a remote cluster.
     360 * [12] The RPC_VFS_DENTRY_CREATE creates a dentry in a remote cluster.
    336361 * It returns an extended pointer on the created dentry.
    337362 ***********************************************************************************
     
    353378
    354379/***********************************************************************************
    355  * The RPC_VFS_DENTRY_DESTROY releases memory allocated for an dentry descriptor
     380 * [13] The RPC_VFS_DENTRY_DESTROY releases memory allocated for an dentry descriptor
    356381 * in a remote cluster.
    357382 ***********************************************************************************
     
    364389void rpc_vfs_dentry_destroy_server( xptr_t xp );
    365390
    366 
    367 
    368 
    369 /***********************************************************************************
    370  * The RPC_VMM_GET_REF_VSEG returns an extended pointer
     391/***********************************************************************************
     392 * [14] The RPC_VFS_FILE_CREATE creates a file descriptor in a remote cluster.
     393 * It returns an extended pointer on the created file structure.
     394 ***********************************************************************************
     395 * @ cxy        :  server cluster identifier
     396 * @ inode      : [in]  local pointer on parent inode.
     397 * @ file_attr  : [in]  new file attributes.
     398 * @ file_xp    : [out] buffer for extended pointer on created file.
     399 * @ error      : [out] error status (0 if success).
     400 **********************************************************************************/
     401void rpc_vfs_file_create_client( cxy_t                  cxy,
     402                                 struct vfs_inode_s   * inode,
     403                                 uint32_t               file_attr,
     404                                 xptr_t               * file_xp,
     405                                 error_t              * error );
     406
     407void rpc_vfs_file_create_server( xptr_t xp );
     408
     409/***********************************************************************************
     410 * [15] The RPC_VFS_FILE_DESTROY releases memory allocated for a file descriptor
     411 * in a remote cluster.
     412 ***********************************************************************************
     413 * @ cxy       :  server cluster identifier
     414 * @ file       : [in]  local pointer on file.
     415 **********************************************************************************/
     416void rpc_vfs_file_destroy_client( cxy_t               cxy,
     417                                  struct vfs_file_s * file );
     418
     419void rpc_vfs_file_destroy_server( xptr_t xp );
     420
     421/***********************************************************************************
     422 * [16] The RPC_FATFS_GET_CLUSTER can be send by any thread running in a "client"
     423 * cluster to scan the FAT mapper, stored in a remote "server" cluster, and get
     424 * from the mapper the local pointer on a given page.
     425 ***********************************************************************************
     426 * @ cxy      : server cluster identifier.
     427 * @ mapper   : [in]  local pointer on FAT mapper.
     428 * @ first    : [in]  FATFS cluster index allocated to first page of file.
     429 * @ page     : [in]  page index in file.
     430 * @ cluster  : [out] local pointer on buffer for found FATFS cluster index.
     431 * @ error    : [out] local pointer on buffer for error code (in client cluster).
     432 **********************************************************************************/
     433void rpc_fatfs_get_cluster_client( cxy_t             cxy,
     434                                   struct mapper_s * mapper,
     435                                   uint32_t          first,
     436                                   uint32_t          page,
     437                                   uint32_t        * cluster,
     438                                   error_t         * error );   
     439
     440void rpc_fatfs_get_cluster_server( xptr_t xp );
     441
     442/***********************************************************************************
     443 * [20] The RPC_VMM_GET_REF_VSEG returns an extended pointer
    371444 * on the vseg containing a given virtual address in a given process.
    372445 * The server cluster is supposed to be the reference cluster.
     
    386459
    387460/***********************************************************************************
    388  * The RPC_VMM_GET_PTE returns in the "ppn" and "attr" arguments the PTE value
     461 * [21] The RPC_VMM_GET_PTE returns in the "ppn" and "attr" arguments the PTE value
    389462 * for a given VPN in a given process.
    390463 * The server cluster is supposed to be the reference cluster, and the vseg
     
    410483
    411484/***********************************************************************************
    412  * The RPC_SEMAPHORE_ALLOC allocates memory for a semaphore in a remote cluster,
    413  * and returns an extended pointer on the created semaphore.
    414   It returns NULL if physical memory cannot be allocated.
    415  ***********************************************************************************
    416  * @ cxy     : server cluster identifier.
    417  * @ sem_xp  : [out] buffer for extended pointer on semaphore.
    418  **********************************************************************************/
    419 void rpc_semaphore_alloc_client( cxy_t    cxy,
    420                                  xptr_t * sem_xp ); 
    421 
    422 void rpc_semaphore_alloc_server( xptr_t xp );
    423 
    424 /***********************************************************************************
    425  * The RPC_SEMAPHORE_FREE releases memory allocated for a semaphore
     485 * [22] The RPC_KCM_ALLOC allocates memory from a given KCM in a remote cluster,
     486 * and returns an extended pointer on the allocated object.
     487  It returns XPTR_NULL if physical memory cannot be allocated.
     488 ***********************************************************************************
     489 * @ cxy       : server cluster identifier.
     490 * @ kmem_type : [in]  KCM object type (as defined in kmem.h).
     491 * @ buf_xp    : [out] buffer for extended pointer on allocated buffer.
     492 **********************************************************************************/
     493void rpc_kcm_alloc_client( cxy_t      cxy,
     494                           uint32_t   kmem_type,
     495                           xptr_t   * buf_xp ); 
     496
     497void rpc_kcm_alloc_server( xptr_t xp );
     498
     499/***********************************************************************************
     500 * [23] The RPC_KCM_FREE releases memory allocated for a KCM object of a given type,
    426501 * in a remote cluster.
    427502 ***********************************************************************************
    428  * @ cxy     : server cluster identifier.
    429  * @ sem     : [in] local pointer on semaphore.
    430  **********************************************************************************/
    431 void rpc_semaphore_free_client( cxy_t                 cxy,
    432                                 struct remote_sem_s * sem );
    433 
    434 void rpc_semaphore_free_server( xptr_t xp );
    435 
    436 /***********************************************************************************
    437  * The RPC_MAPPER_MOVE can be send by any thread running in a "client" cluster
    438  * to the "server" cluster containing the mapper of a given file. The service is
    439  * to move data between the mapper and an user buffer. This user buffer is described
    440  * as a set of fragments. Each fragment is contained in one single physical page.
    441  * It is defined by four parameters : size / file_offset / ppn / page_offset,
    442  * defined in the mapper.h file. The client thread is in charge of building
    443  * the fragments array covering the user buffer.
    444  * As each fragments can be stored in a different cluster, and this fragment can
    445  * be stored in two successive pages in the radix tree, each fragment is moved
    446  * using one or two different hal_remote_memcpy().
    447  ***********************************************************************************
    448  * @ cxy      : server cluster identifier.
    449  * @ inode    : [in]  local pointer on inode (in server cluster).
    450  * @ read     : [in]  mapper to buffer if true / buffer to mapper if false.
    451  * @ nb_frags : [in]  number of fragments in fragments array.
    452  * @ frags    : [in]  local pointer on fragments array (in client cluster).
    453  * @ error    : [out] local pointer on buffer for error code (in client cluster).
    454  **********************************************************************************/
    455 void rpc_mapper_move_client( cxy_t                cxy,
    456                              struct mapper_s    * mapper,
    457                              bool_t               read,
    458                              uint32_t             nb_frags,
    459                              struct fragment_s  * frags,
    460                              error_t            * error );
     503 * @ cxy       : server cluster identifier.
     504 * @ buf       : [in] local pointer on allocated buffer.
     505 * @ kmem_type : [in]  KCM object type (as defined in kmem.h).
     506 **********************************************************************************/
     507void rpc_kcm_free_client( cxy_t     cxy,
     508                          void    * buf,
     509                          uint32_t  kmem_type );
     510
     511void rpc_kcm_free_server( xptr_t xp );
     512
     513/***********************************************************************************
     514 * [24] The RPC_MAPPER_MOVE is called by the vfs_move() function.
     515 * It allows a client thread to requires a remote mapper to move data to/from
     516 * an user buffer, as specified by the arguments.
     517 ***********************************************************************************
     518 * @ cxy         : server cluster identifier.
     519 * @ mapper      : [in]  local pointer on mapper
     520 * @ to_buffer   : [in]  move data from buffer to mapper if non zero.
     521 * @ file_offset : [in]  first byte to move in mapper
     522 * @ buffer      : [in]  pointer on buffer in user space
     523 * @ size        : [in]  number of bytes to move
     524 * @ error       : [out] error status (0 if success).
     525 **********************************************************************************/
     526void rpc_mapper_move_client( cxy_t             cxy,
     527                             struct mapper_s * mapper,
     528                             uint32_t          to_buffer,
     529                             uint32_t          file_offset,
     530                             void            * buffer,
     531                             uint32_t          size,
     532                             error_t         * error );
    461533
    462534void rpc_mapper_move_server( xptr_t xp );
    463535
    464 /***********************************************************************************
    465  * The RPC_FATFS_GET_CLUSTER can be send by any thread running in a "client" cluster
    466  * to scan the FAT mapper, stored in a remote "server" cluster, and get the FATFS
    467  * cluster index of a given page of a given file.
    468  ***********************************************************************************
    469  * @ cxy      : server cluster identifier.
    470  * @ mapper   : [in]  local pointer on FAT mapper.
    471  * @ first    : [in]  FATFS cluster index allocated to first page of file.
    472  * @ page     : [in]  page index in file.
    473  * @ cluster  : [out] local pointer on buffer for found FATFS cluster index.
    474  * @ error    : [out] local pointer on buffer for error code (in client cluster).
    475  **********************************************************************************/
    476 void rpc_fatfs_get_cluster_client( cxy_t             cxy,
    477                                    struct mapper_s * mapper,
    478                                    uint32_t          first,
    479                                    uint32_t          page,
    480                                    uint32_t        * cluster,
    481                                    error_t         * error );   
    482 
    483 void rpc_fatfs_get_cluster_server( xptr_t xp );
     536
     537
    484538
    485539#endif
  • trunk/kernel/kern/signal.c

    r5 r23  
    2323
    2424#include <hal_types.h>
    25 #include <errno.h>
     25#include <hal_atomic.h>
     26#include <printk.h>
    2627#include <thread.h>
    27 #include <process.h>
    28 #include <core.h>
     28#include <spinlock.h>
    2929#include <signal.h>
     30
     31//////////////////////////////////////
     32void signal_rise( process_t * process,
     33                  uint32_t    sig_id )
     34{
     35    // get the lock protecting the set of local threads
     36        spinlock_lock( &process->th_lock );
     37
     38    // loop on local threads
     39        thread_t * thread;
     40        uint32_t   i;
     41        for( i = 0 ; i < process->th_nr ; i++ )
     42        {
     43                thread = process->th_tbl[i];
     44                hal_atomic_or( &thread->signals , (1 << sig_id) );
     45
     46        signal_dmsg("\n[INFO] %s : thread %x in process %x received signal %d\n",
     47                    __FUNCTION__, thread->trdid , process->pid , sig_id );
     48        }
     49
     50    // release the lock
     51        spinlock_unlock( &process->th_lock );
     52
     53}  // end signal_rise()
     54
     55/*
    3056
    3157SIGNAL_HANDLER(kill_sigaction)
    3258{
    33         struct thread_s *this;
    34  
    35         this = CURRENT_THREAD;
    36         this->state = S_KERNEL;
     59        thread_s * this = CURRENT_THREAD;
    3760
    38         printk(INFO, "INFO: Recieved signal %d, pid %d, tid %x, core %d  [ KILLED ]\n",
     61        printk("\n[INFO] %s : threadReceived signal %d, pid %d, tid %x, core %d  [ KILLED ]\n",
    3962               sig,
    4063               this->process->pid,
     
    4568}
    4669
    47 //////////////////////////////////////////////////
     70///////////////////////////////////////////////
    4871void signal_manager_init( process_t * process )
    4972{
     
    5376}
    5477
    55 //////////////////////////////////////
    56 void signal_rise( process_t * process,
    57                   uint32_t    sig )
     78
     79/////////////////////////////////////
     80void signal_notify( thread_t * this )
    5881{
    59         thread_t     * thread;
    60         uint32_t       i;
     82        uint32_t     sig_state;
     83        uint32_t     sig;
     84        sig_mgr_t  * sig_mgr;
     85        uint32_t     irq_state;
    6186
    62         spinlock_lock( &process->th_lock );
    63 
    64         for( i = 0 ; i < process->th_nr ; i++ )
    65         {
    66                 thread = process->th_tbl[i];
    67                 hal_atomic_or( &thread->signals , (1 << sig) );
    68         }
    69 
    70         spinlock_unlock( &process->th_lock );
    71 
    72         sig_dmsg("\n[INFO] %s : %d threads have been signaled for process %d\n",
    73                         __FUNCTION__, process->th_nr , process->pid );
    74 
    75 }  // end signal_rise()
    76 
    77 ///////////////////////////////////////////
    78 RPC_DECLARE( __signal_rise,                             \
    79                 RPC_RET( RPC_RET_PTR(error_t, err)),    \
    80                 RPC_ARG( RPC_ARG_VAL(pid_t,   pid),     \
    81                          RPC_ARG_VAL(uint32_t,  sig))     \
    82            )
    83 {
    84          process_t   * process;
    85         struct hnode_s  *hnode;
    86 
    87         /* Avoid killing process0 and init */
    88         /* FIXME: Zero should not be hard-coded but obtains with something like MAIN_KERN */
    89         if( ((pid == PID_MIN_GLOBAL) || (pid == PID_MIN_GLOBAL+1))
    90                         && (current_cid == 0) )
    91         {
    92                 *err = EPERM;
    93                 sig_dmsg(1, "%s: can't kill process %u on cluster %u\n",           \
    94                                 __FUNCTION__, PID_GET_LOCAL(pid), current_cid);
    95                 goto SYS_RISE_ERR_PID;
    96         }
    97 
    98         /* Step 1 : lock the process manager */
    99         processs_manager_lock();
    100 
    101         /* Step 2 : Get the process' address */
    102         /* Case 1 : current cluster is the anchor and the owner. */
    103         if ( PID_GET_CLUSTER(pid) == current_cid )
    104         {
    105                 sig_dmsg(1, "%s: process %u is in the processs manager array of cluster  %u\n",       \
    106                                 __FUNCTION__, pid, current_cid);
    107                 process = process_lookup(pid)->process;
    108 
    109         }
    110         else /* Case 2 : current cluster is not the anchor, so the struct
    111               * process_s is in its hash table.
    112               */
    113         {
    114                 sig_dmsg(1, "%s: process %u is in the processs manager hash table of cluster  %u\n",  \
    115                                 __FUNCTION__, pid, current_cid);
    116                 hnode = hfind(processs_manager_get_htable(), (void*)pid);
    117                 process    = ( process_t*) container_of(hnode,          \
    118                                  process_t, t_hnode);
    119         }
    120 
    121         /* Step 4 : check process' address */
    122         if ( process == NULL )
    123         {
    124                 *err = ESRCH;
    125                 goto SYS_RISE_ERR;
    126         }
    127 
    128         /* Step 5 : deliver signal */
    129         if((sig == SIGTERM) || (sig == SIGKILL))
    130                 *err = signal_rise_all(process, sig);
    131         else
    132                 *err = signal_rise_one(process, sig);
    133 
    134         /* Step 6 : unlock processs manager */
    135         processs_manager_unlock();
    136 
    137         return;
    138 
    139 SYS_RISE_ERR:
    140         processs_manager_unlock();
    141 SYS_RISE_ERR_PID:
    142         sig_dmsg(1, "%s: Cluster %u has not deliver signal %u to process %u (err %u)\n",  \
    143                         __FUNCTION__, current_cid, sig, err );
    144 
    145         return;
    146 }
    147 
    148 ///////////////////////////////
    149 error_t sys_kill( pid_t    pid,
    150                   uint32_t sig)
    151 {
    152     cxy_t       owner_cxy;    // process owner cluster
    153     lpid_t      owner_lpid;   // local process identifier
    154     xptr_t      root_xp;      // extended pointer on root of xlist of process copies
    155     xptr_t      lock_xp;      // extended pointer on remote_spinlock protecting this list
    156     xptr_t      iter_xp;      // iterator for process copies list
    157     xptr_t      process_xp;   // local pointer on process copy
    158     cxy_t       process_cxy;  // cluster of process copy
    159     process_t * process_ptr;  // local pointer on process copy
    160         error_t     error;
    161 
    162     // get local pointer on local cluster manager
    163     cluster_t * cluster = LOCAL_CLUSTER;
    164 
    165     // get owner process cluster and lpid
    166     owner_cxy  = CXY_FROM_PID( pid );
    167     owner_lpid = LPID_FROM_PID( pid );
    168 
    169     // get extended pointers on copies root and lock
    170     root_xp = XPTR( owner_cxy , &cluster->copies_root[lpid] );
    171     lock_xp = XPTR( owner_cxy , &cluster->copies_lock[lpid] );
    172 
    173     // take the lock protecting the copies
    174     remote_spinlock_lock( lock_xp );
    175 
    176     // TODO the loop below sequencialize the RPCs
    177     // they could be pipelined...
    178  
    179     // traverse the list of copies
    180     XLIST_FOREACH( root_xp , iter_xp )
    181     {
    182         process_xp  = XLIST_ELEMENT( iter_xp , process_t , copies_list );
    183         process_cxy = GET_CXY( process_xp );
    184         process_ptr = (process_t *)GET_PTR( process_xp );
    185 
    186         if( process_xy == local_cxy )   // process copy is local
    187         {
    188             error = signal_rise( process_ptr , sig );
    189         }
    190         else                           // process copy is remote
    191         {
    192             rpc_signal_rise_client( process_cxy , process_ptr , sig );
    193         }
    194     }
    195 
    196         return 0;
    197 }
    198 
    199 ////////////////////////////////////
    200 void signal_notify( thread_s * this)
    201 {
    202         register uint32_t sig_state;
    203         register uint32_t sig;
    204         register struct sig_mgr_s *sig_mgr;
    205         uint32_t irq_state;
    206 
    207         sig_state = this->info.sig_state & this->info.sig_mask;
     87        sig_state = this->signals;
    20888        sig       = 0;
    20989 
     
    242122        }
    243123}
     124*/
  • trunk/kernel/kern/signal.h

    r16 r23  
    44 * Author  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
     
    3333#define SIG_ERROR     -1L
    3434
    35 #define SIGHUP     1       /*! hangup */
    36 #define SIGINT     2       /*! interrupt */
    37 #define SIGQUIT    3       /*! quit */
    38 #define SIGILL     4       /*! illegal instruction (not reset when caught) */
    39 #define SIGTRAP    5       /*! trace trap (not reset when caught) */
    40 #define SIGIOT     6       /*! IOT instruction */
    41 #define SIGABRT    6       /*! used by abort, replace SIGIOT in the future */
    42 #define SIGEMT     7       /*! EMT instruction */
    43 #define SIGFPE     8       /*! floating point exception */
    44 #define SIGKILL    9       /*! kill (cannot be caught or ignored) */
    45 #define SIGBUS     10      /*! bus error */
    46 #define SIGSEGV    11      /*! segmentation violation */
    47 #define SIGSYS     12      /*! bad argument to system call */
    48 #define SIGPIPE    13      /*! write on a pipe with no one to read it */
    49 #define SIGALRM    14      /*! alarm clock */
    50 #define SIGTERM    15      /*! software termination signal from kill */
    51 #define SIGURG     16      /*! urgent condition on IO channel */
    52 #define SIGSTOP    17      /*! sendable stop signal not from tty */
    53 #define SIGTSTP    18      /*! stop signal from tty */
    54 #define SIGCONT    19      /*! continue a stopped process */
    55 #define SIGCHLD    20      /*! to parent on child stop or exit */
    56 #define SIGCLD     20      /*! System V name for SIGCHLD */
    57 #define SIGTTIN    21      /*! to readers pgrp upon background tty read */
    58 #define SIGTTOU    22      /*! like TTIN for output if (tp->t_local&LTOSTOP) */
    59 #define SIGIO      23      /*! input/output possible signal */
    60 #define SIGPOLL    SIGIO   /*! System V name for SIGIO */
    61 #define SIGXCPU    24      /*! exceeded CPU time limit */
    62 #define SIGXFSZ    25      /*! exceeded file size limit */
    63 #define SIGVTALRM  26      /*! virtual time alarm */
    64 #define SIGPROF    27      /*! profiling time alarm */
    65 #define SIGWINCH   28      /*! window changed */
    66 #define SIGLOST    29      /*! resource lost (eg, record-lock lost) */
    67 #define SIGUSR1    30      /*! user defined signal 1 */
    68 #define SIGUSR2    31      /*! user defined signal 2 */
    69 #define SIG_NR     32      /*! signal 0 implied */
     35#define SIGHUP     1       /*! hangup                                                     */
     36#define SIGINT     2       /*! interrupt                                                  */
     37#define SIGQUIT    3       /*! quit                                                       */
     38#define SIGILL     4       /*! illegal instruction (not reset when caught)                */
     39#define SIGTRAP    5       /*! trace trap (not reset when caught)                         */
     40#define SIGIOT     6       /*! IOT instruction                                            */
     41#define SIGABRT    6       /*! used by abort, replace SIGIOT in the future                */
     42#define SIGEMT     7       /*! EMT instruction                                            */
     43#define SIGFPE     8       /*! floating point exception                                   */
     44#define SIGKILL    9       /*! kill (cannot be caught or ignored)                         */
     45#define SIGBUS     10      /*! bus error                                                  */
     46#define SIGSEGV    11      /*! segmentation violation                                     */
     47#define SIGSYS     12      /*! bad argument to system call                                */
     48#define SIGPIPE    13      /*! write on a pipe with no one to read it                     */
     49#define SIGALRM    14      /*! alarm clock                                                */
     50#define SIGTERM    15      /*! software termination signal from kill                      */
     51#define SIGURG     16      /*! urgent condition on IO channel                             */
     52#define SIGSTOP    17      /*! sendable stop signal not from tty                          */
     53#define SIGTSTP    18      /*! stop signal from tty                                       */
     54#define SIGCONT    19      /*! continue a stopped process                                 */
     55#define SIGCHLD    20      /*! to parent on child stop or exit                            */
     56#define SIGCLD     20      /*! System V name for SIGCHLD                                  */
     57#define SIGTTIN    21      /*! to readers pgrp upon background tty read                   */
     58#define SIGTTOU    22      /*! like TTIN for output if (tp->t_local&LTOSTOP)              */
     59#define SIGIO      23      /*! input/output possible signal                               */
     60#define SIGPOLL    SIGIO   /*! System V name for SIGIO                                    */
     61#define SIGXCPU    24      /*! exceeded CPU time limit                                    */
     62#define SIGXFSZ    25      /*! exceeded file size limit                                   */
     63#define SIGVTALRM  26      /*! virtual time alarm                                         */
     64#define SIGPROF    27      /*! profiling time alarm                                       */
     65#define SIGWINCH   28      /*! window changed                                             */
     66#define SIGLOST    29      /*! resource lost (eg, record-lock lost)                       */
     67#define SIGUSR1    30      /*! user defined signal 1                                      */
     68#define SIGUSR2    31      /*! user defined signal 2                                      */
     69#define SIG_NR     32      /*! signal 0 implied                                           */
    7070
    7171#define SIG_DEFAULT_MASK         0xFFEEFFFF
     
    8181
    8282/*******************************************************************************************
    83  * This structure ...
     83 * This structure ... TODO
    8484 ******************************************************************************************/
    8585
     
    104104
    105105/*******************************************************************************************
    106  * This structure ...
     106 * This structure ... TODO
    107107 ******************************************************************************************/
    108108
     
    122122
    123123/*******************************************************************************************
    124  * This structure TODO
     124 * This structure ... TODO
    125125 ******************************************************************************************/
    126126
     
    132132sig_mgr_t;
    133133
    134 
    135134/*******************************************************************************************
    136  * This function TODO
    137  ******************************************************************************************/
    138 int sys_signal ( uint32_t       sig,
    139                  sa_handler_t * handler );
    140 
    141 /*******************************************************************************************
    142  * This function TODO
     135 * This function ... TODO
    143136 ******************************************************************************************/
    144137int sys_sigreturn_setup( void * sigreturn_func );
    145138
    146 /*******************************************************************************************
    147  * This function register the signal <sig> in the bit_vector of all threads of a given
    148  * process identified by its <pid>, in all clusters containing threads for this process.
    149  * It can be executed by any thread running in any cluster, as this function uses
    150  * remote access to traverse the list of process copies, and the RPC_RISE_SIGNAL
    151  * to deliver the signal to all involved clusters.
    152  * The list of process copies is rooted in the owner cluster.
    153  ******************************************************************************************/
    154 int sys_kill( pid_t    pid,
    155               uint32_t sig );
    156139
    157140/*******************************************************************************************
    158  * This function TODO
     141 * This function ... TODO
    159142 ******************************************************************************************/
    160 error_t signal_manager_init( struct process_s * process );
     143void signal_manager_init( struct process_s * process );
    161144
    162145/*******************************************************************************************
     
    165148 * It must be executed by a thread running in the same cluster as the target threads
    166149 * (can be a local thread or a RPC thread).
     150 *******************************************************************************************
     151 * @ process   : local pointer on local target process.
     152 * @ sig_id    : signal type.
    167153 ******************************************************************************************/
    168 error_t signal_rise( struct process_s * process,
    169                      uint32_t           sig );
     154void signal_rise( struct process_s * process,
     155                  uint32_t           sig_id );
    170156
    171157/*******************************************************************************************
  • trunk/kernel/kern/thread.c

    r16 r23  
    33 *
    44 * Author  Ghassan Almaless (2008,2009,2010,2011,2012)
    5  *         Mohamed Lamine Karaoui (2015)
    6  *         Alain Greiner (2016)
     5 *         Alain Greiner (2016,2017)
    76 *
    87 * Copyright (c) UPMC Sorbonne Universites
     
    7473static thread_t * thread_alloc()
    7574{
    76         page_t       * page;       // pointer on page descriptor containing thread descriptor
    77         kmem_req_t     req;        // kmem request
     75        page_t       * page;   // pointer on page descriptor containing thread descriptor
     76        kmem_req_t     req;    // kmem request
    7877
    7978        // allocates memory for thread descriptor + kernel stack
     
    8483
    8584    // return pointer on new thread descriptor
    86         if( page == NULL )
    87     {
    88         printk("\n[ERROR] in %s : no memory for thread descriptor\n", __FUNCTION__ );
    89         return NULL;
    90     }
    91     else
    92     {
    93         return (thread_t *)ppm_page2base( page );
    94     }
    95 }  // end thread_alloc()
     85        if( page == NULL ) return NULL;
     86    else               return (thread_t *)ppm_page2base( page );
     87
     88
     89/////////////////////////////////////////////////////////////////////////////////////
     90// This static function releases the physical memory for a thread descriptor.
     91// It can be called by the three functions:
     92// - thread_user_create()
     93// - thread_user_fork()
     94// - thread_kernel_create()
     95/////////////////////////////////////////////////////////////////////////////////////
     96// @ thread  : pointer on thread descriptor.
     97/////////////////////////////////////////////////////////////////////////////////////
     98static void thread_release( thread_t * thread )
     99{
     100    kmem_req_t   req;
     101
     102    req.type  = KMEM_PAGE;
     103    req.ptr   = ppm_base2page( thread );
     104    kmem_free( &req );
     105}
    96106
    97107/////////////////////////////////////////////////////////////////////////////////////
     
    194204
    195205/////////////////////////////////////////////////////////
    196 error_t thread_user_create( thread_t       ** new_thread,
     206error_t thread_user_create( pid_t             pid,
     207                            void            * start_func,
     208                            void            * start_arg,
    197209                            pthread_attr_t  * attr,
    198                             intptr_t          u_stack_base,
    199                             uint32_t          u_stack_size )
     210                            thread_t       ** new_thread )
    200211{
    201212    error_t        error;
     
    203214    process_t    * process;      // pointer to local process descriptor
    204215    lid_t          core_lid;     // selected core local index
    205         kmem_req_t     req;          // kmem request (for release)
    206 
    207     thread_dmsg("\n[INFO] %s : enters\n", __FUNCTION__ );
    208 
    209         cluster_t    * local_cluster = LOCAL_CLUSTER;
     216    vseg_t       * vseg;         // stack vseg
     217
     218    thread_dmsg("\n[INFO] %s : enters for process %x\n", __FUNCTION__ , pid );
     219
     220    // get process descriptor local copy
     221    process = process_get_local_copy( pid );
     222
     223    if( process == NULL )
     224    {
     225                printk("\n[ERROR] in %s : cannot get process descriptor %x\n",
     226               __FUNCTION__ , pid );
     227        return ENOMEM;
     228    }
    210229
    211230    // select a target core in local cluster
    212     if( attr->flags & PT_FLAG_CORE_DEFINED ) core_lid = attr->lid;
    213     else                                     core_lid = cluster_select_local_core();
     231    if( attr->attributes & PT_ATTR_CORE_DEFINED ) core_lid = attr->lid;
     232    else                                          core_lid = cluster_select_local_core();
    214233
    215234    // check core local index
    216     if( core_lid >= local_cluster->cores_nr ) return EINVAL;
    217 
    218     // get process descriptor local copy
    219     process = process_get_local_copy( attr->pid );
    220     if( process == NULL ) return ENOMEM;
     235    if( core_lid >= LOCAL_CLUSTER->cores_nr )
     236    {
     237            printk("\n[ERROR] in %s : illegal core index attribute = %d\n",
     238               __FUNCTION__ , core_lid );
     239       
     240        return EINVAL;
     241    }
     242
     243    // allocate a stack from local VMM
     244    vseg = vmm_create_vseg( process, 0 , 0 , VSEG_TYPE_STACK );
     245
     246    if( vseg == NULL );
     247    {
     248            printk("\n[ERROR] in %s : cannot create stack vseg\n", __FUNCTION__ );
     249                return ENOMEM;
     250    }
    221251
    222252    // allocates memory tor thread descriptor
    223253    thread = thread_alloc();
    224254
    225     if( thread == NULL ) return ENOMEM;
     255    if( thread == NULL )
     256    {
     257            printk("\n[ERROR] in %s : cannot create new thread\n", __FUNCTION__ );
     258        vmm_remove_vseg( vseg );
     259        return ENOMEM;
     260    }
    226261
    227262    // initializes thread descriptor
     
    229264                         process,
    230265                         THREAD_USER,
    231                          attr->entry_func,
    232                          attr->entry_args,
     266                         start_func,
     267                         start_arg,
    233268                         core_lid,
    234                          u_stack_base,
    235                          u_stack_size );
    236 
    237     if( error )  // release allocated memory for thread descriptor
    238     {
    239             req.type  = KMEM_PAGE;
    240         req.ptr   = ppm_base2page( thread );
    241         kmem_free( &req );
     269                         vseg->min,
     270                         vseg->max - vseg->min );
     271
     272    if( error )
     273    {
     274            printk("\n[ERROR] in %s : cannot initialize new thread\n", __FUNCTION__ );
     275        vmm_remove_vseg( vseg );
     276        thread_release( thread );
    242277        return EINVAL;
    243278    }
     
    247282
    248283    // set DETACHED flag if required
    249     if( attr->flags & PT_FLAG_DETACH ) thread->flags |= THREAD_FLAG_DETACHED;
     284    if( attr->attributes & PT_ATTR_DETACH ) thread->flags |= THREAD_FLAG_DETACHED;
    250285
    251286    // allocate & initialise CPU context
    252287        error = hal_cpu_context_create( thread );
    253     if( error ) return ENOMEM;
     288
     289    if( error )
     290    {
     291            printk("\n[ERROR] in %s : cannot create CPU context\n", __FUNCTION__ );
     292        vmm_remove_vseg( vseg );
     293        thread_release( thread );
     294        return ENOMEM;
     295    }
    254296
    255297    // allocate & initialise FPU context
    256298    error = hal_fpu_context_create( thread );
    257     if( error ) return ENOMEM;
    258  
     299
     300    if( error )
     301    {
     302            printk("\n[ERROR] in %s : cannot create FPU context\n", __FUNCTION__ );
     303        vmm_remove_vseg( vseg );
     304        thread_release( thread );
     305        return ENOMEM;
     306    }
     307
    259308    thread_dmsg("\n[INFO] %s : exit / trdid = %x / process %x / core = %d\n",
    260309                __FUNCTION__ , thread->trdid , process->pid , core_lid );
     
    266315
    267316
    268 /////////////////////////////////////////////////
    269 error_t thread_user_fork( thread_t ** new_thread,
    270                           process_t * process,
    271                           intptr_t    u_stack_base,
    272                           uint32_t    u_stack_size )
     317//////////////////////////////////////////////
     318error_t thread_user_fork( process_t * process,
     319                          thread_t ** new_thread )
    273320{
    274321    error_t        error;
    275322        thread_t     * thread;       // pointer on new thread descriptor
    276323    lid_t          core_lid;     // selected core local index
    277         kmem_req_t     req;          // kmem request (for release)
     324        vseg_t       * vseg;         // stack vseg
    278325
    279326    thread_dmsg("\n[INFO] %s : enters\n", __FUNCTION__ );
     327
     328    // allocate a stack from local VMM
     329    vseg = vmm_create_vseg( process, 0 , 0 , VSEG_TYPE_STACK );
     330
     331    if( vseg == NULL );
     332    {
     333            printk("\n[ERROR] in %s : cannot create stack vseg\n", __FUNCTION__ );
     334                return ENOMEM;
     335    }
    280336
    281337    // select a target core in local cluster
     
    288344    thread = thread_alloc();
    289345
    290     if( thread == NULL ) return ENOMEM;
     346    if( thread == NULL )
     347    {
     348        printk("\n[ERROR] in %s : cannot allocate new thread\n", __FUNCTION__ );
     349        vmm_remove_vseg( vseg );
     350        return ENOMEM;
     351    }
    291352
    292353    // initializes thread descriptor
     
    297358                         this->entry_args,
    298359                         core_lid,
    299                          u_stack_base,
    300                          u_stack_size );
    301 
    302     if( error ) // release allocated memory for thread descriptor
    303     {
    304             req.type  = KMEM_PAGE;
    305         req.ptr   = ppm_base2page( thread );
    306         kmem_free( &req );
     360                         vseg->min,
     361                         vseg->max - vseg->min );
     362
     363    if( error )
     364    {
     365            printk("\n[ERROR] in %s : cannot initialize new thread\n", __FUNCTION__ );
     366        vmm_remove_vseg( vseg );
     367        thread_release( thread );
    307368        return EINVAL;
    308369    }
     
    313374    // allocate & initialise CPU context from calling thread
    314375        error = hal_cpu_context_copy( thread , this );
    315     if( error ) return ENOMEM;
     376
     377    if( error )
     378    {
     379            printk("\n[ERROR] in %s : cannot create CPU context\n", __FUNCTION__ );
     380        vmm_remove_vseg( vseg );
     381        thread_release( thread );
     382        return ENOMEM;
     383    }
    316384
    317385    // allocate & initialise FPU context from calling thread
    318386        error = hal_fpu_context_copy( thread , this );
    319     if( error ) return ENOMEM;
    320 
    321     thread_dmsg("INFO : %s thread %x for process %x on core %d in cluster %x\n",
     387
     388    if( error )
     389    {
     390            printk("\n[ERROR] in %s : cannot create CPU context\n", __FUNCTION__ );
     391        vmm_remove_vseg( vseg );
     392        thread_release( thread );
     393        return ENOMEM;
     394    }
     395
     396    thread_dmsg("\n[INFO] %s : exit / thread %x for process %x on core %d in cluster %x\n",
    322397                 __FUNCTION__, thread->trdid, process->pid, core_lid, local_cxy );
    323398
     
    473548        spinlock_unlock( &process->th_lock );
    474549       
     550    // update local DQDT
     551    dqdt_local_update_threads( -1 );
     552
    475553    // invalidate thread descriptor
    476554        thread->signature = 0;
    477555
    478556    // release memory for thread descriptor
    479         kmem_req_t   req;
    480         req.type     = KMEM_PAGE;
    481         req.ptr      = ppm_base2page( thread );
    482         kmem_free(&req);
     557    thread_release( thread );
    483558
    484559        tm_end = hal_time_stamp();
     
    706781
    707782////////////////////////////////////////////////
    708 void thread_signals_handler( thread_t * thread )
     783void thread_signals_handle( thread_t * thread )
    709784{
    710785    // TODO
     
    712787}
    713788
    714 
     789/////////////////////////////////////
     790xptr_t thread_get_xptr( pid_t    pid,
     791                        trdid_t  trdid )
     792{
     793    cxy_t         target_cxy;          // target thread cluster identifier
     794    ltid_t        target_thread_ltid;  // target thread local index
     795    thread_t    * target_thread_ptr;   // target thread local pointer           
     796    xptr_t        target_process_xp;   // extended pointer on target process descriptor
     797    process_t   * target_process_ptr;  // local pointer on target process descriptor
     798    pid_t         target_process_pid;  // target process identifier
     799    xlist_entry_t root;                // root of list of process in target cluster
     800    xptr_t        lock_xp;             // extended pointer on lock protecting  this list
     801
     802    // get target cluster identifier and local thread identifier
     803    target_cxy         = CXY_FROM_TRDID( trdid );
     804    target_thread_ltid = LTID_FROM_TRDID( trdid );
     805
     806    // get root of list of process descriptors in target cluster
     807    hal_remote_memcpy( XPTR( local_cxy  , &root ),
     808                       XPTR( target_cxy , &LOCAL_CLUSTER->pmgr.local_root ),
     809                       sizeof(xlist_entry_t) );
     810
     811    // get extended pointer on lock protecting the list of processes
     812    lock_xp = XPTR( target_cxy , &LOCAL_CLUSTER->pmgr.local_lock );
     813
     814    // take the lock protecting the list of processes in target cluster
     815    remote_spinlock_lock( lock_xp );
     816
     817    // loop on list of process in target cluster to find the PID process
     818    xptr_t  iter;
     819    bool_t  found = false;
     820    XLIST_FOREACH( XPTR( target_cxy , &LOCAL_CLUSTER->pmgr.local_root ) , iter )
     821    {
     822        target_process_xp  = XLIST_ELEMENT( iter , process_t , local_list );
     823        target_process_ptr = (process_t *)GET_PTR( target_process_xp );
     824        target_process_pid = hal_remote_lw( XPTR( target_cxy , &target_process_ptr->pid ) );
     825        if( target_process_pid == pid )
     826        {
     827            found = true;
     828            break;
     829        }
     830    }
     831
     832    // release the lock protecting the list of processes in target cluster
     833    remote_spinlock_unlock( lock_xp );
     834
     835    // check target thread found
     836    if( found == false )
     837    {
     838        return XPTR_NULL;
     839    }
     840
     841    // get target thread local pointer
     842    xptr_t xp = XPTR( target_cxy , &target_process_ptr->th_tbl[target_thread_ltid] );
     843    target_thread_ptr = (thread_t *)hal_remote_lpt( xp );   
     844
     845    if( target_thread_ptr == NULL )
     846    {
     847        return XPTR_NULL;
     848    }
     849
     850    return XPTR( target_cxy , target_thread_ptr );
     851
     852}  // end thread_get_xptr()
     853
  • trunk/kernel/kern/thread.h

    r16 r23  
    33 *
    44 * Author  Ghassan Almaless (2008,2009,2010,2011,2012)
    5  *         Mohamed Lamine Karaoui (2015)
    65 *         Alain Greiner (2016)
    76 *
     
    4342
    4443/***************************************************************************************
    45  * This defines the various pthread_attr_t flags.
    46  **************************************************************************************/
    47 
    48 #define PT_FLAG_DETACH                0x001    // user defined not joinable
    49 #define PT_FLAG_CLUSTER_DEFINED       0x002    // user defined target cluster
    50 #define PT_FLAG_CORE_DEFINED          0x004    // user defined core cluster
    51 
    52 /***************************************************************************************
    53  * This structure defines the input argument of the pthread_create() system call.
    54  * It contains all informations required to initialize an user thread, and is passed
    55  * as input argument to the thread_user_create() function.
    56  * It is partly set by the kernel, partly set by the user application itself,
    57  * using the pthread_attr_***() functions.
     44 * These macros are used to compose or decompose global thread identifier (TRDID)
     45 * to or from cluster identifier / local thread index (CXY , LTID)
     46 **************************************************************************************/
     47
     48#define LTID_FROM_TRDID( trdid )   (ltid_t)(trdid & 0x0000FFFF)
     49#define CXY_FROM_TRDID( trdid )    (cxy_t)(trdid >> 16)
     50#define TRDID( cxy , ltid )        (trdid_t)((cxy << 16) | ltid )
     51
     52/***************************************************************************************
     53 * This defines the various pthread_attr_t attributes bit-vector.
     54 **************************************************************************************/
     55
     56/***************************************************************************************
     57 * This opaque structure contains the user defined attributes for an user thread.
     58 * It is passed as input argument to the thread_user_create() function.
     59 * It is set by the user application itself, using the pthread_attr_***() functions.
     60 * The currently supported attributes are defined below.
    5861 **************************************************************************************/
    5962 
    6063typedef struct pthread_attr_s
    6164{
    62     pid_t       pid;             /*! owner process identifier                         */
    63         void      * entry_func;      /*! pointer on entry function                        */
    64         void      * entry_args;      /*! pointer on entry function arguments              */
    65         uint32_t    flags;           /*! pthread flags        (entirely user specified)   */
    66         cxy_t       cxy;             /*! target cluster       (can be user specified)     */
    67         lid_t       lid;             /*! target core          (can be user specified)     */
     65        uint32_t    attributes;      /*! user defined attributes bit vector               */
     66        cxy_t       cxy;             /*! target cluster identifier                        */
     67        lid_t       lid;             /*! target core index                                */
    6868}
    6969pthread_attr_t;
    7070
     71typedef enum
     72{
     73    PT_ATTR_DETACH          = 0x0001,  /*! user defined not joinable                  */
     74    PT_ATTR_CLUSTER_DEFINED = 0x0002,  /*! user defined target cluster                */
     75    PT_ATTR_CORE_DEFINED    = 0x0004,  /*! user defined core index in cluster         */
     76}
     77pt_attributes_t;
    7178
    7279/***************************************************************************************
     
    8693
    8794/***************************************************************************************
    88  * This defines the masks associated to the thread flags.
     95 * This defines the thread flags bit-vector.
    8996 **************************************************************************************/
    9097
    9198#define THREAD_FLAG_LOADABLE     0x0001  /*! This thread has not been executed yet    */
    92 #define THREAD_FLAG_DETACHED     0x0002  /*! This user thread is detached from parent */
     99#define THREAD_FLAG_DETACHED     0x0002  /*! This thread is detached from parent      */
     100#define THREAD_FLAG_JOIN         0x0004  /*! Parent thread made a join                */
     101#define THREAD_FLAG_EXIT         0x0008  /*! This thread made an exit                 */
    93102
    94103/***************************************************************************************
     
    102111 **************************************************************************************/
    103112
    104 #define THREAD_BLOCKED_GLOBAL    0x0001  /*! thread global blocking                   */
     113#define THREAD_BLOCKED_GLOBAL    0x0001  /*! thread desactivated / wait activation    */
    105114#define THREAD_BLOCKED_IO        0x0002  /*! thread wait IO operation completion      */
    106115#define THREAD_BLOCKED_MAPPER    0x0004  /*! thread wait mapper                       */
    107 #define THREAD_BLOCKED_EXIT      0x0010  /*! thread requested exit                    */
     116#define THREAD_BLOCKED_JOIN      0x0008  /*! thread blocked in join / wait exit       */
     117#define THREAD_BLOCKED_EXIT      0x0010  /*! thread blocked in exit / wait join i     */
    108118#define THREAD_BLOCKED_KILL      0x0020  /*! thread received kill signal              */
    109119#define THREAD_BLOCKED_SEM       0x0040  /*! thread wait semaphore                    */
    110120#define THREAD_BLOCKED_PAGE      0x0080  /*! thread wait page access                  */
     121#define THREAD_BLOCKED_USERSYNC  0x0100  /*! thread wait POSIX (cond/mutex/barrier)   */
     122
    111123#define THREAD_BLOCKED_IDLE      0x1000  /*! thread RPC wait activation               */
    112124#define THREAD_BLOCKED_DEV_QUEUE 0x2000  /*! thread DEV wait queue                    */
     
    141153 * that is returned by the kernel to the user:
    142154 * - The TRDID 16 LSB bits contain the LTID (Local Thread Index).
    143  * - The TRDID 16 MSB bits contain the owner cluster CXY.
     155 * - The TRDID 16 MSB bits contain the CXY of cluster containing the thread.
    144156 * - The LTID is used to index the th_tbl[] array in the local process descriptor.
    145157 * This TRDID is computed by the process_register_thread() function, when the user
     
    155167        void              * fpu_context;     /*! used for dynamic FPU allocation          */
    156168
    157         uint32_t            trdid;           /*! thread index (in THTBL)                  */
     169        uint32_t            trdid;           /*! thread index (cxy.ltid)                  */
    158170        thread_type_t       type;            /*! thread type                              */
    159171        uint32_t            quantum;         /*! number of clock ticks given to thread    */
     
    162174        core_t            * core;            /*! pointer to the owner core                */
    163175        process_t         * process;         /*! pointer on local process descriptor      */
    164 
     176    xptr_t              parent;          /*! extended pointer on parent thread        */       
     177
     178    void              * exit_value;      /*! exit_value used in case of join          */
     179   
    165180        uint32_t            local_locks;         /*! number of local locks owned by thread    */
    166181    list_entry_t        locks_root;      /*! root of local locks list                 */
     182
     183    remote_spinlock_t * flags_lock;      /*! lock protecting the flags                */
    167184
    168185        uint32_t            remote_locks;        /*! number of local locks owned by thread    */
     
    182199
    183200        error_t             errno;           /*! errno value set by last system call      */
     201    uint32_t            utls;            /*! user thread local storage                */
    184202
    185203    bool_t              fork_user;       /*! user defined placement for next fork()   */
     
    231249/***************************************************************************************
    232250 * This function allocates memory for an user thread descriptor in the local cluster,
    233  * and initializes it from information contained in the "attr" argument.
    234  * It is used by the pthread_create system call, the CPU context is initialised from
    235  * scratch, and the "loadable" field is set.
    236  * The new thread is attached to the core specified in the "attr" argument.
    237  * It is registered in the local process descriptor for the process specified in "attr".
     251 * and initializes it from information contained in the arguments.
     252 * It is used by the "pthread_create" system call.
     253 * The CPU context is initialised from scratch, and the "loadable" field is set.
     254 * The new thread is attached to the core specified in the <attr> argument.
     255 * It is registered in the local process descriptor specified by the <pid> argument.
    238256 * The thread descriptor pointer is returned to allow the parent thread to register it
    239257 * in its children list.
    240  * The THREAD_BLOCKED_GLOBAL bit is set, and the thread must be activated to start.   
    241  ***************************************************************************************
    242  * @ new_thread   : address of buffer for new thread descriptor pointer. 
     258 * The THREAD_BLOCKED_GLOBAL bit is set => the thread must be activated to start.   
     259 ***************************************************************************************
     260 * @ pid          : process identifier.
     261 * @ start_func   : pointer on entry function.
     262 * @ start_args   : pointer on function argument (can be NULL).
    243263 * @ attr         : pointer on pthread attributes descriptor.
    244  * @ u_stack_base : actual user stack size.
    245  * @ u_stack_size : actual user stack base.
     264 * @ new_thread   : [out] address of buffer for new thread descriptor pointer. 
    246265 * @ returns 0 if success / returns ENOMEM if error.
    247266 **************************************************************************************/
    248 error_t thread_user_create( thread_t       ** new_thread,
     267error_t thread_user_create( pid_t             pid,
     268                            void            * start_func,
     269                            void            * start_arg,
    249270                            pthread_attr_t  * attr,
    250                             intptr_t          u_stack_base,
    251                             uint32_t          u_stack_size );
     271                            thread_t       ** new_thread );
    252272
    253273/***************************************************************************************
     
    261281 * The THREAD_BLOCKED_GLOBAL bit is set, and the thread must be activated to start.   
    262282 ***************************************************************************************
    263  * @ new_thread   : address of buffer for new thread descriptor pointer. 
    264283 * @ process      : local pointer on owner process descriptor.
    265  * @ u_stack_base : actual user stack size.
    266  * @ u_stack_size : actual user stack base.
     284 * @ new_thread   : [out] address of buffer for new thread descriptor pointer. 
    267285 * @ returns 0 if success / returns ENOMEM if error.
    268286 **************************************************************************************/
    269 error_t thread_user_fork( thread_t ** new_thread,
    270                           process_t * process,
    271                           intptr_t    u_stack_base,
    272                           uint32_t    u_stack_size );
     287error_t thread_user_fork( process_t * process,
     288                          thread_t ** new_thread );
    273289
    274290/***************************************************************************************
     
    343359 * This function removes an user thread from the parent thread global list
    344360 * of attached children threads.
    345  * It does take the lock, as this function can be called by the child thread.
    346  * In this case, it uses the extended pointer on the parent thread contained
    347  * in the pthread_attr_t embedded in the child thread descriptor.
    348361 ***************************************************************************************
    349362 * @ xp_parent : extended pointer on the parent thread descriptor.
     
    352365void thread_child_parent_unlink( xptr_t xp_parent,
    353366                                 xptr_t xp_child );
    354 
    355367
    356368/***************************************************************************************
     
    475487void thread_signals_handle( thread_t * thread );
    476488
     489/***************************************************************************************
     490 * This function returns the extended pointer on a thread descriptor identified
     491 * by its thread identifier, and process identifier.
     492 * It can be called by any thread running in any cluster.
     493 ***************************************************************************************
     494 * @ pid     : process identifier.
     495 * @ trdid   : thread identifier.
     496 * @ return the extended pointer if thread found / return XPTR_NULL if not found.
     497 **************************************************************************************/
     498xptr_t thread_get_xptr( pid_t    pid,
     499                        trdid_t  trdid );
    477500
    478501
  • trunk/kernel/kern/time.h

    r1 r23  
    11/*
    2  * time.h: thread time related management
     2 * time.h - Structure used by gettimeofday.
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * author    Alain Greiner (2016,2017)
    65 *
    7  * This file is part of ALMOS-kernel.
     6 * Copyright (c) UPMC Sorbonne Universites
    87 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     8 * This file is part of ALMOS-MKH.
     9 *
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1718 *
    1819 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2021 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2122 */
     
    2425#define _TIME_H_
    2526
    26 #include <types.h>
    27 #include <list.h>
    28 #include <device.h>
     27#include <hal_types.h>
    2928
    30 struct event_s;
    3129
    32 struct alarm_info_s
     30struct timeval
    3331{
    34         uint_t signature;
    35 
    36         /* Public members */
    37         struct event_s *event;
    38 
    39         /* Private members */
    40         uint_t tm_wakeup;
    41         struct list_entry list;
     32        uint32_t tv_sec;        /* secondes */
     33        uint32_t tv_usec;       /* microsecondes */
    4234};
    4335
    44 struct alarm_s
    45 {
    46         struct list_entry wait_queue;
    47 };
    48 
    49 
    50 struct timeb {
    51         time_t         time;
    52         unsigned short millitm;
    53         short          timezone;
    54         short          dstflag;
    55 };
    56 
    57 struct timeval {
    58         clock_t tv_sec;    /* secondes */
    59         clock_t tv_usec;   /* microsecondes */
    60 };
    61 
    62 struct timezone {
     36struct timezone
     37{
    6338        int tz_minuteswest;     /* minutes west of Greenwich */
    6439        int tz_dsttime;         /* type of DST correction */
    6540};
    6641
    67 
    68 struct tms
    69 {
    70        clock_t tms_utime;  /* user time */
    71        clock_t tms_stime;  /* system time */
    72        clock_t tms_cutime; /* user time of children */
    73        clock_t tms_cstime; /* system time of children */
    74 };
    75 
    76 
    77 error_t alarm_manager_init(struct alarm_s *alarm);
    78 error_t alarm_wait(struct alarm_info_s *info, uint_t msec);
    79 
    80 void alarm_clock(struct alarm_s *alarm, uint_t ticks_nr);
    81 
    82 int sys_clock (uint64_t *val);
    83 int sys_alarm (unsigned nb_sec);
    84 int sys_ftime (struct timeb *utime);
    85 int sys_times(struct tms *utms);
    86 int sys_gettimeofday(struct timeval *tv, struct timezone *tz);
    87 
    88 #if CONFIG_THREAD_TIME_STAT
    89 struct thread_s;
    90 inline void tm_sleep_compute(struct thread_s *thread);
    91 inline void tm_usr_compute(struct thread_s *thread);
    92 inline void tm_sys_compute(struct thread_s *thread);
    93 inline void tm_wait_compute(struct thread_s *thread);
    94 inline void tm_exit_compute(struct thread_s *thread);
    95 inline void tm_born_compute(struct thread_s *thread);
    96 inline void tm_create_compute(struct thread_s *thread);
    97 
    98 #else
    99 
    100 #define tm_sleep_compute(thread)
    101 #define tm_usr_compute(thread)
    102 #define tm_sys_compute(thread)
    103 #define tm_wait_compute(thread)
    104 #define tm_exit_compute(thread)
    105 #define tm_born_compute(thread)
    106 #define tm_create_compute(thread)
    107 
    108 #endif  /* CONFIG_SCHED_STAT */
    109 
    11042#endif  /* _TIME_H_ */
  • trunk/kernel/libk/bits.c

    r11 r23  
    2525#include <hal_types.h>
    2626#include <bits.h>
     27
     28////////////////////////////////////
     29void bitmap_init( bitmap_t * bitmap,
     30                  uint32_t   len )
     31{
     32    uint32_t word;
     33    uint32_t nwords = BITMAP_SIZE( len );
     34    for( word = 0 ; word < nwords ; word++ )
     35    {
     36        bitmap[word] = 0;
     37    }
     38}  // end bitmap_init()
    2739
    2840//////////////////////////////////////////
  • trunk/kernel/libk/bits.h

    r14 r23  
    7878
    7979/**********************************************************************************************
    80  * This macro returns the number of 32 bits words required to register size entries.
     80 * This macro returns the number of 32 bits words required to register <size> entries.
    8181 *********************************************************************************************/
    8282
    8383#define BITMAP_SIZE(size) ( ((size) & 31) ? (((size)>>5) + 1) : ((size)>>5) )
    84  
    85 /**********************************************************************************************
    86  * This macro declare a bitmap data structure. It is actually an array of uint32_t.
    87  * size is the total number of entries in the bitmap.
    88  *********************************************************************************************/
    89 
    90 #define BITMAP( name , size )     uint32_t name[BITMAP_SIZE(size)]
    9184
    9285typedef uint32_t    bitmap_t;
    9386
    94 /**********************************************************************************************
     87/*********************************************************************************************
     88 * This function reset all bits in a bitmap. (array ot 32 bits words).
     89 *********************************************************************************************
     90 * @ bitmap  : pointer on first word in the bitmap.
     91 * @ len     : number of bits to reset.
     92 ********************************************************************************************/
     93void bitmap_init( bitmap_t * bitmap,
     94                  uint32_t   len );
     95
     96/*********************************************************************************************
    9597 * This function set a specific bit in a bitmap.
    96  **********************************************************************************************
     98 *********************************************************************************************
    9799 * @ bitmap  : pointer on the bitmap
    98100 * @ index   : bit index in the bitmap
    99  *********************************************************************************************/
     101 ********************************************************************************************/
    100102extern inline void bitmap_set( bitmap_t * bitmap,
    101103                               uint32_t   index );
    102104
    103 /**********************************************************************************************
     105/*********************************************************************************************
    104106 * This function clear a specific bit in a bitmap.
    105  **********************************************************************************************
     107 *********************************************************************************************
    106108 * @ bitmap  : pointer on the bitmap
    107109 * @ index   : bit index in the bitmap
    108  *********************************************************************************************/
     110 ********************************************************************************************/
    109111extern inline void bitmap_clear( bitmap_t * bitmap,
    110112                                 uint32_t   index );
    111113
    112 /**********************************************************************************************
     114/*********************************************************************************************
    113115 * This function returns a specific bit in a bitmap.
    114  **********************************************************************************************
     116 *********************************************************************************************
    115117 * @ bitmap  : pointer on the bitmap
    116118 * @ index   : bit index in the bitmap
    117  * @ returns tru if bitmap[index] is set
    118  *********************************************************************************************/
     119 * @ returns true if bitmap[index] is set
     120 ********************************************************************************************/
    119121extern inline bool_t bitmap_state( bitmap_t * bitmap,
    120122                                   uint32_t   index );
    121123
    122 /**********************************************************************************************
     124/*********************************************************************************************
    123125 * This function set a range of bits in a bitmap : [index ... (index + len)[
    124  **********************************************************************************************
     126 *********************************************************************************************
    125127 * @ bitmap  : pointer on the bitmap
    126128 * @ index   : first bit index in the bitmap
    127129 * @ len     : number of bits to set
    128  *********************************************************************************************/
     130 ********************************************************************************************/
    129131extern void bitmap_set_range( bitmap_t * bitmap,
    130132                              uint32_t   index,
    131133                              uint32_t   len );
    132134
    133 /**********************************************************************************************
     135/*********************************************************************************************
    134136 * This function reset a range of bits in a bitmap : [index ... (index + len)[
    135  **********************************************************************************************
     137 *********************************************************************************************
    136138 * @ bitmap  : pointer on the bitmap
    137139 * @ index   : first bit index in the bitmap
    138140 * @ len     : number of bits to clear
    139  *********************************************************************************************/
     141 ********************************************************************************************/
    140142extern void bitmap_clear_range( bitmap_t * bitmap,
    141143                                uint32_t   index,
    142144                                uint32_t   len );
    143145
    144 /**********************************************************************************************
     146/*********************************************************************************************
    145147 * This function returns the index of first bit set in a bitmap, starting from index.
    146  **********************************************************************************************
     148 *********************************************************************************************
    147149 * @ bitmap  : pointer on the bitmap
    148150 * @ index   : first bit to analyse in the bitmap
    149151 * @ size    : number of bits to analyse in bitmap
    150152 * @ returns index if found / returns 0xFFFFFFFF if bit not found
    151  *********************************************************************************************/
     153 ********************************************************************************************/
    152154extern uint32_t bitmap_ffs2( bitmap_t * bitmap,
    153155                             uint32_t   index,
    154156                             uint32_t   size );
    155157
    156 /**********************************************************************************************
     158/*********************************************************************************************
    157159 * This function returns the index of first bit cleared in a bitmap, starting from index.
    158  **********************************************************************************************
     160 *********************************************************************************************
    159161 * @ bitmap  : pointer on the bitmap
    160162 * @ index   : first bit to analyse in the bitmap
    161163 * @ size    : number of bits to analyse in bitmap
    162164 * @ returns index if found / returns 0xFFFFFFFF if bit not found
    163  *********************************************************************************************/
     165 ********************************************************************************************/
    164166extern uint32_t bitmap_ffc2( bitmap_t * bitmap,
    165167                             uint32_t   index,
    166168                             uint32_t   size );
    167169
    168 /**********************************************************************************************
     170/*********************************************************************************************
    169171 * This function returns the index of first bit set in a bitmap, starting from bit 0.
    170  **********************************************************************************************
     172 *********************************************************************************************
    171173 * @ bitmap  : pointer on the bitmap
    172174 * @ size    : number of bits to analyse in bitmap
    173175 * @ returns index if found / returns 0xFFFFFFFF if bit not found
    174  *********************************************************************************************/
     176 ********************************************************************************************/
    175177extern uint32_t bitmap_ffs( bitmap_t * bitmap,
    176178                            uint32_t   size );
    177179
    178 /**********************************************************************************************
     180/*********************************************************************************************
    179181 * This function returns the index of first bit cleared in a bitmap, starting from bit 0.
    180  **********************************************************************************************
     182 *********************************************************************************************
    181183 * @ bitmap  : pointer on the bitmap
    182184 * @ size    : number of bits to alalyse in bitmap
    183185 * @ returns index if found / returns 0xFFFFFFFF if bit not found
    184  *********************************************************************************************/
     186 ********************************************************************************************/
    185187extern uint32_t bitmap_ffc( bitmap_t * bitmap,
    186188                            uint32_t   size );
    187189
    188 /**********************************************************************************************
     190/*********************************************************************************************
    189191 * This function returns the number of bits to code a non-zero unsigned integer value.
    190  **********************************************************************************************
     192 *********************************************************************************************
    191193 * @ val   : value to analyse
    192194 * @ returns number of bits
    193  *********************************************************************************************/
     195 ********************************************************************************************/
    194196static inline uint32_t bits_nr( uint32_t val )
    195197{
     
    202204}
    203205
    204 /**********************************************************************************************
     206/*********************************************************************************************
    205207 * This function takes an unsigned integer value as input argument, and returns another
    206208 * unsigned integer, that is the (base 2) logarithm of the smallest power of 2 contained
    207209 * in the input value.
    208  **********************************************************************************************
     210 *********************************************************************************************
    209211 * @ val   : value to analyse
    210212 * @ returns logarithm value
    211  *********************************************************************************************/
     213 ********************************************************************************************/
    212214static inline uint32_t bits_log2( uint32_t val )
    213215{
  • trunk/kernel/libk/elf.c

    r14 r23  
    3131#include <vfs.h>
    3232#include <elf.h>
     33#include <syscalls.h>
    3334
    3435
     
    8586
    8687    // load .elf header
    87         count = vfs_read( file_xp , buffer , size );
     88        count = vfs_move( true ,
     89                      file_xp,
     90                      buffer,
     91                      size );
    8892
    8993        if( count != size )
     
    163167
    164168        // set seek on segment base in file
    165                 error = vfs_lseek( file_xp , offset , VFS_SEEK_SET , NULL );
     169                error = vfs_lseek( file_xp,
     170                           offset,
     171                           SEEK_SET,
     172                           NULL );
    166173
    167174                if( error )
     
    210217                          process_t * process)
    211218{
     219    char         path_copy[CONFIG_VFS_MAX_PATH_LENGTH];
    212220        kmem_req_t   req;              // kmem request for program header
    213     char         path_copy[256];   // local copy of pathname
    214221        uint32_t     length;           // actual path length
    215222        Elf32_Ehdr   header;           // local buffer for .elf header
     
    217224    uint32_t     segs_size;        // size of buffer for segment descriptors array 
    218225        xptr_t       file_xp;          // extended pointer on created file descriptor
     226    uint32_t     file_id;          // file descriptor index (unused)
    219227    uint32_t     count;            // bytes counter
    220228        error_t      error;
     
    223231        length = hal_strlen_from_uspace( pathname );
    224232
    225     if( length > 255 )
     233    if( length >= CONFIG_VFS_MAX_PATH_LENGTH )
    226234    {
    227235        printk("\n[ERROR] in %s : pathname length too long\n", __FUNCTION__ );
     
    234242    // open file
    235243    file_xp = XPTR_NULL;  // avoid GCC warning
     244    file_id = -1;
    236245
    237246        error = vfs_open( process->vfs_cwd_xp,
    238247                      path_copy,
    239                       VFS_O_RDONLY,
    240                       &file_xp );
     248                      O_RDONLY,
     249                      0,
     250                      &file_xp,
     251                      &file_id );
    241252        if( error )
    242253        {
     
    252263        if( error )
    253264    {
    254         vfs_close( file_xp , &count );
     265        vfs_close( file_xp , file_id );
    255266        return -1;
    256267    }
     
    261272        {
    262273                printk("\n[ERROR] in %s : no segments found\n", __FUNCTION__ );
    263         vfs_close( file_xp , &count );
     274        vfs_close( file_xp , file_id );
    264275                return -1;
    265276        }
     
    277288    {
    278289                printk("\n[ERROR] in %s : no memory for segment descriptors\n", __FUNCTION__ );
    279         vfs_close( file_xp , &count );
     290        vfs_close( file_xp , file_id );
    280291        return -1;
    281292    }
    282293
    283294    // set seek pointer in file descriptor to access segment descriptors array
    284         error = vfs_lseek( file_xp , header.e_phoff, VFS_SEEK_SET , NULL );
     295        error = vfs_lseek( file_xp , header.e_phoff, SEEK_SET , NULL );
    285296
    286297        if( error )
    287298        {
    288299                printk("\n[ERROR] in %s : cannot seek for descriptors array\n", __FUNCTION__ );
    289         vfs_close( file_xp , &count );
     300        vfs_close( file_xp , file_id );
    290301            req.ptr = segs_base;
    291302            kmem_free( &req );
     
    294305
    295306    // load seg descriptors array to local buffer
    296         count = vfs_read( file_xp,
     307        count = vfs_move( true,
     308                      file_xp,
    297309                      segs_base,
    298310                      segs_size );
     
    301313        {
    302314                printk("\n[ERROR] in %s : cannot read segments descriptors\n", __FUNCTION__ );
    303         vfs_close( file_xp , &count );
     315        vfs_close( file_xp , file_id );
    304316            req.ptr = segs_base;
    305317            kmem_free( &req );
     
    316328        if( error )
    317329    {
    318         vfs_close( file_xp , &count );
     330        vfs_close( file_xp , file_id );
    319331            req.ptr = segs_base;
    320332            kmem_free( &req );
  • trunk/kernel/libk/htab.c

    r1 r23  
    22 * htable.c - Generic, embedded hash table implementation.
    33 *
    4  * Author     Ghassan Almalles (2008,2009,2010,2011,2012)
    5  *            Mohamed Lamine Karaoui (2015)
    6  *            Alain Greiner (2016)
     4 * Author      Alain Greiner (2016,2017)
    75 *
    86 * Copyright (c) UPMC Sorbonne Universites
     
    108 * This file is part of ALMOS-MKH.
    119 *
    12  * ALMOS-MKH.is free software; you can redistribute it and/or modify it
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1311 * under the terms of the GNU General Public License as published by
    1412 * the Free Software Foundation; version 2.0 of the License.
    1513 *
    16  * ALMOS-MKH.is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1715 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1816 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    2018 *
    2119 * You should have received a copy of the GNU General Public License
    22  * along with ALMOS-MKH.; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2321 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2422 */
    2523
    26 #include <htable.h>
    27 #include <kmem.h>
    28 #include <ppm.h>
    29 
    30 ///////////////////////////////////////////////
    31 error_t ht_header_init( ht_header_t  * header,
    32                         ht_hash_t    * hash,
    33                         ht_compare_t * compare )
     24#include <kernel_config.h>
     25#include <hal_types.h>
     26#include <hal_special.h>
     27#include <htab.h>
     28#include <rwlock.h>
     29#include <list.h>
     30#include <printk.h>
     31#include <vfs.h>
     32
     33///////////////////////////////////////////////////////////////////////////////////////////
     34//    Item type specific (static) functions (two functions for each item type).
     35// Example below if for <vhs_inode_t>, where the identifier is the inum field.
     36///////////////////////////////////////////////////////////////////////////////////////////
     37
     38///////////////////////////////////////////////////////////////////////////////////////////
     39// These static functions compute the hash index from the key.
     40///////////////////////////////////////////////////////////////////////////////////////////
     41// @ key      : local pointer on key.
     42// @ return the index value, from 0 to (HASHTAB_SIZE - 1)
     43///////////////////////////////////////////////////////////////////////////////////////////
     44
     45static uint32_t htab_inode_index( void * key )
     46{
     47        uint32_t * inum = key;
     48        return (((*inum) >> 16) ^ ((*inum) & 0xFFFF)) % HASHTAB_SIZE;
     49}
     50
     51///////////////////////////////////////////////////////////////////////////////////////
     52// These static functions are used by htab_lookup(), htab_insert(), and htab_remove().
     53// They scan one sub-list identified by  <index> to find an item  identified by <key>.
     54// The sub-list is not modified, but the lock must have been taken by the caller.
     55///////////////////////////////////////////////////////////////////////////////////////
     56// @ htab    : pointer on hash table.
     57// @ index   : index of sub-list to be scanned.
     58// @ key     : pointer on item identifier.
     59// @ return pointer on item if found / return NULL if not found.
     60///////////////////////////////////////////////////////////////////////////////////////
     61
     62static void * htab_inode_scan( htab_t  * htab,
     63                               uint32_t  index,
     64                               void    * key )
     65{
     66    list_entry_t * list_entry;   // pointer on list_entry_t (iterator)
     67    vfs_inode_t  * inode;        // pointer on item
     68   
     69        LIST_FOREACH( &htab->roots[index] , list_entry )
     70        {
     71        inode = (vfs_inode_t *)LIST_ELEMENT( list_entry , vfs_inode_t , list );
     72        if( inode->inum == *(uint32_t *)key ) return inode;
     73    }
     74
     75    // no matching item found
     76        return NULL;
     77}
     78
     79////////////////////////////////////////////////////////////////////////////////////////
     80//         Generic access functions
     81////////////////////////////////////////////////////////////////////////////////////////
     82
     83////////////////////////////////////////
     84void htab_init( htab_t           * htab,
     85                htab_item_type_t   type )
    3486{
    3587        uint32_t     i;
    36         kmem_req_t   req;
    37         page_t     * page;
    38 
    39         req.type  = KMEM_PAGE;
    40         req.size  = 0;
    41         req.flags = AF_ZERO;
    42         page      = kmem_alloc( &req );
    43        
    44         if( page == NULL ) return ENOMEM;
    45 
    46         header->nb_buckets = CONFIG_PPM_PAGE_SIZE/sizeof( list_entry_t );
    47         header->buckets    = ppm_page2base( page );
    48         header->hash       = hash;
    49         header->compare    = compare;
    50 
    51         for( i=0 ; i < header->nb_buckets ; i++ )
    52         {
    53                 list_root_init( &header->buckets[i] );
    54         }
    55 
    56         return 0;
    57 }
    58 
    59 ////////////////////////////////////////
    60 error_t ht_node_init( ht_node_t * node )
    61 {
    62         node->index = (uint32_t) -1;
    63         list_entry_init( &node->list );
    64 
    65         return 0;
    66 }
    67 
    68 /////////////////////////////////////////////////
    69 static ht_node_t * __hfind( ht_header_t * header,
    70                             uint32_t      index,
    71                             void        * key)
    72 {
    73         ht_node_t    * node;
    74         list_entry_t * root,
    75     list_entry_t * iter;
    76 
    77         root = &header->buckets[index % header->nb_buckets];
    78 
    79         LIST_FOREACH( root , iter )
    80         {
    81                 node = LIST_ELEMENT( iter , ht_node_t , list );
    82                 if( node->index == index )
    83                 {
    84                         if( header->compare( node , key ) ) return node;
    85                 }
    86         }
    87 
    88         return NULL;
    89 }
    90 
    91 //////////////////////////////////////////
    92 ht_node_t * ht_find( ht_header_t * header,
    93                      void        * key )
    94 {
    95         uint32_t index = header->hash( key );
    96 
    97         return __ht_find( header , index , key );
    98 }
    99 
    100 ////////////////////////////////////////
    101 error_t ht_insert( ht_header_t * header,
    102                    ht_node_t   * node,
    103                    void        * key )
    104 {
    105         uint32_t index = header->hash( key );
    106 
    107         ht_node_t * node = __ht_find( header , index , key );
    108 
    109         if( node != NULL ) return EINVAL;
    110 
    111         list_entry_t * root = &header->buckets[index % header->nb_buckets];
    112 
    113         list_add_first( root , &node->list);
    114 
    115         node->index = index;
    116 
    117         return 0;
    118 }
    119 
    120 ////////////////////////////////////////
    121 error_t ht_remove( ht_header_t * header,
    122                    void        * key )
    123 {
    124         uint32_t index = header->hash( key );
    125 
    126         ht_node_t * node = __ht_find( header , index , key );
    127 
    128         if( node == NULL ) return EINVAL;
    129 
    130         list_unlink( &node->list );
    131 
    132         return 0;
    133 }
    134 
     88
     89    // initialize readlock
     90    rwlock_init( &htab->lock );
     91
     92    htab->items = 0;
     93
     94    if( type == HTAB_INODE_TYPE )
     95    {
     96        htab->scan    = &htab_inode_scan;
     97        htab->index   = &htab_inode_index;
     98    }
     99    else
     100    {
     101        printk("\n[PANIC] in %s : undefined item type\n", __FUNCTION__ );
     102        hal_core_sleep();
     103    }
     104
     105    // initialize partial lists
     106    for( i = 0 ; i < HASHTAB_SIZE ; i++ )
     107    {
     108        list_root_init( &htab->roots[i] );
     109    }
     110}
     111
     112/////////////////////////////////////////
     113error_t htab_insert( htab_t       * htab,
     114                     void         * key,
     115                     list_entry_t * list_entry )
     116{
     117    // compute index from key
     118    uint32_t index = htab->index( key );
     119
     120    // take the lock in write mode
     121    rwlock_wr_lock( &htab->lock );
     122
     123    // scan sub-list to check if item exist
     124    void * item = htab->scan( htab , index , key );
     125
     126    if( item != NULL ) // item exist => return error
     127    {
     128        // release lock
     129        rwlock_wr_unlock( &htab->lock );
     130
     131        return -1;
     132    }
     133    else               // item doesn't exist => register
     134    {
     135        // register item in hash table
     136        list_add_last( &htab->roots[index] , list_entry );
     137
     138        // update items number
     139        htab->items++;
     140
     141        // release lock
     142        rwlock_wr_unlock( &htab->lock );
     143
     144        return 0;
     145    }
     146}
     147
     148/////////////////////////////////////////
     149error_t htab_remove( htab_t       * htab,
     150                     void         * key,
     151                     list_entry_t * list_entry )
     152{
     153    // compute index from key
     154    uint32_t index = htab->index( key );
     155
     156    // take the lock in write mode
     157    rwlock_wr_lock( &htab->lock );
     158
     159    // scan sub-list to chek if item exist
     160    void * item = htab->scan( htab , index , key );
     161
     162    if( item == NULL ) // item doesn't exist
     163    {
     164        // release lock
     165        rwlock_wr_unlock( &htab->lock );
     166
     167        return -1;
     168    }
     169    else               // item exist => remove it
     170    {
     171        // remove item from hash table
     172        list_unlink( list_entry );
     173
     174        // update items number
     175        htab->items--;
     176
     177        // release lock
     178        rwlock_wr_unlock( &htab->lock );
     179
     180        return 0;
     181    }
     182}
     183
     184//////////////////////////////////
     185void * htab_lookup( htab_t * htab,
     186                    void   * key )
     187{
     188    // compute index from key
     189    uint32_t index = htab->index( key );
     190
     191    // take the lock in read mode
     192    rwlock_rd_lock( &htab->lock );
     193
     194    // scan sub-list
     195    void * item = htab->scan( htab , index , key );
     196
     197    // release lock
     198    rwlock_rd_unlock( &htab->lock );
     199
     200        return item;
     201}
     202
     203
     204
  • trunk/kernel/libk/htab.h

    r1 r23  
    22 * htab.h - Generic embedded hash table definition.
    33 *
    4  * Author     Ghassan Almalles (2008,2009,2010,2011,2012)
    5  *            Mohamed Lamine Karaoui (2015)
    6  *            Alain Greiner (2016)
     4 * Authors  Alain Greiner (2016,2017)
    75 *
    86 * Copyright (c) UPMC Sorbonne Universites
     
    2927
    3028#include <hal_types.h>
     29#include <rwlock.h>
    3130#include <list.h>
    3231
     32/////////////////////////////////////////////////////////////////////////////////////////
     33// This file define a generic, embedded, hash table.
     34//
     35// It can only be accessed by threads running in the local cluster.
     36// It is generic as it can be used to register various types of items.
     37// The main goal is to provide fast retrieval for a large number of items of same type.
     38// For this purpose the set of all registered items is split in several subsets.
     39// Each subset is organised as a double linked lists.
     40// - an item is uniquely identified by a <key>, that can be a single uint32_t,
     41//   a character string, or a more complex structure.
     42// - From the pointer on <key>, we use an item type specific htab_index() function,
     43//   to compute an <index> value, defining a subset of registered items.
     44// - As several items can have the same <index>, we use the item type specific defined
     45//   htab_scan() function for a final associative search on the subset.
     46// - Each registered item is a structure, that must contain an embedded list_entry_t,
     47//   that is part of a rooted double linked list.
     48//
     49// Implementation Note: for each supported item type ***, you must define the two
     50//                      htab_***_index() and htab_***_scan() functions, and
     51//                      update the htab_init() function.
     52/////////////////////////////////////////////////////////////////////////////////////////
     53
     54#define HASHTAB_SIZE    64   // number of subsets
     55
    3356/****************************************************************************************
    34  * This file define a generic, embedded, hash table.
    35  * The main goal is to provide fast retrieval for a large number of items of same type
    36  * in a given cluster. For this purpose the set of all registered items is split
    37  * in several subsets. Each subset is organised as a double linked lists.
    38  * - an item is uniquely identified by a <key>, that can be a single uint32_t,
    39  *   a character string, or a more complex structure.
    40  * - From the pointer on the <key>, the hash table uses an user defined ht_hash()
    41  *   function, to compute an <index> value, defining a subset of registered
    42  *   items, to restrict the associative search.
    43  * - As several items can have the same <index>, the hash table uses the user defined
    44  *   ht_compare() function for a final associative search on the subset.
    45  * - Each registered item is a structure, that must contain an embedded ht_node_t,
    46  *   This ht_node_t is part of a rooted double linked list, and contains the <index>.
    47  * - Finally, the hash table returns a pointer on the embedded ht_node_t, and the
    48  *   pointer on the searched item can be obtained by a simple offset.
     57 * These typedef define the two item type specific function prototypes.
    4958 ***************************************************************************************/
    5059
     60struct htab_s;
     61
     62typedef void *     htab_scan_t( struct htab_s * htab , uint32_t index , void * key );
     63
     64typedef uint32_t   htab_index_t( void * key );
     65
    5166/****************************************************************************************
    52  * This define the generic, user defined, function types.
     67 * This define the supported item types.
    5368 ***************************************************************************************/
    5469
    55 struct ht_node_s;
    56 
    57 typedef bool_t     ht_compare_t( struct ht_node_s * node , void * key );
    58 typedef uint32_t   ht_hash_t( void * key );
     70typedef enum
     71{
     72    HTAB_INODE_TYPE = 1,                     /*! item is a vfs_inode_t                 */
     73}
     74htab_item_type_t;
    5975
    6076/****************************************************************************************
    61  * This structure defines the hash table header.
     77 * This structure defines the the root of a local hash table.
    6278 ***************************************************************************************/
    6379
    64 typedef struct ht_header_s
     80typedef struct htab_s
    6581{
    66         uint32_t        nb_buckets;   /*! number of subsets (one linked list per subset)   */
    67         ht_hash_t     * hash;         /*! user defined hash function                       */
    68         ht_compare_t  * compare;      /*! user defined compare function                    */
    69         list_entry_t  * buckets;      /*! array of root of partial lists of ht_node_t      */
     82        list_entry_t      roots[HASHTAB_SIZE];  /*! array of roots of partial lists        */
     83        htab_index_t    * index;                /*! item type  specific function           */
     84        htab_scan_t     * scan;                 /*! item type specific function            */
     85    uint32_t          items;                /*! number of registered items             */
     86    rwlock_t          lock;                 /*! lock protecting hash table accesses    */
    7087}
    71 ht_header_t;
     88htab_t;
    7289
    7390/****************************************************************************************
    74  * This structure defines one hash table node.
     91 * This function initialises an empty hash table (zero registered item).
     92 ****************************************************************************************
     93 * @ htab       : pointer on hash table.
     94 * @ type       : item type.
    7595 ***************************************************************************************/
    76 
    77 typedef struct ht_node_s
    78 {
    79         uint32_t     index;           /*! integer value computed from the key              */
    80         list_entry_t list;                /*! member of list of all nodes in same bucket       */
    81 }
    82 ht_node_t;
     96void htab_init( htab_t           * htab,
     97                htab_item_type_t   type );
    8398
    8499/****************************************************************************************
    85  * This function initialises one hash table node.
     100 * This function register a new item in the hash table.
    86101 ****************************************************************************************
    87 ccccc
     102 * @ htab       : pointer on the hash table.
     103 * @ key        : pointer on the item identifier.
     104 * @ list_entry : pointer on list_entry_t embedded in item to be registered.
     105 * @ return 0 if success / return EINVAL if item already registered.
    88106 ***************************************************************************************/
    89 void ht_node_init( ht_node_t * node );
     107error_t htab_insert( htab_t       * htab,
     108                     void         * key,
     109                     list_entry_t * list_entry );
    90110
    91111/****************************************************************************************
    92  * This function allocates memory for the buckets array, and initializes the header.
    93  * The number of buckets (number of subsets) is PAGE_SIZE / sizeof(list_entry_t)
     112 * This function remove an item from the hash table.
    94113 ****************************************************************************************
    95  * @ header     : pointer on the hash table header.
    96  * @ ht_hash    : pointer on the user defined hash function.
    97  * @ ht_compare : pointer on the user defined compare function.
    98  * @ return 0 if success / return ENOMEM if error.
     114 * @ header     : pointer on the hash table.
     115 * @ key        : pointer on the item identifier.
     116 * @ list_entry : pointer on list_entry_t embedded in item to be removed.
     117 * @ return 0 if success / return EINVAL if item not found.
    99118 ***************************************************************************************/
    100 error_t ht_header_init( ht_header_t  * header,
    101                         ht_hash_t    * ht_hash,
    102                         ht_compare_t * ht_compare );
    103 
    104 /****************************************************************************************
    105  * This function register a new node in the hash table.
    106  ****************************************************************************************
    107  * @ header     : pointer on the hash table header.
    108  * @ node       : pointer on the node to be registered (embedded in item).
    109  * @ key        : pointer on the item identifier.
    110  * @ return 0 if success / return EINVAL if node already registered...
    111  ***************************************************************************************/
    112 error_t ht_insert( ht_header_t * header,
    113                    ht_node_t   * node,
    114                    void        * key );
     119error_t htab_remove( htab_t       * htab,
     120                     void         * key,
     121                     list_entry_t * list_entry );
    115122
    116123/****************************************************************************************
     
    118125 * identified by its key.
    119126 ****************************************************************************************
    120  * @ header     : pointer on the hash table header.
    121  * @ key        : pointer on the item identifier.
    122  * @ return pointer on node if found / return NULL if not found.
     127 * @ htab      : pointer on the hash table.
     128 * @ key       : pointer on the item identifier.
     129 * @ return pointer on item if found / return NULL if not found.
    123130 ***************************************************************************************/
    124 ht_node_t * ht_find( ht_header_t * header,
    125                      void        * key);
     131void * htab_lookup( htab_t * htab,
     132                    void   * key);
    126133
    127 /****************************************************************************************
    128  * This function remove an item from the hash table.
    129  ****************************************************************************************
    130  * @ header     : pointer on the hash table header.
    131  * @ key        : pointer on the item identifier.
    132  * @ return 0 if success / return EINVAL if not found.
    133  ***************************************************************************************/
    134 error_t ht_remove( ht_header_t * header,
    135                    void        * key );
    136134
    137 #endif /* _HTABLE_H_ */
     135#endif /* _HTAB_H_ */
  • trunk/kernel/libk/remote_barrier.c

    r14 r23  
    11/*
    2  * remote_barrier.c - distributed kernel barrier implementaion
     2 * remote_barrier.c - Access a POSIX barrier.
    33 *
    4  * Author   Alain Greiner (2016)
     4 * Author   Alain Greiner (2016,2017)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    2424#include <hal_types.h>
    2525#include <hal_remote.h>
     26#include <hal_irqmask.h>
     27#include <remote_spinlock.h>
     28#include <thread.h>
     29#include <kmem.h>
     30#include <printk.h>
     31#include <process.h>
     32#include <vmm.h>
    2633#include <remote_barrier.h>
    2734
    28 /////////////////////////////////////////
    29 inline void remote_barrier( xptr_t    xp,
     35/////////////////////////////////////////////////
     36inline void remote_barrier( xptr_t    barrier_xp,
    3037                            uint32_t  count )
    3138{
    3239    uint32_t  expected;
    3340
    34     remote_barrier_t * ptr = (remote_barrier_t *)GET_PTR( xp );
    35     cxy_t              cxy = GET_CXY( xp );
     41    remote_barrier_t * ptr = (remote_barrier_t *)GET_PTR( barrier_xp );
     42    cxy_t              cxy = GET_CXY( barrier_xp );
    3643
    3744    // get barrier sense value
     
    5764}
    5865
    59 
     66///////////////////////////////////////////////////
     67xptr_t remote_barrier_from_ident( intptr_t  ident )
     68{
     69    // get pointer on local process_descriptor
     70    process_t * process = CURRENT_THREAD->process;
     71
     72    // get extended pointer on reference process
     73    xptr_t      ref_xp = process->ref_xp;
     74
     75    // get cluster and local pointer on reference process
     76    cxy_t          ref_cxy = GET_CXY( ref_xp );
     77    process_t    * ref_ptr = (process_t *)GET_PTR( ref_xp );
     78
     79    // get extended pointer on root of barriers list
     80    xptr_t root_xp = XPTR( ref_cxy , &ref_ptr->barrier_root );
     81   
     82    // scan reference process barriers list
     83    xptr_t             iter_xp;
     84    xptr_t             barrier_xp;
     85    cxy_t              barrier_cxy;
     86    remote_barrier_t * barrier_ptr;
     87    intptr_t           current;
     88    bool_t             found = false;
     89           
     90    XLIST_FOREACH( root_xp , iter_xp )
     91    {
     92        barrier_xp  = XLIST_ELEMENT( iter_xp , remote_barrier_t , list );
     93        barrier_cxy = GET_CXY( barrier_xp );
     94        barrier_ptr = (remote_barrier_t *)GET_PTR( barrier_xp );
     95        current     = (intptr_t)hal_remote_lpt( XPTR( barrier_cxy , &barrier_ptr->ident ) );   
     96        if( ident == current )
     97        {
     98            found = true;
     99            break;
     100        }
     101    }
     102
     103    if( found == false )  return XPTR_NULL;
     104    else                  return barrier_xp;
     105
     106}  // end remote_barrier_from_ident()
     107
     108//////////////////////////////////////////////
     109error_t remote_barrier_create( intptr_t ident,
     110                               uint32_t count )
     111{
     112    xptr_t             barrier_xp;
     113    remote_barrier_t * barrier_ptr;
     114
     115    // get pointer on local process descriptor
     116    process_t * process = CURRENT_THREAD->process;
     117
     118    // get extended pointer on reference process
     119    xptr_t      ref_xp = process->ref_xp;
     120
     121    // get reference process cluster and local pointer
     122    cxy_t       ref_cxy = GET_CXY( ref_xp );
     123    process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
     124
     125    // allocate memory for barrier descriptor
     126    if( ref_cxy == local_cxy )                  // local cluster is the reference
     127    {
     128        kmem_req_t req;   
     129        req.type      = KMEM_BARRIER;
     130        req.flags     = AF_ZERO;
     131        barrier_ptr   = kmem_alloc( &req );
     132        barrier_xp    = XPTR( local_cxy , barrier_ptr );
     133    }
     134    else                                       // reference is remote
     135    {
     136        rpc_kcm_alloc_client( ref_cxy , KMEM_BARRIER , &barrier_xp );
     137        barrier_ptr = (remote_barrier_t *)GET_PTR( barrier_xp );
     138    }
     139
     140    if( barrier_ptr == NULL ) return ENOMEM;
     141
     142    // initialise barrier
     143    hal_remote_sw ( XPTR( ref_cxy , &barrier_ptr->nb_threads ) , count );
     144    hal_remote_sw ( XPTR( ref_cxy , &barrier_ptr->current    ) , 0 );
     145    hal_remote_sw ( XPTR( ref_cxy , &barrier_ptr->sense      ) , 0 );
     146    hal_remote_spt( XPTR( ref_cxy , &barrier_ptr->ident      ) , (void*)ident );
     147
     148    xlist_entry_init( XPTR( ref_cxy , &barrier_ptr->list ) );
     149
     150    // register  barrier in reference process xlist
     151    xptr_t root_xp  = XPTR( ref_cxy , &ref_ptr->barrier_root );
     152    xptr_t entry_xp = XPTR( ref_cxy , &barrier_ptr->list );
     153
     154    remote_spinlock_lock( XPTR( ref_cxy , &ref_ptr->sync_lock ) );
     155    xlist_add_first( root_xp , entry_xp );
     156    remote_spinlock_unlock( XPTR( ref_cxy , &ref_ptr->sync_lock ) );
     157
     158    return 0;
     159
     160}  // end remote_barrier_create()
     161
     162////////////////////////////////////////////////
     163void remote_barrier_destroy( xptr_t barrier_xp )
     164{
     165    // get pointer on local process descriptor
     166    process_t * process = CURRENT_THREAD->process;
     167
     168    // get extended pointer on reference process
     169    xptr_t      ref_xp = process->ref_xp;
     170
     171    // get reference process cluster and local pointer
     172    cxy_t       ref_cxy = GET_CXY( ref_xp );
     173    process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
     174
     175    // get barrier cluster and local pointer
     176    cxy_t              barrier_cxy = GET_CXY( barrier_xp );
     177    remote_barrier_t * barrier_ptr = (remote_barrier_t *)GET_PTR( barrier_xp );
     178
     179    // remove barrier from reference process xlist
     180    remote_spinlock_lock( XPTR( ref_cxy , &ref_ptr->sync_lock ) );
     181    xlist_unlink( XPTR( barrier_cxy , &barrier_ptr->list ) );
     182    remote_spinlock_unlock( XPTR( ref_cxy , &ref_ptr->sync_lock ) );
     183
     184    // release memory allocated for barrier descriptor
     185    if( barrier_cxy == local_cxy )                        // reference is local
     186    {
     187        kmem_req_t  req;
     188        req.type = KMEM_BARRIER;
     189        req.ptr  = barrier_ptr;
     190        kmem_free( &req );
     191    }
     192    else                                                  // reference is remote
     193    {
     194        rpc_kcm_free_client( barrier_cxy , barrier_ptr , KMEM_BARRIER );
     195    }
     196
     197}  // end remote_barrier_destroy()
     198
     199/////////////////////////////////////////////
     200void remote_barrier_wait( xptr_t barrier_xp )
     201{
     202    uint32_t  expected;
     203    uint32_t  current;
     204    uint32_t  count;
     205    uint32_t  sense;
     206    uint32_t  irq_state;
     207    xptr_t    root_xp;
     208
     209    // get cluster and local pointer on calling thread
     210    cxy_t              thread_cxy = local_cxy;
     211    thread_t         * thread_ptr = CURRENT_THREAD;
     212
     213    // get cluster and local pointer on remote barrier
     214    remote_barrier_t * barrier_ptr = (remote_barrier_t *)GET_PTR( barrier_xp );
     215    cxy_t              barrier_cxy = GET_CXY( barrier_xp );
     216
     217    // get count and root fields from barrier descriptor
     218    count   = hal_remote_lw ( XPTR( barrier_cxy , &barrier_ptr->nb_threads ) );
     219    root_xp = hal_remote_lwd( XPTR( barrier_cxy , &barrier_ptr->root ) );
     220
     221    // get barrier sense value
     222    sense = hal_remote_lw( XPTR( barrier_cxy , &barrier_ptr->sense ) );
     223
     224        // compute expected value
     225    if ( sense == 0 ) expected = 1;
     226    else              expected = 0;
     227
     228    // atomically increment current
     229    current = hal_remote_atomic_add( XPTR( barrier_cxy , &barrier_ptr->current ) , 1 );
     230
     231    // last thread reset current, toggle sense, and activate all waiting threads
     232    // other threads block, register in queue, and deschedule
     233
     234    if( current == (count-1) )                       // last thread
     235    {
     236        hal_remote_sw( XPTR( barrier_cxy , &barrier_ptr->current) , 0 ); 
     237        hal_remote_sw( XPTR( barrier_cxy , &barrier_ptr->sense  ) , expected ); 
     238
     239        // activate waiting threads if required
     240        if( xlist_is_empty( root_xp ) == false ) 
     241        {
     242            // disable interrupts
     243                hal_disable_irq( &irq_state );
     244 
     245            xptr_t  iter_xp;
     246            xptr_t  thread_xp;
     247            XLIST_FOREACH( root_xp , iter_xp )
     248            {
     249                // get extended pointer on waiting thread
     250                thread_xp = XLIST_ELEMENT( iter_xp , thread_t , wait_list );
     251       
     252                // remove waiting thread from queue
     253                remote_spinlock_lock( XPTR( barrier_cxy , &barrier_ptr->lock ) );
     254                xlist_unlink( XPTR( barrier_cxy , &barrier_ptr->list ) );
     255                remote_spinlock_unlock( XPTR( barrier_cxy , &barrier_ptr->lock ) );
     256
     257                // unblock waiting thread
     258                thread_unblock( thread_xp , THREAD_BLOCKED_USERSYNC );
     259            }
     260
     261            // restore interrupts
     262            hal_restore_irq( irq_state );
     263        }
     264    }
     265    else                                             // not the last thread 
     266    {
     267        // disable interrupts
     268            hal_disable_irq( &irq_state );
     269 
     270        // register calling thread in barrier waiting queue
     271        xptr_t entry_xp = XPTR( thread_cxy , &thread_ptr->wait_list );
     272
     273        remote_spinlock_lock( XPTR( barrier_cxy , &barrier_ptr->lock ) );
     274        xlist_add_last( root_xp , entry_xp );
     275        remote_spinlock_unlock( XPTR( barrier_cxy , &barrier_ptr->lock ) );
     276
     277        // block & deschedule the calling thread   
     278        thread_block( thread_ptr , THREAD_BLOCKED_USERSYNC );
     279        sched_yield();
     280
     281        // restore interrupts
     282        hal_restore_irq( irq_state );
     283    }
     284}  // end remote_barrier_wait()
  • trunk/kernel/libk/remote_barrier.h

    r14 r23  
    11/*
    2  * remote_barrier.h - distributed kernel barrier definition
     2 * remote_barrier.h - Access a POSIX barrier.               
    33 *
    44 * Author  Alain Greiner (2016)
     
    1010 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1111 * under the terms of the GNU General Public License as published by
    12 err* the Free Software Foundation; version 2.0 of the License.
     12 * the Free Software Foundation; version 2.0 of the License.
    1313 *
    1414 * ALMOS-MKH is distributed in the hope that it will be useful, but
     
    2727#include <kernel_config.h>
    2828#include <hal_types.h>
     29#include <remote_spinlock.h>
     30#include <xlist.h>
     31
     32/***************************************************************************************
     33 *          This file defines a POSIX compliant barrier.
     34 *
     35 * It is used by multi-threaded applications to synchronise threads running in
     36 * different clusters, as all access functions uses hal_remote_lw() / hal_remote_sw()
     37 * portable remote access primitives.
     38 *
     39 * A barrier is declared by a given user process as a "pthread_barrier_t" global variable.
     40 * This user type is implemented as an unsigned long, but the value is not used by the
     41 * kernel. ALMOS-MKH uses only the barrier virtual address as an identifier.
     42 * For each user barrier, ALMOS-MKH creates a kernel "remote_barrier_t" structure,
     43 * dynamically allocated in the reference cluster by the remote_barrier_create() function,
     44 * and destroyed by the remote_barrier_destroy() function, using RPC if the calling thread
     45 * is not running in the reference cluster.
     46 *
     47 * The blocking "remote_barrier_wait()" function implements a descheduling policy when
     48 * the calling thread is not the last expected thread: the calling thread is registered
     49 * in a waiting queue, rooted in the barrier structure, and the the calling thread
     50 * is blocked on the THREAD_BLOCKED_USERSYNC condition. The last arrived thread
     51 * unblocks all registtered waiting threads.
     52 *
     53 * Implementation note:
     54 * This barrier is also used by the kernel in the parallel kernel_init phase, as the
     55 * remote_barrier() function does not require barrier initialisation, when the barrier
     56 * is statically allocated by the compiler in the kdata segment.
     57 * **************************************************************************************/
    2958
    3059/*****************************************************************************************
    31  * This structure defines a distributed "rendez-vous" barrier, that can be used
    32  * to synchronise several kernel threads running in different clusters
    33  * It is used in the parallel kernel_init phase.
    34  * It does not need to be initialised, but it must be statically allocated
    35  * in the KDATA segment to be properly initialised by the compiler/loader.
     60 * This structure defines the barrier descriptor.
     61 * - It contains an xlist of all barriers dynamically created by a given process,
     62 *   rooted in the reference process descriptor.
     63 * - It contains the root of another xlist to register all arrived threads.
    3664 ****************************************************************************************/
    3765
    3866typedef struct remote_barrier_s
    3967{
    40     uint32_t   current;   // number of arrived threads
    41     uint32_t   sense;     // barrier state (toggle)
    42     uint32_t   pad[(CONFIG_CACHE_LINE_SIZE>>2)-2];
     68    remote_spinlock_t  lock;          /*! lock protecting list of arrived threads       */
     69    intptr_t           ident;         /*! virtual address in user space == identifier   */
     70    uint32_t           current;       /*! number of arrived threads                     */
     71    uint32_t           sense;         /*! barrier state (toggle)                        */
     72    uint32_t           nb_threads;    /*! number of expected threads                    */
     73    xlist_entry_t      list;          /*! member of list of barriers in same process    */
     74    xlist_entry_t      root;          /*! root of list of arrived threads               */
    4375}
    4476remote_barrier_t;
    4577
    4678/*****************************************************************************************
    47  * This blocking function implements a toggle barrier. It returns only when all
    48  * expected threads reach the barrier. It can be used several times without
    49  * specific initialisation.
    50  * It is portable, as it uses the remote_lw() & remote_sw() access functions.
    51  * @ xp      : extended pointer on barrier in remote cluster
    52  * @ count   : number of expected thread
     79 * This function is directly used by the kernel in the kernel_init phase,
     80 * because it does not require barrier state initialisation.
     81 * It returns only when the <count> expected threads reach the barrier.
     82 *****************************************************************************************
     83 * @ barrier_xp  : extended pointer on barrier descriptor.
     84 * @ count       : number of expected threads.
    5385 ****************************************************************************************/
    54 inline void remote_barrier( xptr_t   xp, 
     86inline void remote_barrier( xptr_t   barrier_xp, 
    5587                            uint32_t count );
    5688
    5789
     90/*****************************************************************************************
     91 * This function returns an extended pointer on the remote barrier identified
     92 * by its virtual address in a given user process. It makes an associative search,
     93 * scanning the list of barriers rooted in the reference process descriptor.
     94 *****************************************************************************************
     95 * @ ident    : barrier virtual address, used as identifier.
     96 * @ returns extended pointer on barrier if success / returns XPTR_NULL if not found.
     97 ****************************************************************************************/
     98xptr_t remote_barrier_from_ident( intptr_t  ident );
     99
     100/*****************************************************************************************
     101 * This function implement the pthread_barrier_init() syscall.
     102 * It allocates memory for the barrier descriptor in the reference cluster for
     103 * the calling process, it initializes the barrier state, and register it in the
     104 * list of barriers owned by the reference process.
     105 *****************************************************************************************
     106 * @ count       : number of expected threads.
     107 * @ ident       : barrier identifier (virtual address in user space).
     108 * @ return 0 if success / return ENOMEM if failure.
     109 ****************************************************************************************/
     110error_t remote_barrier_create( intptr_t ident,
     111                               uint32_t count );
     112
     113/*****************************************************************************************
     114 * This function implement the pthread_barrier_destroy() syscall.
     115 * It releases thr memory allocated for the barrier descriptor, and remove the barrier
     116 * from the list of barriers owned by the reference process.
     117 *****************************************************************************************
     118 * @ barrier_xp  : extended pointer on barrier descriptor.
     119 ****************************************************************************************/
     120void remote_barrier_destroy( xptr_t   barrier_xp );
     121
     122/*****************************************************************************************
     123 * This function implement the pthread_barrier_wait() syscall.
     124 * It returns only when the number of expected threads (registered in the barrier
     125 * dexcriptor) reach the barrier.
     126 *****************************************************************************************
     127 * @ barrier_xp   : extended pointer on barrier descriptor.
     128 ****************************************************************************************/
     129void remote_barrier_wait( xptr_t   barrier_xp );
     130
     131
    58132#endif  /* _REMOTE_BARRIER_H_ */
  • trunk/kernel/libk/remote_rwlock.c

    r1 r23  
    22 * remote_rwlock.c - kernel remote rwlock implementation.
    33 *
    4  * Authors  Mohamed Karaoui (2015)
    5  *          Alain   Greiner (2016)
     4 * Authors    Alain   Greiner (2016,2017)
    65 *
    76 * Copyright (c) UPMC Sorbonne Universites
     
    6766
    6867    // get next free ticket
    69     ticket = hal_remote_lw( ticket_xp );
    70 
    71     // loop to take the lock
     68    ticket = hal_remote_atomic_add( ticket_xp , 1 );
     69
     70    // busy waiting loop to take the lock
    7271        while( ticket != hal_remote_lw( current_xp ) )
    7372        {
     
    147146
    148147    // get next free ticket
    149     ticket = hal_remote_lw( ticket_xp );
     148    ticket = hal_remote_atomic_add( ticket_xp , 1 );
    150149
    151150    // loop to take the lock
  • trunk/kernel/libk/remote_rwlock.h

    r14 r23  
    3030
    3131/***************************************************************************************
    32  * This structure defines a remote rwdlock,that supports several simultaneous read
     32 * This file defines a remote kernel lock, that supports several simultaneous read
    3333 * accesses, but only one write access. It implements a ticket based allocation policy.
    3434 * It can be used to synchronize threads running in different clusters, because
     
    4141 * When the lock is taken by another thread, the new-comers use a busy waiting policy.
    4242 *
    43  * TODO This could be replaced by a descheduling policy and a threads waiting queue
    44  * implemented in the lock itself: each thread releasing the lock (i.e. incrementing
    45  * the current field) activates the first waiting thread...
     43 * It uses a busy-waiting policy if the lock is already allocated to another thread.
    4644 **************************************************************************************/
    4745
  • trunk/kernel/libk/remote_sem.c

    r15 r23  
    2323
    2424#include <hal_types.h>
     25#include <hal_remote.h>
    2526#include <thread.h>
    2627#include <kmem.h>
     
    3536{
    3637    // get pointer on local process_descriptor
    37     process_t * process = CURRENT_PROCESS;
     38    process_t * process = CURRENT_THREAD->process;
    3839
    3940    // get extended pointer on reference process
     
    5758    XLIST_FOREACH( root_xp , iter_xp )
    5859    {
    59         sem_xp  = XLIST_ELEMENT( iter_xp , remote_sem_t , sem_list );
     60        sem_xp  = XLIST_ELEMENT( iter_xp , remote_sem_t , list );
    6061        sem_cxy = GET_CXY( sem_xp );
    6162        sem_ptr = (remote_sem_t *)GET_PTR( sem_xp );
    62         ident   = hal_remote_lw( XPTR( sem_cxy , &sem_ptr->ident ) );   
     63        ident   = (intptr_t)hal_remote_lpt( XPTR( sem_cxy , &sem_ptr->ident ) );   
    6364        if( ident == vaddr )
    6465        {
     
    7374}  // end remote_sem_from_vaddr()
    7475
    75 /////////////////////////////////////////
    76 error_t remote_sem_init( intptr_t  vaddr,
    77                          uint32_t  value )
     76///////////////////////////////////////////
     77error_t remote_sem_create( intptr_t  vaddr,
     78                           uint32_t  value )
    7879{
    7980    xptr_t         sem_xp;
     
    8182
    8283    // get pointer on local process descriptor
    83     process_t * process = CURRENT_PROCESS;
     84    process_t * process = CURRENT_THREAD->process;
    8485
    8586    // get extended pointer on reference process
    8687    xptr_t      ref_xp = process->ref_xp;
    8788
     89    // get reference process cluster and local pointer
    8890    cxy_t       ref_cxy = GET_CXY( ref_xp );
    8991    process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
     
    100102    else                         // reference is remote
    101103    {
    102         rpc_semaphore_alloc_client( ref_cxy , &sem_xp );
     104        rpc_kcm_alloc_client( ref_cxy , KMEM_SEM , &sem_xp );
    103105        sem_ptr = (remote_sem_t *)GET_PTR( sem_xp );
    104106    }
     
    106108    if( sem_xp == XPTR_NULL ) return ENOMEM;
    107109
    108     // initialise semaphore lock
     110    // initialise semaphore
     111    hal_remote_sw ( XPTR( ref_cxy , &sem_ptr->count ) , value );
     112        hal_remote_spt( XPTR( ref_cxy , &sem_ptr->ident ) , (void *)vaddr );
     113
    109114    remote_spinlock_init( XPTR( ref_cxy , &sem_ptr->lock ) );
    110 
    111     // initialise semaphore count
    112     hal_remote_sw( XPTR( ref_cxy , &sem_ptr->count ) , value );
    113 
    114     // initialise vaddr
    115         hal_remote_spt( XPTR( ref_cxy , &sem_ptr->ident ) , (void *)vaddr );
    116 
    117     // initialise waiting threads queue
    118         xlist_root_init( XPTR( ref_cxy , &sem_ptr->wait_queue ) );
    119 
    120     // register new semaphore in reference process xlist
     115        xlist_root_init( XPTR( ref_cxy , &sem_ptr->root ) );
     116        xlist_entry_init( XPTR( ref_cxy , &sem_ptr->list ) );
     117
     118    // register semaphore in reference process xlist
    121119    xptr_t root_xp = XPTR( ref_cxy , &ref_ptr->sem_root );
    122     xptr_t xp_list = XPTR( ref_cxy , &sem_ptr->sem_list );
     120    xptr_t xp_list = XPTR( ref_cxy , &sem_ptr->list );
     121
     122    remote_spinlock_lock( XPTR( ref_cxy , &ref_ptr->sync_lock ) );
    123123    xlist_add_first( root_xp , xp_list );
     124    remote_spinlock_unlock( XPTR( ref_cxy , &ref_ptr->sync_lock ) );
    124125
    125126    return 0;
     
    127128}  // en remote_sem_init()
    128129 
     130////////////////////////////////////////
     131void remote_sem_destroy( xptr_t sem_xp )
     132{
     133    // get pointer on local process descriptor
     134    process_t * process = CURRENT_THREAD->process;
     135
     136    // get extended pointer on reference process
     137    xptr_t      ref_xp = process->ref_xp;
     138
     139    // get reference process cluster and local pointer
     140    cxy_t       ref_cxy = GET_CXY( ref_xp );
     141    process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
     142
     143    // get semaphore cluster and local pointer
     144    cxy_t          sem_cxy = GET_CXY( sem_xp );
     145    remote_sem_t * sem_ptr = (remote_sem_t *)GET_PTR( sem_xp );
     146
     147    // get lock protecting semaphore
     148    remote_spinlock_lock( XPTR( sem_cxy , &sem_ptr->lock ) );
     149 
     150    // get remote pointer on waiting queue
     151    xptr_t root_xp = (xptr_t)hal_remote_lwd( XPTR( sem_cxy , &sem_ptr->root ) );
     152 
     153    if( !xlist_is_empty( root_xp ) )   // user error
     154    {
     155        printk("WARNING in %s for thread %x in process %x : "
     156               "destroy semaphore, but  waiting threads queue not empty\n",
     157               __FUNCTION__ , CURRENT_THREAD->trdid , CURRENT_THREAD->process->pid );
     158    }
     159
     160    // reset semaphore count
     161    hal_remote_sw( XPTR( sem_cxy , &sem_ptr->count ) , 0 );
     162
     163    // remove semaphore from reference process xlist
     164    remote_spinlock_lock( XPTR( ref_cxy , &ref_ptr->sync_lock ) );
     165    xlist_unlink( XPTR( sem_cxy , &sem_ptr->list ) );
     166    remote_spinlock_unlock( XPTR( ref_cxy , &ref_ptr->sync_lock ) );
     167
     168    // release lock
     169    remote_spinlock_unlock( XPTR( sem_cxy , &sem_ptr->lock ) );
     170
     171    // release memory allocated for semaphore descriptor
     172    if( sem_cxy == local_cxy )                            // reference is local
     173    {
     174        kmem_req_t  req;
     175        req.type = KMEM_SEM;
     176        req.ptr  = sem_ptr;
     177        kmem_free( &req );
     178    }
     179    else                                                  // reference is remote
     180    {
     181        rpc_kcm_free_client( sem_cxy , sem_ptr , KMEM_SEM );
     182    }
     183
     184}  // end remote_sem_destroy()
     185
    129186//////////////////////////////////
    130187void remote_sem_wait( xptr_t sem_xp )
     
    153210
    154211        // register thread in waiting queue
    155         xptr_t root_xp   = (xptr_t)hal_remote_lwd( XPTR( sem_cxy , &sem_ptr->wait_queue ) );
     212        xptr_t root_xp   = (xptr_t)hal_remote_lwd( XPTR( sem_cxy , &sem_ptr->root ) );
    156213        xptr_t thread_xp = XPTR( local_cxy , this );
    157214                xlist_add_last( root_xp , thread_xp );
     
    177234 
    178235    // get remote pointer on waiting queue root
    179     xptr_t queue_xp = (xptr_t)hal_remote_lwd( XPTR( sem_cxy , &sem_ptr->wait_queue ) );
    180  
    181         if( xlist_is_empty( queue_xp ) )   // no waiting thread
     236    xptr_t root_xp = (xptr_t)hal_remote_lwd( XPTR( sem_cxy , &sem_ptr->root ) );
     237 
     238        if( xlist_is_empty( root_xp ) )   // no waiting thread
    182239    {
    183240        // get semaphore current value
     
    190247    {
    191248        // get first waiting thread from queue
    192         xptr_t thread_xp = XLIST_FIRST_ELEMENT( queue_xp , thread_t , wait_list );
     249        xptr_t thread_xp = XLIST_FIRST_ELEMENT( root_xp , thread_t , wait_list );
    193250
    194251        // get thread cluster and local poiner
     
    206263}  // end remote_sem_post()
    207264
    208 ////////////////////////////////////////
    209 void remote_sem_destroy( xptr_t sem_xp )
    210 {
    211     // get semaphore cluster and local pointer
    212     cxy_t          sem_cxy = GET_CXY( sem_xp );
    213     remote_sem_t * sem_ptr = (remote_sem_t *)GET_PTR( sem_xp );
    214 
    215     // get lock protecting semaphore
    216     remote_spinlock_lock( XPTR( sem_cxy , &sem_ptr->lock ) );
    217  
    218     // get remote pointer on waiting queue
    219     xptr_t queue_xp = (xptr_t)hal_remote_lwd( XPTR( sem_cxy , &sem_ptr->wait_queue ) );
    220  
    221     if( !xlist_is_empty( queue_xp ) )   // user error
    222     {
    223         printk("WARNING in %s for thread %x in process %x : "
    224                "destroy semaphore, but  waiting threads queue not empty\n",
    225                __FUNCTION__ , CURRENT_THREAD->trdid , CURRENT_PROCESS->pid );
    226     }
    227 
    228     // reset semaphore count
    229     hal_remote_sw( XPTR( sem_cxy , &sem_ptr->count ) , 0 );
    230 
    231     // remove semaphore from process
    232     xptr_t xp_list = (xptr_t)hal_remote_lwd( XPTR( sem_cxy , &sem_ptr->sem_list ) );
    233     xlist_unlink( xp_list );
    234 
    235     // release lock
    236     remote_spinlock_unlock( XPTR( sem_cxy , &sem_ptr->lock ) );
    237 
    238     // release memory allocated
    239     if( sem_cxy == local_cxy )         // reference is local
    240     {
    241         kmem_req_t  req;
    242         req.type = KMEM_SEM;
    243         req.ptr  = sem_ptr;
    244         kmem_free( &req );
    245     }
    246     else                                // reference is remote
    247     {
    248         rpc_semaphore_free_client( sem_cxy , sem_ptr );
    249     }
    250 
    251 }  // end remote_sem_destroy()
    252265
    253266//////////////////////////////////////////////
  • trunk/kernel/libk/remote_sem.h

    r15 r23  
    3030
    3131/*********************************************************************************************
    32  *      This file defines the the POSIX compliant unnamed semaphore.
     32 *      This file defines a POSIX compliant unnamed semaphore.
    3333 *
    3434 * A semaphore is declared by a given user process as a "sem_t" global variable.
     
    4646
    4747/*********************************************************************************************
    48  * This structure defines the kernel remote_sem_t structure.
    49  * It contains the root of a waiting threads queue, implemented as a distributed xlist.
    50  * It contains an xlist of all semaphores, rooted in the reference process descriptor.
    51  * It contains a lock protecting both the semaphore value and the waiting queue.
     48 * This structure defines the kernel semaphore descriptor.
     49 * - It contains the root of a waiting threads queue, implemented as a distributed xlist.
     50 * - It contains an xlist of all semaphores, rooted in the reference process descriptor.
     51 * - It contains a lock protecting both the semaphore value and the waiting queue.
    5252 ********************************************************************************************/
    5353
     
    5757        uint32_t          count;         /*! current value                                      */
    5858    intptr_t          ident;         /*! virtual address in user space == identifier        */
    59     xlist_entry_t     wait_queue;    /*! root of waiting thread queue                       */
    60     xlist_entry_t     sem_list;      /*! member of list of semaphores in same process       */
     59    xlist_entry_t     root;          /*! root of waiting thread queue                       */
     60    xlist_entry_t     list;          /*! member of list of semaphores in same process       */
    6161}
    6262remote_sem_t;
    63 
    64 /*********************************************************************************************
    65  * This enum defines the semaphore operation types supported by the sys_sem() function.
    66  * It must be consistent with the values defined in the semaphore.c file (user library).
    67  ********************************************************************************************/
    68 
    69 typedef enum
    70 {
    71         SEM_INIT,
    72         SEM_GETVALUE,
    73         SEM_WAIT,
    74         SEM_POST,
    75         SEM_DESTROY
    76 }
    77 sem_operation_t;
    78 
    7963
    8064
    8165/*********************************************************************************************
    8266 * This function returns an extended pointer on the remote semaphore identified
    83  * by its virtual address in a given user process. It makes an associative search, scanning
    84  * the list of semaphores rooted in the reference process descriptor.
     67 * by its virtual address in a given user process. It makes an associative search,
     68 * scanning the list of semaphores rooted in the reference process descriptor.
    8569 *********************************************************************************************
    8670 * @ process  : pointer on local process descriptor.
     
    9983 * @ returns 0 if success / returns ENOMEM if error.
    10084 ********************************************************************************************/
    101 error_t remote_sem_init( intptr_t  vaddr,
    102                          uint32_t  value );
     85error_t remote_sem_create( intptr_t  vaddr,
     86                           uint32_t  value );
    10387 
     88/****************************yy***************************************************************
     89 * This function implements the SEM_DESTROY operation.
     90 * It desactivates the semaphore, and releases the physical memory allocated in the
     91 * reference cluster, using a RPC if required.
     92 *********************************************************************************************
     93 * @ sem_xp   : extended pointer on semaphore.
     94 ********************************************************************************************/
     95void remote_sem_destroy( xptr_t sem_xp );
     96
    10497/****************************yy***************************************************************
    10598 * This blocking function implements the SEM_WAIT operation.
     
    123116
    124117/****************************yy***************************************************************
    125  * This function implements the SEM_DESTROY operation.
    126  * It desactivates the semaphore, and releases the physical memory allocated in the
    127  * reference cluster, using a RPC if required.
    128  *********************************************************************************************
    129  * @ sem_xp   : extended pointer on semaphore.
    130  ********************************************************************************************/
    131 void remote_sem_destroy( xptr_t sem_xp );
    132 
    133 /****************************yy***************************************************************
    134118 * This function implements the SEM_GETVALUE operation.
    135119 * It returns in the <data> buffer the semaphore current value.
  • trunk/kernel/libk/rwlock.c

    r14 r23  
    8686 
    8787    // decrement number of readers
    88     hal_atomic_dec( &lock->count );
     88    hal_atomic_add( &lock->count , -1 );
    8989    this->local_locks--;
    9090
  • trunk/kernel/libk/string.h

    r1 r23  
    8383
    8484/********************************************************************************************
    85  * TODO
     85 * this function copies the <src> buffer to the <dst> buffer, including the terminating NUL.
    8686 ********************************************************************************************
     87 * @ dst   : pointer on destination buffer.
     88 * @ src   : pointer on source buffer.
    8789 *******************************************************************************************/
    88 char * strcpy ( char * dest,
     90char * strcpy ( char * dst,
    8991                char * src );
    9092
    9193/********************************************************************************************
    92  * TODO
     94 * This function copies <n> characters from the <sr> buffer to the <dst> buffer.
    9395 ********************************************************************************************
     96 * @ dst   : pointer on destination buffer.
     97 * @ src   : pointer on source buffer.
     98 * @ n     : number of characters to be copied.
    9499 *******************************************************************************************/
    95 char * strncpy ( char    * dest,
     100char * strncpy ( char    * dst,
    96101                 char    * src,
    97102                 uint32_t  n );
    98103
    99104/********************************************************************************************
    100  * TODO
     105 * This function locates the first occurence of the <c> character in the <s> string.
    101106 ********************************************************************************************
     107 * @ s     : string to be analysed.
     108 * @ c     : searched character value (casted to a char)
     109 * @ return pointer on the found character / return NULL if not found.
    102110 *******************************************************************************************/
    103111char * strchr ( const char * s,
     
    105113
    106114/********************************************************************************************
    107  * TODO
     115 * This function locates the last occurence of the <c> character in the <s> string.
    108116 ********************************************************************************************
     117 * @ s     : string to be analysed.
     118 * @ c     : searched character value (casted to a char)
     119 * @ return pointer on the found character / return NULL if not found.
    109120 *******************************************************************************************/
    110121char * strrchr ( const char * t,
  • trunk/kernel/libk/xhtab.c

    r14 r23  
    22 * xhtab.c - Remote access embedded hash table implementation.
    33 *
    4  * Author     Alain Greiner          (2016)
     4 * Author     Alain Greiner          (2016,2017)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    3434
    3535
    36 ///////////////////////////////////////////////////////////////////////////////////////
    37 // This static function s called by the xhtab_lookup() and xhtab_register() functions.
    38 // It scan one sub-list identified by  <index> to find an item  identified by <key>.
    39 // The hash table is identified by <cxy> and local pointer <xhtab>.
     36///////////////////////////////////////////////////////////////////////////////////////////
     37// Item type specific (static) functions (two functions for each item type).
     38// - for type <vfs_dentry_t>, identifier is the name field.
     39///////////////////////////////////////////////////////////////////////////////////////////
     40
     41///////////////////////////////////////////////////////////////////////////////////////////
     42// These static functions compute the hash index from the key.
     43///////////////////////////////////////////////////////////////////////////////////////////
     44// @ key      : local pointer on key.
     45// @ return the index value, from 0 to (HASHTAB_SIZE - 1)
     46///////////////////////////////////////////////////////////////////////////////////////////
     47
     48/////////////////////////////////////////
     49uint32_t xhtab_dentry_index( void * key )
     50{
     51        char     * name  = key;
     52        uint32_t   index = 0;
     53        while( *name )
     54    {
     55        index = index + (*(name++) ^ index);
     56    }
     57        return index % HASHTAB_SIZE;
     58}
     59
     60////////////////////////////////////////////////////////////////////////////////////////////
     61// These static function are used by xhtab_lookup(), xhtab_insert(), xhtab_remove().
     62// They scan one sub-list identified by  <index> to find an item  identified by <key>.
    4063// The sub-list is not modified, but the readlock must have been taken by the caller.
    41 ///////////////////////////////////////////////////////////////////////////////////////
    42 // @ cxy       : hash table cluster.
    43 // @ xhtab_xp  : hash table local pointer.
     64////////////////////////////////////////////////////////////////////////////////////////////
     65// @ xhtab_xp  : extended pointer on hash table.
    4466// @ index     : index of sub-list to be scanned.
    4567// @ key       : local pointer on item identifier.
    46 ///////////////////////////////////////////////////////////////////////////////////////
    47 static xptr_t xhtab_scan( cxy_t     cxy,
    48                           xhtab_t * xhtab,
    49                           uint32_t  index,
    50                           void    * key )
    51 {
    52     xptr_t   xlist_xp;    // extended pointer on xlist_entry_t (iterator)
    53     xptr_t   item_xp;     // extended pointer on found item (return value)
     68// return an extended pointer on item if found / return XPTR_NULL if not found.
     69////////////////////////////////////////////////////////////////////////////////////////////
     70
     71////////////////////////////////////////////////////
     72static xptr_t xhtab_dentry_scan( xptr_t    xhtab_xp,
     73                                 uint32_t  index,
     74                                 void    * key )
     75{
     76    xptr_t    xlist_xp;                                 // xlist_entry_t (iterator)
     77    xhtab_t * xhtab_ptr;                                // hash table local pointer
     78    cxy_t     xhtab_cxy;                                // hash table cluster
     79    char      local_name[CONFIG_VFS_MAX_NAME_LENGTH];   // local copy of dentry name
     80
     81    // get hash table cluster and local pointer
     82    xhtab_cxy = GET_CXY( xhtab_xp );
     83    xhtab_ptr = (xhtab_t *)GET_PTR( xhtab_xp );
     84
     85    // scan sub-list[index]
     86    XLIST_FOREACH( XPTR( xhtab_cxy , &xhtab_ptr->roots[index] ) , xlist_xp )
     87    {
     88        // get extended pointer on dentry containing the xlist_entry_t
     89            xptr_t dentry_xp = XLIST_ELEMENT( xlist_xp , vfs_dentry_t , xlist );
     90
     91        // get dentry cluster and local pointer
     92        cxy_t          dentry_cxy = GET_CXY( dentry_xp );
     93        vfs_dentry_t * dentry_ptr = (vfs_dentry_t *)GET_PTR( dentry_xp );
    5494   
    55     // scan the sub-list[index]
    56         XLIST_FOREACH( XPTR( cxy , &xhtab->roots[index] ) , xlist_xp )
    57         {
    58         if ( xhtab->compare( xlist_xp , key , &item_xp ) ) return item_xp;
    59     }
    60 
    61     // no matching item found
    62         return XPTR_NULL;
     95        // make a local copy of dentry name
     96        hal_remote_memcpy( XPTR( local_cxy  , local_name ) ,
     97                           XPTR( dentry_cxy , dentry_ptr->name ),
     98                           CONFIG_VFS_MAX_NAME_LENGTH  );
     99
     100        // check matching
     101        if( strcmp( local_name , (char *)key ) == 0 ) return dentry_xp;
     102    }
     103
     104    // No matching item found
     105    return XPTR_NULL;
    63106}
    64107
    65 /////////////////////////////////
    66 void xhtab_init( xhtab_t * xhtab,
    67                  uint32_t  type )
     108////////////////////////////////////////////////////////////////////////////////////////
     109//         Generic access functions
     110////////////////////////////////////////////////////////////////////////////////////////
     111
     112//////////////////////////////////////////
     113void xhtab_init( xhtab_t          * xhtab,
     114                 xhtab_item_type_t  type )
    68115{
    69116        uint32_t i;
     
    76123    if( type == XHTAB_DENTRY_TYPE )
    77124    {
    78         hal_remote_spt( XPTR( local_cxy , &xhtab->compare ) , &xhtab_dentry_compare );
    79         hal_remote_spt( XPTR( local_cxy , &xhtab->index   ) , &xhtab_dentry_index   );
     125        xhtab->scan  = &xhtab_dentry_scan;
     126        xhtab->index = &xhtab_dentry_index;
    80127    }
    81128    else
     
    92139
    93140///////////////////////////////////////
    94 void xhtab_register( xptr_t   xhtab_xp,
    95                      void   * key,
    96                      xptr_t   xlist_xp )
    97 {
     141error_t xhtab_insert( xptr_t   xhtab_xp,
     142                      void   * key,
     143                      xptr_t   xlist_xp )
     144{
     145
     146printk("\n                @@@ xhtab_insert : 0 / name = %s / xhtab_xp = %l / xlist_xp = %l\n",
     147       key , xhtab_xp , xlist_xp );
     148
    98149    // get xhtab cluster and local pointer
    99150    cxy_t     xhtab_cxy = GET_CXY( xhtab_xp );
     
    103154        uint32_t index = xhtab_ptr->index( key );
    104155
     156printk("\n                @@@ xhtab_insert : 1 / name = %s / index = %d\n",
     157       key , index );
     158
    105159    // take the lock protecting hash table
    106160    remote_rwlock_wr_lock( XPTR( xhtab_cxy , &xhtab_ptr->lock ) );
    107161
    108     // register item in hash table
    109         xlist_add_last( XPTR( xhtab_cxy , &xhtab_ptr->roots[index] ) , xlist_xp );
    110 
    111     // update number of registered items
    112     hal_remote_atomic_add( XPTR( xhtab_cxy , &xhtab_ptr->items ) , 1 );
    113 
    114     // release the lock protecting hash table
    115     remote_rwlock_wr_unlock( XPTR( xhtab_cxy , &xhtab_ptr->lock ) );
    116 
    117 }  // end xhtab_register()
     162    // search a matching item
     163    xptr_t item_xp = xhtab_ptr->scan( xhtab_xp , index , key );
     164
     165    if( item_xp != XPTR_NULL )    // error if found
     166    {
     167        // release the lock protecting hash table
     168        remote_rwlock_wr_unlock( XPTR( xhtab_cxy , &xhtab_ptr->lock ) );
     169
     170printk("\n                @@@ xhtab_insert : 2 / name = %s / item_xp = %l\n",
     171       key , item_xp );
     172
     173        return EINVAL;
     174    }
     175    else                          // insert item if not found
     176    {
     177        // register item in hash table
     178            xlist_add_last( XPTR( xhtab_cxy , &xhtab_ptr->roots[index] ) , xlist_xp );
     179
     180        // update number of registered items
     181        hal_remote_atomic_add( XPTR( xhtab_cxy , &xhtab_ptr->items ) , 1 );
     182
     183        // release the lock protecting hash table
     184        remote_rwlock_wr_unlock( XPTR( xhtab_cxy , &xhtab_ptr->lock ) );
     185
     186printk("\n                @@@ xhtab_insert : 3 / name = %s / item_xp = %l\n",
     187       key , xhtab_ptr->scan( xhtab_xp , index , key ) );
     188
     189        return 0;
     190    }
     191}  // end xhtab_insert()
    118192
    119193/////////////////////////////////////
    120 void xhtab_remove( xptr_t   xhtab_xp,
    121                    void   * key )
     194error_t xhtab_remove( xptr_t   xhtab_xp,
     195                      void   * key,
     196                      xptr_t   xlist_entry_xp )
    122197{
    123198    // get xhtab cluster and local pointer
     
    125200    xhtab_t * xhtab_ptr = (xhtab_t *)GET_PTR( xhtab_xp );
    126201
     202    // compute index from key
     203        uint32_t index = xhtab_ptr->index( key );
     204
    127205    // take the lock protecting hash table
    128206    remote_rwlock_wr_lock( XPTR( xhtab_cxy , &xhtab_ptr->lock ) );
    129207
    130     // compute index from key
    131         uint32_t index = xhtab_ptr->index( key );
    132 
    133208    // get extended pointer on item to remove
    134     xptr_t item_xp = xhtab_scan( xhtab_cxy , xhtab_ptr , index , key );
    135 
    136     if( item_xp == XPTR_NULL )    // do nothing if not found
    137     {
    138         // release the lock protecting hash table
    139         remote_rwlock_wr_unlock( XPTR( xhtab_cxy , &xhtab_ptr->lock ) );
     209    xptr_t item_xp = xhtab_ptr->scan( xhtab_xp , index , key );
     210
     211    if( item_xp == XPTR_NULL )    // error if not found
     212    {
     213        // release the lock protecting hash table
     214        remote_rwlock_wr_unlock( XPTR( xhtab_cxy , &xhtab_ptr->lock ) );
     215
     216        return EINVAL;
    140217    }
    141218    else                          // remove item if found
    142219    {
    143         // get item cluster and local pointer
    144         cxy_t          item_cxy = GET_CXY( item_xp );
    145         vfs_dentry_t * item_ptr = (vfs_dentry_t *)GET_PTR( item_xp );
    146 
    147220        // remove item from hash table <=> unlink xlist_entry_t
    148         xlist_unlink( XPTR( item_cxy , &item_ptr->xlist ) );
     221        xlist_unlink( xlist_entry_xp );
    149222
    150223        // update number of registered items
     
    153226        // release the lock protecting hash table
    154227        remote_rwlock_wr_unlock( XPTR( xhtab_cxy , &xhtab_ptr->lock ) );
    155     }
    156 }  // end xhtab_unregister()
     228
     229        return 0;
     230    }
     231}  // end xhtab_remove()
    157232
    158233/////////////////////////////////////////
     
    173248
    174249    // scan sub-list
    175     item_xp = xhtab_scan( xhtab_cxy , xhtab_ptr , index , key );
     250    item_xp = xhtab_ptr->scan( xhtab_xp , index , key );
    176251
    177252    // release the lock protecting hash table
     
    183258
    184259
    185 
    186 /////////////////////////////////////////
    187 uint32_t xhtab_dentry_index( void * key )
    188 {
    189         char    * str   = key;
    190         uint32_t  index = 0;
    191  
    192         while( *str ) index = index + (*(str++) ^ index);
    193 
    194         return index % HASHTAB_SIZE;
    195 }
    196 
    197 ///////////////////////////////////////////////
    198 bool_t xhtab_dentry_compare( xptr_t   xlist_xp,
    199                              void   * key,
    200                              xptr_t * item_xp )
    201 {
    202     char   tested_name[256];      // local copy of name stored in remote hash table
    203 
    204     char * searched_name = key;   // local pointer on searched name
    205 
    206     // compute name length
    207     uint32_t length = strlen( searched_name );
    208 
    209     // get extended pointer on dentry containing the xlist_entry_t
    210         xptr_t dentry_xp = XLIST_ELEMENT( xlist_xp , vfs_dentry_t , xlist );
    211 
    212     // get dentry cluster and local pointer
    213     cxy_t          dentry_cxy = GET_CXY( dentry_xp );
    214     vfs_dentry_t * dentry_ptr = (vfs_dentry_t *)GET_PTR( dentry_xp );
    215    
    216     // make a local copy of remote dentry name
    217     hal_remote_memcpy( XPTR( local_cxy  , tested_name ) ,
    218                        XPTR( dentry_cxy , dentry_ptr->name ) , length );
    219 
    220     // check matching / return if match
    221     if( strcmp( tested_name , searched_name ) == 0 )
    222     {
    223         return true;
    224         *item_xp = dentry_xp;
    225     }
    226     else
    227     {
    228         return false;
    229     }
    230 }
    231 
    232 
    233  
    234 ////////////////////////////////////////
    235 uint32_t xhtab_inode_index( void * key )
    236 {
    237         uint32_t * inum = key;
    238 
    239         return (((*inum) >> 16) ^ ((*inum) & 0xFFFF)) % HASHTAB_SIZE;
    240 }
    241 
    242 ///////////////////////////////////////////////
    243 bool_t xhtab_inode_compare( xptr_t   xlist_xp,
    244                             void   * key,
    245                             xptr_t * item_xp )
    246 {
    247     uint32_t * searched_inum = key;
    248     uint32_t   tested_inum;   
    249 
    250     // get extended pointer on inode containing the xlist_entry_t
    251         xptr_t inode_xp = XLIST_ELEMENT( xlist_xp , vfs_inode_t , xlist );
    252 
    253     // get inode cluster and local pointer
    254     cxy_t         inode_cxy = GET_CXY( inode_xp );
    255     vfs_inode_t * inode_ptr = (vfs_inode_t *)GET_PTR( inode_xp );
    256    
    257     // get tested inode inum
    258     tested_inum = hal_remote_lw( XPTR( inode_cxy , &inode_ptr->inum ) );
    259 
    260     // check matching / return if match
    261     if( tested_inum == *searched_inum )
    262     {
    263         return true;
    264         *item_xp = inode_xp;
    265     }
    266     else
    267     {
    268         return false;
    269     }
    270 }
    271 
  • trunk/kernel/libk/xhtab.h

    r14 r23  
    22 * xhtab.h - Remote access embedded hash table definition.
    33 *
    4  * Author     Alain Greiner          (2016)
     4 * Author     Alain Greiner  (2016,2017)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    3131
    3232
    33 /******************************************************************************************
    34  * This file define a generic, embedded, hash table that can be remotely accessed by
    35  * any thread running in any cluster.
    36  * The main goal is to speedup search by key in a set of items identified by their key.
    37  * For this purpose the set of all registered items is split in several subsets:
    38  * Each subset is organised an embedded double linked lists.
    39  * - an item is uniquely identified by a <key>, that can be a single uint32_t,
    40  *   a name (character string), or a more complex structure.
    41  * - From the <key>, the hash table uses an item type specific "xhtab_index()" function,
    42  *   to compute an <index> value, defining a subset of registered items.
    43  * - to discriminate between items that have the same <index>, the hash table uses another
    44  *   item type specific "xhtab_compare()" function for the associative search in subset.
    45  * - Each registered item is a structure, that must contain an embedded xlist_entry,
    46  *   that is part of the xlist implementing the subset.
    47  * - The xhtab header contains an array indexed by <index> and containing the roots
    48  *   of the various xlists implementing the subsets.
    49  *   pointer on the searched item can be obtained by a simple offset.
    50  * Implementation note:
    51  * to use this generic infrastructure for a new type of item, you must define a new
    52  * type in the xhtan_item_type_t" below, and to define the two  associated
    53  * "xhtab_compare() and xhtab_index().
    54  *****************************************************************************************/
     33///////////////////////////////////////////////////////////////////////////////////////////
     34// This file define a generic, embedded, remotely accessible hash table.
     35//
     36// It can be accessed by any thread, running in any cluster.
     37// It is generic as it can be used to register various types of items.
     38// The main goal is to speedup search by key for a large number of items of same type.
     39// For this purpose the set of all registered items is split in several subsets.
     40// Each subset is organised an embedded double linked lists.
     41// - an item is uniquely identified by a <key>, that can be a single uint32_t,
     42//   a name (character string), or a more complex structure.
     43// - From the pointer on <key>, we use an item type specific xhtab_index() function,
     44//   to compute an <index> value, defining a subset of registered items.
     45// - to discriminate between items that have the same <index>, the hash table uses another
     46//   item type specific "xhtab_scan()" function for the associative search in subset.
     47// - Each registered item is a structure, that must contain an embedded xlist_entry,
     48//   that is part of the xlist implementing the subset.
     49//
     50// Implementation Note: for each supported item type ***, you must define the two
     51//                      xhtab_***_index() and xhtab_***_scan() functions, and
     52//                      update the xhtab_init() function.
     53///////////////////////////////////////////////////////////////////////////////////////////
    5554
    5655#define HASHTAB_SIZE    64   // number of subsets
    5756
    5857/******************************************************************************************
    59  * These typedef define the generic xhtab_compare() and xhtab_index() function prototypes.
    60  * It must exist a specific couple of functions for each item type.
    61  * @ entry_xp : extended pointer on an xlist_entry_t in a partial xlist.
    62  * @ key      : local pointer on the searched item key.
    63  * @ item_xp  : buffer to store extended pointer on found item.
     58 * These typedef define the two item type specific function prototypes.
    6459 *****************************************************************************************/
    6560
    66 typedef  bool_t    xhtab_compare_t( xptr_t entry_xp , void * key , xptr_t * item_xp );
     61typedef  xptr_t    xhtab_scan_t( xptr_t xhtab_xp , uint32_t index , void * key );
     62
    6763typedef  uint32_t  xhtab_index_t( void * key );
    6864
     
    7369typedef enum
    7470{
    75     XHTAB_DENTRY_TYPE = 1,                   /*! item is a vfs_dentry_t                  */
    76     XHTAB_INODE_TYPE  = 2,                   /*! item is a vfs_inode_t                   */
     71    XHTAB_DENTRY_TYPE = 0,                    /*! item is a vfs_dentry_t                 */
    7772}
    7873xhtab_item_type_t;
    7974
    8075/******************************************************************************************
    81  * This structure define the root of a generic, remote accessible, hash table.
     76 * This structure define the root of the remote accessible hash table.
    8277 *****************************************************************************************/
    8378
     
    8580{
    8681        xlist_entry_t      roots[HASHTAB_SIZE];   /*! array of roots of xlist                */
    87     xhtab_compare_t  * compare;               /*! item specific index function           */
    88     xhtab_index_t    * index;                 /*! item specific compare function         */
     82    xhtab_index_t    * index;                 /*! item specific function                 */
     83    xhtab_scan_t     * scan;                  /*! item specific function                 */
    8984    uint32_t           items;                 /*! number of registered items             */
    90     remote_rwlock_t  lock;                  /*! lock protecting hash table modifs      */
     85    remote_rwlock_t    lock;                  /*! lock protecting hash table accesses    */
    9186}
    9287xhtab_t;
    9388
    9489/******************************************************************************************
    95  * This function initializes an empty hash table (zero children).
     90 * This function initializes an empty hash table (zero registered item).
    9691 * The initialisation must be done by a thread running in cluster containing the table.
    9792 ******************************************************************************************
     
    9994 * @ type    : item type (see above).
    10095 *****************************************************************************************/
    101 void xhtab_init( xhtab_t * xhtab,
    102                  uint32_t  type );
     96void xhtab_init( xhtab_t           * xhtab,
     97                 xhtab_item_type_t   type );
    10398
    10499/******************************************************************************************
     
    108103 * @ key        : local pointer on item identifier.
    109104 * @ xlist_xp   : extended pointer on xlist_entry_t embedded in item to be registered.
     105 * @ return 0 if success / return EINVAL if item already registered.
    110106 *****************************************************************************************/
    111 void xhtab_register( xptr_t   xhtab_xp,
    112                      void   * key,
    113                      xptr_t   xlist_xp );
     107error_t xhtab_insert( xptr_t   xhtab_xp,
     108                      void   * key,
     109                      xptr_t   xlist_xp );
    114110
    115111/******************************************************************************************
    116112 * This function safely remove an item from the hash table, using the lock protecting it.
    117113 ******************************************************************************************
    118  * @ xhtab_xp : extended pointer on hash table.
    119  * @ key      : local pointer on item identifier.
     114 * @ xhtab_xp       : extended pointer on hash table.
     115 * @ key            : local pointer on item identifier.
     116 * @ xlist_entry_xp : extended pointer on xlist_entry embedded in item to be removed.
     117 * @ return 0 if success / return EINVAL if item not found.
    120118 *****************************************************************************************/
    121 void xhtab_remove( xptr_t   xhtab_xp,
    122                    void   * key );
     119error_t xhtab_remove( xptr_t   xhtab_xp,
     120                      void   * key,
     121                      xptr_t   xlist_entry_xp );
    123122
    124123/******************************************************************************************
     
    133132
    134133
    135 /************************  vfs_dentry_t specific functions  ******************************/
    136 
    137 /******************************************************************************************
    138  * This function compute the hash index from the key, when the item is a vhs_dentry_t.
    139  ******************************************************************************************
    140  * @ key      : local pointer on dentry name.
    141  * @ return the index value, from 0 to (HASHTAB_SIZE - 1)
    142  *****************************************************************************************/
    143 uint32_t xhtab_dentry_index( void * key );
    144 
    145 /******************************************************************************************
    146  * This function check the key value for a given item, when the item is a vhs_dentry_t.
    147  ******************************************************************************************
    148  * @ xlist_xp : extended pointer on xlist_entry_t contained in a vfs_dentry_t.
    149  * @ key      : local pointer on searched dentry name.
    150  * @ return true if the item name matches the searched name.
    151  *****************************************************************************************/
    152 bool_t xhtab_dentry_compare( xptr_t   xlist_xp,
    153                              void   * key,
    154                              xptr_t * item_xp );
    155 
    156 
    157 /************************  vfs_inode_t specific functions  *******************************/
    158 
    159 /******************************************************************************************
    160  * This function compute the hash index from the key, when the item is a vhs_inode_t.
    161  ******************************************************************************************
    162  * @ key      : local pointer on dentry name.
    163  * @ return the index value, from 0 to (HASHTAB_SIZE - 1)
    164  *****************************************************************************************/
    165 uint32_t xhtab_inode_index( void * key );
    166 
    167 /******************************************************************************************
    168  * This function check the key value for a given item, when the item is a vhs_inode_t.
    169  ******************************************************************************************
    170  * @ xlist_xp : extended pointer on xlist_entry_t contained in a vfs_dentry_t.
    171  * @ key      : local pointer on searched dentry name.
    172  * @ return true if the item name matches the searched name.
    173  *****************************************************************************************/
    174 bool_t xhtab_inode_compare( xptr_t   xlist_xp,
    175                             void   * key,
    176                             xptr_t * item_xp );
    177 
    178134#endif  /* _XHTAB_H_ */
  • trunk/kernel/mm/kcm.h

    r18 r23  
    7070typedef struct kcm_page_s
    7171{
    72         BITMAP          ( bitmap , CONFIG_KCM_BLOCKS_MAX );
     72        uint32_t        bitmap[BITMAP_SIZE(CONFIG_KCM_BLOCKS_MAX)];
    7373        uint8_t       * base;                  /*! pointer on first block in page          */
    7474        kcm_t         * kcm;                   /*! owner KCM allocator                     */
  • trunk/kernel/mm/kmem.c

    r18 r23  
    4444#include <remote_sem.h>
    4545#include <remote_barrier.h>
     46#include <remote_mutex.h>
     47#include <remote_condvar.h>
    4648#include <mapper.h>
    4749#include <grdxt.h>
     
    8991    else if( type == KMEM_CPU_CTX )       return sizeof( hal_cpu_context_t );
    9092    else if( type == KMEM_FPU_CTX )       return sizeof( hal_fpu_context_t );
     93    else if( type == KMEM_BARRIER )       return sizeof( remote_barrier_t );
    9194
    9295    else if( type == KMEM_FATFS_INODE )   return sizeof( fatfs_inode_t );
    9396    else if( type == KMEM_FATFS_CTX )     return sizeof( fatfs_ctx_t );
    94     else if( type == KMEM_RAMFS_INODE )   return sizeof( ramfs_inode_t );
    95     else if( type == KMEM_RAMFS_CTX )     return sizeof( ramfs_ctx_t );
     97    else if( type == KMEM_DEVFS_INODE )   return sizeof( devfs_inode_t );
     98    else if( type == KMEM_MUTEX )         return sizeof( remote_mutex_t );
    9699    else if( type == KMEM_VFS_CTX )       return sizeof( vfs_ctx_t );
    97100    else if( type == KMEM_VFS_INODE )     return sizeof( vfs_inode_t );
     
    99102    else if( type == KMEM_VFS_FILE )      return sizeof( vfs_file_t );
    100103    else if( type == KMEM_SEM )           return sizeof( remote_sem_t );
     104    else if( type == KMEM_CONDVAR )       return sizeof( remote_condvar_t );
    101105    else                                  return 0;
    102106}
     
    114118    else if( type == KMEM_CPU_CTX )       return "KMEM_CPU_CTX";
    115119    else if( type == KMEM_FPU_CTX )       return "KMEM_FPU_CTX";
     120    else if( type == KMEM_BARRIER )       return "KMEM_BARRIER";
    116121
    117122    else if( type == KMEM_FATFS_INODE )   return "KMEM_FATFS_INODE";
    118123    else if( type == KMEM_FATFS_CTX )     return "KMEM_FATFS_CTX";
    119     else if( type == KMEM_RAMFS_INODE )   return "KMEM_RAMFS_INODE";
    120     else if( type == KMEM_RAMFS_CTX )     return "KMEM_RAMFS_CTX";
     124    else if( type == KMEM_DEVFS_INODE )   return "KMEM_DEVFS_INODE";
     125    else if( type == KMEM_MUTEX )         return "KMEM_MUTEX";
    121126    else if( type == KMEM_VFS_CTX )       return "KMEM_VFS_CTX";
    122127    else if( type == KMEM_VFS_INODE )     return "KMEM_VFS_INODE";
     
    124129    else if( type == KMEM_VFS_FILE )      return "KMEM_VFS_FILE";
    125130    else if( type == KMEM_SEM )           return "KMEM_SEM";
     131    else if( type == KMEM_SEM )           return "KMEM_CONDVAR";
    126132    else                                  return "undefined";
    127133}
  • trunk/kernel/mm/kmem.h

    r18 r23  
    3131
    3232/*************************************************************************************
    33  * This enum defines the Kernel Memory Types for dynamically allocated objectsn.
     33 * This enum defines the Kernel Memory Types for dynamically allocated objects.
     34 * WARNING : this enum must be kepts consistent with use in kmem.c file.
    3435 ************************************************************************************/
    3536
     
    4546  KMEM_CPU_CTX          = 7,   /*! hal_cpu_context_t                                */
    4647  KMEM_FPU_CTX          = 8,   /*! hal_fpu_context_t                                */
    47   KMEM_TBD_9            = 9,
     48  KMEM_BARRIER          = 9,   /*! remote_barrier_t                                 */
    4849
    4950  KMEM_FATFS_INODE      = 10,  /*! fatfs_inode_t                                    */
    5051  KMEM_FATFS_CTX        = 11,  /*! fatfs_ctx_t                                      */
    51   KMEM_RAMFS_INODE      = 12,  /*  ramfs_inode_t                                    */
    52   KMEM_RAMFS_CTX        = 13,  /*! ramfs_ctx_t                                      */
     52  KMEM_DEVFS_INODE      = 12,  /*  devfs_inode_t                                    */
     53  KMEM_MUTEX            = 13,  /*! remote_mutex_t                                   */
    5354  KMEM_VFS_CTX          = 14,  /*! vfs_context_t                                    */
    5455  KMEM_VFS_INODE        = 15,  /*! vfs_inode_t                                      */
     
    5657  KMEM_VFS_FILE         = 17,  /*! vfs_file_t                                       */
    5758  KMEM_SEM              = 18,  /*! remote_sem_t                                     */
    58   KMEM_TBD_19           = 19,
     59  KMEM_CONDVAR          = 19,  /*! remote_condvar_t                                 */
    5960
    60   KMEM_TYPES_NR         = 20,
     61  KMEM_TYPES_NR         = 19,
    6162};
    6263
  • trunk/kernel/mm/mapper.c

    r18 r23  
    2626#include <hal_types.h>
    2727#include <hal_special.h>
     28#include <hal_uspace.h>
    2829#include <grdxt.h>
    2930#include <rwlock.h>
     
    108109        {
    109110            // remove page from mapper and release to PPM
    110                 error = mapper_release_page( mapper , found_index , page );
     111                error = mapper_release_page( mapper , page );
    111112
    112113            if ( error ) return error;
     
    148149
    149150    // test if page available in mapper
    150     if( ( page == NULL) || page_is_flag( page , PG_INLOAD ) )  // page not available            /
     151    if( ( page == NULL) || page_is_flag( page , PG_INLOAD ) )  // page not available
    151152    {
    152153        // release the lock in READ_MODE and take it in WRITE_MODE
     
    194195                printk("\n[ERROR] in %s : thread %x cannot insert page in mapper\n",
    195196                       __FUNCTION__ , this->trdid );
    196                 mapper_release_page( mapper , index , page );
     197                mapper_release_page( mapper , page );
    197198                page_clear_flag( page , PG_ALL );
    198199                req.ptr  = page;
     
    203204
    204205            // launch I/O operation to load page from file system
    205             error = mapper_updt_page( mapper , index , page );
     206            error = vfs_move_page_to_mapper( page );
    206207
    207208            if( error )
     
    209210                printk("\n[ERROR] in %s : thread %x cannot load page from device\n",
    210211                       __FUNCTION__ , this->trdid );
    211                 mapper_release_page( mapper , index , page );
     212                mapper_release_page( mapper , page );
    212213                page_clear_flag( page , PG_ALL );
    213214                req.ptr  = page;
     
    255256///////////////////////////////////////////////
    256257error_t mapper_release_page( mapper_t * mapper,
    257                              uint32_t   index,
    258258                             page_t   * page )
    259259{
     
    261261
    262262    // lauch IO operation to update page to file system
    263     error = mapper_sync_page( mapper , index , page );
     263    error = vfs_move_page_from_mapper( page );
    264264
    265265    if( error )
     
    288288}  // end mapper_release_page()
    289289
    290 ////////////////////////////////////////////
    291 error_t mapper_updt_page( mapper_t * mapper,
    292                           uint32_t   index,
    293                           page_t   * page )
    294 {
    295     uint32_t      type;
    296     vfs_inode_t * inode;
    297     error_t       error = 0;
    298 
    299     if( page == NULL )
    300     {
    301         printk("\n[PANIC] in %s : page pointer is NULL\n", __FUNCTION__ );
    302         hal_core_sleep();
    303     }
    304 
    305     if( mapper == NULL )
    306     {
    307         printk("\n[PANIC] in %s : no mapper for this page\n", __FUNCTION__ );
    308         hal_core_sleep();
    309     }
    310 
    311     // get file system type and inode pointer
    312     inode = mapper->inode;
    313     type  = inode->ctx->type;
    314 
    315     // get page lock
    316     page_lock( page );
    317 
    318     // get mapper lock in WRITE_MODE
    319     rwlock_wr_lock( &mapper->lock );
    320 
    321     // call proper I/O operation to update file system
    322     if     ( type == FS_TYPE_FATFS ) error = fatfs_read_page( page );
    323     else if( type == FS_TYPE_RAMFS ) error = ramfs_read_page( page );
    324     else
    325     {
    326         printk("\n[PANIC] in %s : undefined file system type\n", __FUNCTION__ );
    327         hal_core_sleep();
    328     }
    329 
    330     // release mapper lock from WRITE_MODE
    331     rwlock_wr_unlock( &mapper->lock );
    332 
    333     // release page lock
    334     page_unlock( page );
    335 
    336     if( error )
    337     {
    338         printk("\n[PANIC] in %s : cannot access file system\n", __FUNCTION__ );
    339         return EIO;
    340     }
    341 
    342     return 0;
    343 }  // end mapper_updt_page
    344 
    345 ////////////////////////////////////////////
    346 error_t mapper_sync_page( mapper_t * mapper,
    347                           uint32_t   index,
    348                           page_t   * page )
    349 {
    350     uint32_t      type;
    351     vfs_inode_t * inode;
    352     error_t       error = 0;
    353 
    354     if( page == NULL )
    355     {
    356         printk("\n[PANIC] in %s : page pointer is NULL\n", __FUNCTION__ );
    357         hal_core_sleep();
    358     }
    359 
    360     if( mapper == NULL )
    361     {
    362         printk("\n[PANIC] in %s : no mapper for this page\n", __FUNCTION__ );
    363         hal_core_sleep();
    364     }
    365 
    366         if( page_is_flag( page , PG_DIRTY ) )
    367         {
    368         // get file system type and inode pointer
    369         inode = mapper->inode;
    370         type  = inode->ctx->type;
    371 
    372         // get page lock
    373         page_lock( page );
    374 
    375         // get mapper lock in READ_MODE
    376         rwlock_rd_lock( &mapper->lock );
    377 
    378         // call proper I/O operation to update file system
    379         if     ( type == FS_TYPE_FATFS ) error = fatfs_write_page( page );
    380         else if( type == FS_TYPE_RAMFS ) error = ramfs_write_page( page );
    381         else
    382         {
    383             printk("\n[PANIC] in %s : undefined file system type\n", __FUNCTION__ );
    384             hal_core_sleep();
    385         }
    386 
    387         // release mapper lock from READ_MODE
    388         rwlock_rd_unlock( &mapper->lock );
    389 
    390         // release page lock
    391         page_unlock( page );
    392 
    393         if( error )
    394         {
    395             printk("\n[PANIC] in %s : cannot update file system\n", __FUNCTION__ );
    396             return EIO;
    397         }
    398 
    399         // clear dirty bit
    400                 page_undo_dirty( page );
    401      }
    402 
    403     return 0;
    404 
    405 }  // end mapper_sync_page()
    406 
    407 ///////////////////////////////////////////////////////////////////////////////////////
    408 // This static function is called by the mapper_move fragments() function.
    409 // It moves one fragment between an user buffer and the kernel mapper.
    410 // Implementation Note: It can require access to one or two pages in mapper:
    411 //  [max_page_index == min_page_index]     <=>  fragment fit in one mapper page
    412 //  [max_page index == min_page_index + 1] <=>  fragment spread on two mapper pages
    413 ///////////////////////////////////////////////////////////////////////////////////////
    414 static error_t mapper_move_one_fragment( mapper_t   * mapper,
    415                                          bool_t       to_buffer,
    416                                          fragment_t * fragment )
    417 {
    418     uint32_t   size;                 // number of bytes in fragment
    419     cxy_t      buf_cxy;              // cluster identifier for user buffer
    420     uint8_t  * buf_ptr;              // local pointer on first byte in user buffer
    421 
    422     xptr_t     xp_buf;               // extended pointer on byte in user buffer
    423     xptr_t     xp_map;               // extended pointer on byte in kernel mapper
    424 
    425     uint32_t   min_file_offset;      // offset of first byte in file
    426     uint32_t   max_file_offset;      // offset of last byte in file
    427 
    428     uint32_t   first_page_index;     // index of first page in mapper
    429     uint32_t   first_page_offset;    // offset of first byte in first page in mapper
    430     uint32_t   first_page_size;      // offset of first byte in first page in mapper
    431 
    432     uint32_t   second_page_index;    // index of last page in mapper
    433     uint32_t   second_page_offset;   // offset of last byte in last page in mapper
    434     uint32_t   second_page_size;     // offset of last byte in last page in mapper
    435 
    436     page_t   * page;                 // pointer on one page descriptor in mapper
    437     uint8_t  * map_ptr;              // local pointer on first byte in mapper
    438 
    439     // get fragment attributes in user buffer
    440     buf_cxy = fragment->buf_cxy;
    441     buf_ptr = fragment->buf_ptr;
    442     size    = fragment->size;
    443 
    444     if( size > CONFIG_PPM_PAGE_SIZE )
    445     {
    446         printk("\n[PANIC] in %s : illegal fragment size = %d\n",
    447                __FUNCTION__ , size );
    448         return EINVAL;
    449     }
     290/////////////////////////////////////////
     291error_t mapper_move( mapper_t  *  mapper,
     292                     bool_t       to_buffer,
     293                     uint32_t     file_offset,
     294                     void      *  buffer,
     295                     uint32_t     size )
     296{
     297    uint32_t   page_offset;    // first byte to move to/from a mapper page
     298    uint32_t   page_count;     // number of bytes to move to/from a mapper page
     299    uint32_t   index;          // current mapper page index
     300    uint32_t   done;           // number of moved bytes
     301    page_t   * page;           // current mapper page descriptor
     302    uint8_t  * map_ptr;        // current mapper  address
     303    uint8_t  * buf_ptr;        // current buffer  address
    450304
    451305    // compute offsets of first and last bytes in file
    452     min_file_offset = fragment->file_offset;
    453     max_file_offset = min_file_offset + size;
     306    uint32_t min_byte = file_offset;
     307    uint32_t max_byte = file_offset + size -1;
    454308
    455309    // compute indexes of pages for first and last byte in mapper
    456     first_page_index  = min_file_offset >> CONFIG_PPM_PAGE_SHIFT;
    457     second_page_index = max_file_offset >> CONFIG_PPM_PAGE_SHIFT;
    458 
    459     if ( first_page_index == second_page_index )  // only one page in mapper
    460     {
    461         // compute offset and size for page in mapper
    462         first_page_offset = min_file_offset & (1<<CONFIG_PPM_PAGE_SHIFT);
    463         first_page_size   = size;
    464 
    465         // get pointer on first page in mapper
    466         page = mapper_get_page( mapper , first_page_index );
     310    uint32_t first = min_byte >> CONFIG_PPM_PAGE_SHIFT;
     311    uint32_t last  = max_byte >> CONFIG_PPM_PAGE_SHIFT;
     312
     313    done = 0;
     314
     315    // loop on pages in mapper
     316    for( index = first ; index <= last ; index++ )
     317    {
     318        // compute page_offset
     319        if( index == first ) page_offset = min_byte & CONFIG_PPM_PAGE_MASK;
     320        else                 page_offset = 0;
     321
     322        // compute page_count
     323        if      ( first == last  ) page_count = size;
     324        else if ( index == first ) page_count = CONFIG_PPM_PAGE_SIZE - page_offset;
     325        else if ( index == last  ) page_count = (max_byte & CONFIG_PPM_PAGE_MASK) + 1;
     326        else                       page_count = CONFIG_PPM_PAGE_SIZE;
     327
     328        // get page descriptor
     329        page = mapper_get_page( mapper , index );
    467330
    468331        if ( page == NULL ) return EINVAL;
    469332
    470         // compute pointer on fragment first byte in mapper
    471         map_ptr = (uint8_t *)ppm_page2base( page ) + first_page_offset;
    472 
    473         // compute extended pointers in mapper and in buffer
    474         xp_map = XPTR( local_cxy , map_ptr );
    475         xp_buf = XPTR( buf_cxy , buf_ptr );
     333        // compute pointer in mapper
     334        map_ptr = (uint8_t *)ppm_page2base( page ) + page_offset;
     335
     336        // compute pointer in buffer
     337        buf_ptr = (uint8_t *)buffer + done;
    476338
    477339        // move fragment
    478340        if( to_buffer )
    479341        {
    480             hal_remote_memcpy( xp_buf , xp_map , first_page_size );
     342            hal_copy_to_uspace( buf_ptr , map_ptr , page_count );
    481343        }
    482344        else
    483345        {
    484346            page_do_dirty( page );
    485             hal_remote_memcpy( xp_map , xp_buf , first_page_size );
    486         }
    487     }
    488     else                                        // two pages in mapper
    489     {
    490         // compute offset and size for first page in mapper
    491         first_page_offset = min_file_offset & (1<<CONFIG_PPM_PAGE_SHIFT);
    492         first_page_size   = CONFIG_PPM_PAGE_SIZE - first_page_offset;
    493 
    494         // get pointer on first page descriptor in mapper
    495         page = mapper_get_page( mapper , first_page_index );
    496 
    497         if ( page == NULL ) return EINVAL;
    498 
    499         // compute local pointer on first byte in first page in mapper
    500         map_ptr = (uint8_t *)ppm_page2base(page) + first_page_offset;
    501 
    502         // compute extended pointers
    503         xp_map = XPTR( local_cxy , map_ptr );
    504         xp_buf = XPTR( buf_cxy , buf_ptr );
    505 
    506         // move fragment to/from first page
    507         if( to_buffer )
    508         {
    509             hal_remote_memcpy( xp_buf , xp_map , first_page_size );
    510         }
    511         else
    512         {
    513             page_do_dirty( page );
    514             hal_remote_memcpy( xp_map , xp_buf , first_page_size );
    515         }
    516 
    517         // compute offset and size for second page in mapper
    518         second_page_offset = 0;
    519         second_page_size   = size - first_page_size;
    520 
    521         // get pointer on second page in mapper
    522         page = mapper_get_page( mapper , second_page_index );
    523 
    524         if ( page == NULL ) return EINVAL;
    525 
    526         // compute local pointer on first byte in second page in mapper
    527         map_ptr = (uint8_t *)ppm_page2base( page ) + second_page_offset;
    528 
    529         // compute extended pointers
    530         xp_map = XPTR( local_cxy , map_ptr );
    531         xp_buf = XPTR( buf_cxy , buf_ptr + first_page_offset );
    532 
    533         // move fragment to/from second page
    534         if( to_buffer )
    535         {
    536             hal_remote_memcpy( xp_buf , xp_map , second_page_size );
    537         }
    538         else
    539         {
    540             page_do_dirty( page );
    541             hal_remote_memcpy( xp_map , xp_buf , second_page_size );
    542         }
     347            hal_copy_from_uspace( map_ptr , buf_ptr , page_count );
     348        }
     349
     350        done += page_count;
    543351    }
    544352
    545353    return 0;
    546 }  // end mapper_move_one_fragment()
    547 
    548 /////////////////////////////////////////////////
    549 error_t mapper_move_fragments( mapper_t * mapper,
    550                                bool_t     read,
    551                                uint32_t   nb_frags,
    552                                xptr_t     xp_frags )
    553 {
    554         uint32_t     index;
    555         error_t      error;
    556     fragment_t   local_frags[CONFIG_MAPPER_MAX_FRAGMENTS];   // local copy of fragments array
    557     fragment_t * frags_array;                                // pointer on fragments array
    558 
    559     // check nb_frags
    560     if( nb_frags > CONFIG_MAPPER_MAX_FRAGMENTS )
    561     {
    562         printk("\n[PANIC] in %s : number of fragments cannot be larger than %d\n",
    563                __FUNCTION__ , CONFIG_MAPPER_MAX_FRAGMENTS );
    564         return EINVAL;
    565     }
    566 
    567     // get client cluster and local pointer on fragments array
    568     cxy_t        client_cxy   = GET_CXY( xp_frags );
    569     fragment_t * client_frags = (fragment_t *)GET_PTR( xp_frags );
    570 
    571     if ( local_cxy == client_cxy ) // use the local fragments array if possible
    572     {
    573         frags_array = client_frags;
    574     }
    575     else                           // make a local copy of fragments array
    576     {
    577         hal_remote_memcpy( XPTR( local_cxy , local_frags ) , xp_frags ,
    578                            sizeof(fragment_t) * nb_frags );
    579         frags_array = local_frags;
    580     }
    581 
    582     // loop on fragments
    583     for( index = 0 ; index < nb_frags ; index ++ )
    584     {
    585         error = mapper_move_one_fragment( mapper , read , &frags_array[index] );
    586         if ( error ) return error;
    587     }
    588 
    589     return 0;
    590 
    591 }  // end mapper_move_fragments()
    592 
    593 
     354
     355}  // end mapper_move()
     356
     357
     358
  • trunk/kernel/mm/mapper.h

    r18 r23  
    3939/*******************************************************************************************
    4040 * The mapper implements the kernel cache for a given file or directory.
    41  * There is one mapper per file. It is implemented as a three levels radix tree,
     41 * There is one mapper per file/dir. It is implemented as a three levels radix tree,
    4242 * entirely stored in the same cluster as the inode representing the file/dir.
    4343 * - The fast retrieval key is the page index in the file.
     
    4949 * - The mapper is protected by a blocking "rwlock", to support several simultaneous
    5050 *   readers, and only one writer. This lock implement a busy waiting policy.
    51  * - The two functions mapper_sync_page() and mapper_updt_page() define the generic API
    52  *   used to move pages to or from the relevant file system on IOC device.
    53  * - the mapper_move fragments() function is used to move data to or from a distributed
    54  *   user buffer.
     51 * - The two functions vfs_move_page_to_mapper() and vfs_move_page_from_mapper() define
     52 *   the generic API used to move pages to or from the relevant file system on IOC device.
     53 * - the mapper_move() function is used to move data to or from a, possibly distributed
     54 *   user buffer in user space.
    5555 * - The mapper_get_page() function that return a page descriptor pointer from a page
    5656 *   index in file is in charge of handling the miss on the mapper cache.
    5757 * - In the present implementation the cache size increases on demand, and the
    58  *   allocated memory is only released when the mapper is destroyed.
     58 *   allocated memory is only released when the mapper/inode is destroyed.
    5959 ******************************************************************************************/
    6060
     
    6666typedef struct mapper_s
    6767{
    68         struct vfs_inode_s * inode;           /*! owner file inode                                */
     68        struct vfs_inode_s * inode;           /*! owner inode                                     */
    6969        grdxt_t              radix;           /*! pages cache implemented as a radix tree         */
    7070        rwlock_t             lock;        /*! several readers / only one writer               */
     
    8989    uint32_t    size;                /*! number of bytes in fragment                      */
    9090    cxy_t       buf_cxy;             /*! user buffer cluster identifier                   */
    91     uint8_t   * buf_ptr;             /*! local pointer on first byte in user buffer       */
     91    void      * buf_ptr;             /*! local pointer on first byte in user buffer       */
    9292}
    9393fragment_t;
     
    114114
    115115/*******************************************************************************************
    116  * This function moves all fragments covering a distributed user buffer between
    117  * a mapper (associated to a local inode), and the user buffer.
    118  * [See the fragment definition in the mapper.h file]
    119  * It must be executed by a thread running in the cluster containing the mapper.
    120  * The lock protecting the mapper must have been taken in WRITE_MODE or READ_MODE
    121  * by the caller thread, depending on the transfer direction.
     116 * This function move data between a kernel mapper and an user buffer.
     117 * It must be called by a thread running in the cluster containing the mapper.
     118 * It split the data in fragments : one fragment is a set of contiguous bytes
     119 * stored in the same mapper page. 
     120 * It uses "hal_uspace" accesses to move fragments to/from the user buffer.
    122121 * In case of write, the dirty bit is set for all pages written in the mapper.
    123122 * The offset in the file descriptor is not modified by this function.
    124  * Implementation note:
    125  * For each fragment, this function makes ONE hal_remote_memcpy() when the fragment is
    126  * fully contained in one single page of the mapper. It makes TWO hal_remote_memcpy()
    127  * if the fragment spread on two contiguous pages in the mapper.
    128123 *******************************************************************************************
    129  * @ mapper    : local pointer on the local mapper.
    130  * @ to_buffer : mapper to buffer if true / buffer to mapper if false.
    131  * @ nb_frags  : number of fragments covering the user buffer (one per page).
    132  * @ frags_xp  : extended pointer on array of fragments.
    133 FAT * returns O if success / returns EINVAL if error.
     124 * @ mapper       : extended pointer on local mapper.
     125 * @ to_buffer    : move data from mapper to buffer if true.
     126 * @ file_offset  : first byte to move in file.
     127 * @ buffer       : buffer address in user space.
     128 * @ size         : number of bytes to move.
     129 * returns O if success / returns EINVAL if error.
    134130 ******************************************************************************************/
    135 error_t mapper_move_fragments( mapper_t * mapper,
    136                                bool_t     to_buffer,
    137                                uint32_t   nb_frags,
    138                                xptr_t     frags_xp );
    139 
     131error_t mapper_move( mapper_t * mapper,
     132                     bool_t     to_buffer,
     133                     uint32_t   file_offset,
     134                     void     * buffer,
     135                     uint32_t   size );
    140136
    141137/*******************************************************************************************
     
    146142 *******************************************************************************************
    147143 * @ mapper     : local pointer on the mapper.
    148  * @ index      : page index in file
    149144 * @ page       : pointer on page to remove.
    150145 * @ return 0 if success / return EIO if a dirty page cannot be copied to FS.
    151146 ******************************************************************************************/
    152147error_t mapper_release_page( mapper_t      * mapper,
    153                              uint32_t        index,
    154148                             struct page_s * page );
    155149
     
    167161                                 uint32_t   index );
    168162
    169 /*******************************************************************************************
    170  * This function makes an I/O operation to move one page from FS to mapper.
    171  * Depending on the file system type, it calls the proper, FS specific function.
    172  * It must be executed by a thread running in the cluster containing the mapper.
    173  *******************************************************************************************
    174  * @ mapper     : local pointer on the mapper.
    175  * @ index      : page index in file.
    176  * @ page   : local pointer on the page descriptor in mapper.
    177  * @ returns 0 if success / return EINVAL if it cannot access the device.
    178  ******************************************************************************************/
    179 error_t mapper_updt_page( mapper_t      * mapper,
    180                           uint32_t        index,
    181                           struct page_s * page );
    182 
    183 /*******************************************************************************************
    184  * This function makes an I/0 operation to move one page from mapper to FS.
    185  * Depending on the file system type, it calls the proper, FS specific function.
    186  * It must be executed by a thread running in the cluster containing the mapper.
    187  * It does nothing if the page is not dirty. If the page is dirty, it takes
    188  * the page lock before launching the IO operation, clear the page dirty bit,
    189  * and remove the page from the PPM dirty list. It does nothing if the page is not dirty.
    190  *******************************************************************************************
    191  * @ mapper     : local pointer on the mapper.
    192  * @ index      : page index in file.
    193  * @ page   : local pointer on the page descriptor in mapper.
    194  * @ returns 0 if success / return EINVAL if it cannot access the device.
    195  ******************************************************************************************/
    196 error_t mapper_sync_page( mapper_t      * mapper,
    197                           uint32_t        index,
    198                           struct page_s * page );
     163 
    199164
    200165#endif /* _MAPPER_H_ */
  • trunk/kernel/mm/page.c

    r22 r23  
    33 *
    44 * Authors  Ghassan Almaless (2008,2009,2010,2011,2012)
    5  *          Alain Greiner    (2016)
     5 *          Alain Greiner    (2016,2017)
    66 *
    77 * Copyright (c) UPMC Sorbonne Universites
     
    4444        page->flags    = 0;
    4545        page->order    = 0;
     46        page->mapper   = NULL;
    4647        page->index    = 0;
    47         page->mapper   = NULL;
    48         page->private  = 0;
     48        page->fork_nr  = 0;
    4949        page->refcount = 0;
     50
    5051        spinlock_init( &page->lock );
    5152        list_entry_init( &page->list );
     53    xlist_root_init( XPTR( local_cxy , &page->wait_root ) );
    5254}
    5355
    5456////////////////////////////////////////////
    5557inline void page_set_flag( page_t   * page,
    56                            uint16_t   value )
     58                           uint32_t   value )
    5759{
    5860        hal_atomic_or( (uint32_t *)&page->flags , (uint32_t)value );
     
    6163//////////////////////////////////////////////
    6264inline void page_clear_flag( page_t   * page,
    63                              uint16_t   value )
     65                             uint32_t   value )
    6466{
    6567        hal_atomic_and( (uint32_t *)&page->flags , ~((uint32_t)value) );
     
    6870//////////////////////////////////////////////
    6971inline bool_t page_is_flag( page_t   * page,
    70                             uint16_t   value )
    71 {
    72         return (bool_t)(page->flags & value);
     72                            uint32_t   value )
     73{
     74    return ( (page->flags & value) ? 1 : 0 );
    7375}
    7476
     
    150152
    151153                // sync the page
    152                 mapper_sync_page( mapper , index , page );
     154                vfs_move_page_from_mapper( page );
    153155
    154156                // unlock the page
     
    226228inline void page_refcount_up( page_t *page )
    227229{
    228         hal_atomic_inc( &page->refcount );
     230    hal_atomic_add( &page->refcount , +1 );
    229231}
    230232
     
    232234inline void page_refcount_down( page_t *page )
    233235{
    234         hal_atomic_dec( &page->refcount );
     236    hal_atomic_add( &page->refcount , -1 );
    235237}
    236238
  • trunk/kernel/mm/page.h

    r22 r23  
    4949#define PG_DIRTY            0x0040     // page has been written
    5050#define PG_LOCKED       0x0080     // page is locked
     51#define PG_COW          0x0100     // page is copy-on-write
    5152
    5253#define PG_ALL          0xFFFF     // All flags
     
    5455/*************************************************************************************
    5556 * This structure defines a physical page descriptor.
    56  * Size is 60 bytes for a 32 bits core...
     57 * Size is 64 bytes for a 32 bits core...
    5758 ************************************************************************************/
    5859
    5960typedef struct page_s
    6061{
    61     uint16_t          flags;          /*! flags defined above                  (2)  */
    62     uint16_t          order;          /*! log2( number of 4Kbytes pages)       (2)  */
    63 
     62    uint32_t          flags;          /*! flags defined above                  (4)  */
     63    uint32_t          order;          /*! log2( number of 4Kbytes pages)       (4)  */
    6464    struct mapper_s * mapper;         /*! local pointer on associated mapper   (4)  */
    6565    uint32_t          index;          /*! page index in mapper                 (4)  */
    66 
    67         union                             /*!                                      (4)  */
    68         {
    69                 uint32_t      private;        /*! TODO ??? [AG]                             */
    70                 void        * data;           /*! TODO ??? [AG]                             */
    71                 slist_entry_t root;           /*! TODO ??? [AG]                             */
    72         };
    73 
    7466        list_entry_t      list;           /*! for both dirty pages and free pages  (8)  */
    75 
    7667    xlist_entry_t     wait_root;      /*! root of list of waiting threads      (16) */
    77 
    7868        uint32_t          refcount;       /*! reference counter                    (4)  */
     69        uint32_t          fork_nr;        /*! number of forked processes           (4)  */
    7970        spinlock_t        lock;           /*! only used to set the PG_LOCKED flag  (16) */
    8071}
     
    8374/*************************************************************************************
    8475 * This function initializes one page descriptor.
     76 *************************************************************************************
    8577 * @ page    : pointer to page descriptor
    8678 ************************************************************************************/
     
    8880
    8981/*************************************************************************************
    90  * This function sets one or several flags in page descriptor flags.
     82 * This function atomically set one or several flags in page descriptor flags.
     83 *************************************************************************************
    9184 * @ page    : pointer to page descriptor.
    9285 * @ value   : all non zero bits in value will be set.
    9386 ************************************************************************************/
    9487inline void page_set_flag( page_t   * page,
    95                            uint16_t   value );
     88                           uint32_t   value );
    9689
    9790/*************************************************************************************
    98  * This function clears one or several flags in page descriptor flags.
     91 * This function atomically reset one or several flags in page descriptor flags.
     92 *************************************************************************************
    9993 * @ page    : pointer to page descriptor.
    10094 * @ value   : all non zero bits in value will be cleared.
    10195 ************************************************************************************/
    10296inline void page_clear_flag( page_t   * page,
    103                              uint16_t   value );
     97                             uint32_t   value );
    10498
    10599/*************************************************************************************
    106100 * This function tests the value of one or several flags in page descriptor flags.
     101 *************************************************************************************
    107102 * @ page    : pointer to page descriptor.
    108103 * @ value   : all non zero bits will be tested.
     
    110105 ************************************************************************************/
    111106inline bool_t page_is_flag( page_t   * page,
    112                             uint16_t   value );
     107                            uint32_t   value );
    113108
    114109/*************************************************************************************
     
    121116 * This function sets the PG_DIRTY flag in the page descriptor,
    122117 * and registers the page in the dirty list in PPM.
     118 *************************************************************************************
    123119 * @ page     : pointer on page descriptor.
    124120 * @ returns true if page was not dirty / returns false if page was dirty
     
    129125 * This function resets the PG_DIRTY flag in the page descriptor,
    130126 * and removes the page from the dirty list in PPM.
     127 *************************************************************************************
    131128 * @ page     : pointer on page descriptor.
    132129 * @ returns true if page was dirty / returns false if page was not dirty
     
    136133/*************************************************************************************
    137134 * This function makes a local copy of the content of a src page to a dst page.
     135 *************************************************************************************
    138136 * @ dst      : pointer on destination page descriptor.
    139137 * @ src      : pointer on source page descriptor.
     
    144142/*************************************************************************************
    145143 * This function resets to 0 all bytes in a given page.
     144 *************************************************************************************
    146145 * @ page     : pointer on page descriptor.
    147146 ************************************************************************************/
     
    152151 * It deschedule if the page has already been locked by another thread,
    153152 * and returns only when the flag has been successfully set.
     153 *************************************************************************************
    154154 * @ page     : pointer on page descriptor.
    155155 ************************************************************************************/
     
    160160 * other waiting thread. If there is waiting thread(s), it activates the first
    161161 * waiting thread without modifying the PG_LOCKED flag.
     162 *************************************************************************************
    162163 * @ page     : pointer on page descriptor.
    163164 ************************************************************************************/
     
    166167/*************************************************************************************
    167168 * This blocking function atomically increments the page refcount.
     169 *************************************************************************************
    168170 * @ page     : pointer on page descriptor.
    169171 ************************************************************************************/
     
    172174/*************************************************************************************
    173175 * This blocking function atomically decrements the page refcount.
     176 *************************************************************************************
    174177 * @ page     : pointer on page descriptor.
    175178 ************************************************************************************/
     
    178181/*************************************************************************************
    179182 * This function display the values contained in a page descriptor.
     183 *************************************************************************************
     184 * @ page     : pointer on page descriptor.
    180185 ************************************************************************************/
    181186void page_print( page_t * page );
  • trunk/kernel/mm/vmm.c

    r21 r23  
    2929#include <hal_gpt.h>
    3030#include <printk.h>
     31#include <memcpy.h>
    3132#include <rwlock.h>
    3233#include <list.h>
     
    9495
    9596    // initialize local list of vsegs and radix-tree
     97    vmm->vsegs_nr = 0;
    9698        list_root_init( &vmm->vsegs_root );
    97     vmm->vsegs_nr = 0;
    9899    error = grdxt_init( &vmm->grdxt,
    99100                        CONFIG_VMM_GRDXT_W1,
     
    182183
    183184}  // end vmm_init()
     185
     186//////////////////////////////////////////
     187error_t vmm_copy( process_t * dst_process,
     188                  process_t * src_process )
     189{
     190    error_t error;
     191
     192    vmm_t * src_vmm = &src_process->vmm;
     193    vmm_t * dst_vmm = &dst_process->vmm;
     194
     195    // take the src_vmm vsegs_lock
     196    rwlock_wr_lock( &src_vmm->vsegs_lock );
     197
     198    // initialise dst_vmm vsegs_lock
     199    rwlock_init( &dst_vmm->vsegs_lock );
     200
     201    // initialise the dst_vmm vsegs list and the radix tree
     202    dst_vmm->vsegs_nr = 0;
     203    list_root_init( &dst_vmm->vsegs_root );
     204    error = grdxt_init( &dst_vmm->grdxt,
     205                        CONFIG_VMM_GRDXT_W1,
     206                        CONFIG_VMM_GRDXT_W2,
     207                        CONFIG_VMM_GRDXT_W3 );
     208    if( error )
     209    {
     210        printk("\n[ERROR] in %s : cannot initialise radix tree for process %x\n",
     211               __FUNCTION__ , dst_process->pid );
     212        return ENOMEM;
     213    }
     214
     215    // loop on src_vmm list of vsegs to create
     216    // and register vsegs copies in dst_vmm
     217    list_entry_t * iter;
     218    vseg_t       * src_vseg;
     219    vseg_t       * dst_vseg;
     220    LIST_FOREACH( &src_vmm->vsegs_root , iter )
     221    {
     222        // get pointer on current src_vseg
     223        src_vseg = LIST_ELEMENT( iter , vseg_t , list );
     224
     225        // allocate memory for a new dst_vseg
     226        dst_vseg = vseg_alloc();
     227
     228        if( dst_vseg == NULL )
     229        {
     230            // release all allocated vsegs
     231            LIST_FOREACH( &dst_vmm->vsegs_root , iter )
     232            {
     233                dst_vseg = LIST_ELEMENT( iter , vseg_t , list );
     234                vseg_free( dst_vseg );
     235            }
     236            return ENOMEM;
     237        }
     238
     239        // copy src_vseg to dst_vseg
     240        vseg_init_from_ref( dst_vseg , XPTR( local_cxy , src_vseg ) );
     241
     242        // register dst_vseg in dst_vmm
     243        vseg_attach( dst_vmm , dst_vseg );
     244    }
     245
     246    // release the src_vmm vsegs_lock
     247    rwlock_wr_unlock( &src_vmm->vsegs_lock );
     248
     249    // initialize generic page table
     250    error = hal_gpt_create( &dst_vmm->gpt );
     251
     252    if( error )
     253    {
     254        printk("\n[ERROR] in %s : cannot initialize page table\n", __FUNCTION__ );
     255        return ENOMEM;
     256    }
     257
     258    // initialize STACK allocator
     259    dst_vmm->stack_mgr.bitmap   = 0;
     260    dst_vmm->stack_mgr.vpn_base = CONFIG_VMM_STACK_BASE;
     261
     262    // initialize MMAP allocator
     263    dst_vmm->mmap_mgr.vpn_base        = CONFIG_VMM_MMAP_BASE;
     264    dst_vmm->mmap_mgr.vpn_size        = CONFIG_VMM_STACK_BASE - CONFIG_VMM_MMAP_BASE;
     265    dst_vmm->mmap_mgr.first_free_vpn  = CONFIG_VMM_MMAP_BASE;
     266    uint32_t i;
     267    for( i = 0 ; i < 32 ; i++ ) list_root_init( &dst_vmm->mmap_mgr.zombi_list[i] );
     268
     269    // initialise instrumentation counters
     270        dst_vmm->pgfault_nr    = 0;
     271        dst_vmm->u_err_nr      = 0;
     272        dst_vmm->m_err_nr      = 0;
     273
     274    // copy base addresses
     275    dst_vmm->kent_vpn_base = src_vmm->kent_vpn_base;
     276    dst_vmm->args_vpn_base = src_vmm->args_vpn_base;
     277    dst_vmm->envs_vpn_base = src_vmm->envs_vpn_base;
     278    dst_vmm->heap_vpn_base = src_vmm->heap_vpn_base;
     279    dst_vmm->code_vpn_base = src_vmm->code_vpn_base;
     280    dst_vmm->data_vpn_base = src_vmm->data_vpn_base;
     281
     282    dst_vmm->entry_point   = src_vmm->entry_point;
     283
     284    // HEAP TODO : new heap for child ???
     285    dst_vmm->heap_vseg     = src_vmm->heap_vseg;
     286
     287    // initialize generic page table
     288    error = hal_gpt_create( &dst_vmm->gpt );
     289
     290    if( error )
     291    {
     292        printk("\n[ERROR] in %s : cannot initialize page table\n", __FUNCTION__ );
     293        return ENOMEM;
     294    }
     295
     296    // copy GPT content from src_vmm to dst_vmm, activating "Copy-On-Write"
     297    // TODO register Copy-On_Write in page descriptors
     298    bool_t cow = true;
     299    hal_gpt_copy( &dst_vmm->gpt , &src_vmm->gpt , cow );
     300
     301    hal_wbflush();
     302
     303    return 0;
     304
     305}  // end vmm_copy()
    184306
    185307///////////////////////////////////////
     
    659781    error_t   error;
    660782
    661     // this function must be called by in the reference cluster
    662     if( process->is_ref == false );
     783    // this function must be called by a thread running in the reference cluster
     784    if( GET_CXY( process->ref_xp ) != local_cxy );
    663785    {
    664786        printk("\n[PANIC] in %s : not called in the reference cluster\n", __FUNCTION__ );
     
    796918                           paddr_t * paddr )
    797919{
    798     uint32_t vaddr = (uint32_t)ptr;
    799 
    800     thread_t  * this    = CURRENT_THREAD;
    801     process_t * process = this->process;
     920    process_t * process = CURRENT_THREAD->process;
    802921
    803922    if( ident )  // identity mapping
    804923    {
    805         *paddr = (paddr_t)PADDR( local_cxy , vaddr );
     924        *paddr = (paddr_t)PADDR( local_cxy , (lpa_t)ptr );
    806925        return 0;
    807926    }
     
    814933    uint32_t offset;
    815934
    816     vpn    = (vpn_t)( vaddr >> CONFIG_PPM_PAGE_SHIFT );
    817     offset = (uint32_t)( vaddr & CONFIG_PPM_PAGE_MASK );
    818 
    819     if( process->is_ref )   // calling process is reference process
     935    vpn    = (vpn_t)( (intptr_t)ptr >> CONFIG_PPM_PAGE_SHIFT );
     936    offset = (uint32_t)( ((intptr_t)ptr) & CONFIG_PPM_PAGE_MASK );
     937
     938    if( local_cxy == GET_CXY( process->ref_xp) )   // calling process is reference process
    820939    {
    821940        error = vmm_get_pte( process, vpn , &attr , &ppn );
    822941    }
    823     else                    // use a RPC
     942    else                                           // use a RPC
    824943    {
    825944        cxy_t       ref_cxy = GET_CXY( process->ref_xp );
     
    828947    }
    829948
    830     if( error )
    831     {
    832         printk("\n[ERROR] in %s : cannot get physical address for vaddr = %x\n",
    833                __FUNCTION__ , vaddr );
    834         return error;
    835     }
    836 
    837     // return paddr
     949    // set paddr
    838950    *paddr = (((paddr_t)ppn) << CONFIG_PPM_PAGE_SHIFT) | offset;
    839     return 0;
     951
     952    return error;
    840953
    841954}  // end vmm_v2p_translate()
     955
     956//////////////////////////////////////////////
    842957
    843958
  • trunk/kernel/mm/vmm.h

    r18 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
     
    103103        rwlock_t       vsegs_lock;         /*! lock protecting the vsegs list & radix tree      */
    104104        list_entry_t   vsegs_root;         /*! all vsegs in same process and same cluster       */
    105         uint32_t       vsegs_nr;           /*! total number of vsegs                            */
    106 
     105        uint32_t       vsegs_nr;           /*! total number of local vsegs                      */
    107106        grdxt_t        grdxt;              /*! embedded generic vsegs radix tree (key is vpn)   */
    108107
     
    110109
    111110    stack_mgr_t    stack_mgr;          /*! embedded STACK vsegs allocator                   */
    112 
    113111    mmap_mgr_t     mmap_mgr;           /*! embedded MMAP vsegs allocator                    */
    114112
     
    158156
    159157/*********************************************************************************************
     158 * This function copies the content of a source VMM to a destination VMM.
     159 *********************************************************************************************
     160 * @ dst_process   : pointer on destination process descriptor.
     161 * @ src_process   : pointer on source process descriptor.
     162 * @ return 0 if success / return ENOMEM if failure.
     163 ********************************************************************************************/
     164error_t vmm_copy( struct process_s * dst_process,
     165                  struct process_s * src_process );
     166
     167/*********************************************************************************************
    160168 * This function removes all vsegs registered in in a virtual memory manager,
    161169 * and releases the memory allocated to the local generic page table.
    162170 *********************************************************************************************
    163  * @ vmm   : pointer on process descriptor.
     171 * @ process   : pointer on process descriptor.
    164172 ********************************************************************************************/
    165173void vmm_destroy( struct process_s * process );
     
    265273
    266274/*********************************************************************************************
    267  * This function is called by the architecture specific exception handler when a
    268  * page fault has been detected in a given cluster.
     275 * This function is called by the generic exception handler when a page fault
     276 * has been detected in a given cluster.
    269277 * If the local cluster is not the reference cluster, it send a RPC_VMM_GET_PTE
    270278 * to the reference cluster to get the missing PTE attributes and PPN, and update
     
    305313 * This function makes the virtual to physical address translation, using the calling
    306314 * process page table. It uses identity mapping if required by the ident flag.
    307  * This address translation is required to configure the devices
    308  * that have a DMA capability, or to implement the software L2/L3 cache cohérence,
    309  * using the MMC device synchronisation primitives.
    310  * WARNING : the <ident> value must be defined by the CONFIG_KERNEL_IDENT parameter.
     315 * This address translation is required to configure the peripherals having a DMA
     316 * capability, or to implement the software L2/L3 cache cohérence, using the MMC device
     317 * synchronisation primitives.
     318 * WARNING : the <ident> value must be defined by the CONFIG_KERNEL_IDENTITY_MAP parameter.
    311319 *********************************************************************************************
    312320 * @ ident     : [in] uses identity mapping if true.
     
    321329
    322330/*********************************************************************************************
    323  * Pas a sa place ici [AG]
    324  ********************************************************************************************/
    325 int sys_mmap( mmap_attr_t * mattr );
    326 
    327 /*********************************************************************************************
    328331 ********************************************************************************************/
    329332int sys_madvise( void    * start,
  • trunk/kernel/syscalls/sys_alarm.c

    r1 r23  
    11/*
    2  * kern/sys_alarm.c - timed sleep/wakeup
     2 * sys_alarm.c - timed sleep/wakeup
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * Author    Alain Greiner (2016,2017)
     5*
     6 * Copyright (c) UPMC Sorbonne Universites
    67 *
    7  * This file is part of ALMOS-kernel.
     8 * This file is part of ALMOS-MKH.
    89 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1718 *
    1819 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2021 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2122 */
    2223
    23 #include <types.h>
     24#include <hal_types.h>
    2425#include <thread.h>
     26#include <printk.h>
    2527#include <cluster.h>
    26 #include <task.h>
    27 #include <time.h>
     28#include <process.h>
    2829#include <scheduler.h>
    29 #include <cpu.h>
    30 #include <cpu-trace.h>
     30#include <core.h>
    3131
    32 EVENT_HANDLER(sys_alarm_event_handler)
     32////////////////////////////////
     33int sys_alarm( uint64_t cycles )
    3334{
    34         struct thread_s *thread;
     35    thread_t  * this    = CURRENT_THREAD;
     36    process_t * process = this->process;
    3537
    36         thread = event_get_argument(event);
    37         sched_wakeup(thread);
    38         return 0;
    39 }
    40 
    41 int sys_alarm (unsigned nb_sec)
    42 {
    43         struct thread_s *this;
    44         struct event_s event;
    45         struct alarm_info_s info;
    46 
    47         if( nb_sec == 0)
    48                 return 0;
    49 
    50         this = current_thread;
    51         event_set_handler(&event, &sys_alarm_event_handler);
    52         event_set_priority(&event, E_FUNC);
    53         event_set_argument(&event,this);
    54         info.event = &event;
    55 
    56         alarm_wait(&info, nb_sec * 4);
    57         sched_sleep(this);
    58         return 0;
     38    printk("\n[ERROR] in %s for thread %x in process %x : not implemented yet\n",
     39           __FUNCTION__ , this->trdid , process->pid );
     40    this->errno = EFAULT;
     41    return -1;
    5942}
    6043
    6144
     45
  • trunk/kernel/syscalls/sys_barrier.c

    r1 r23  
    11/*
    2  * kern/sys_barrier.c - barrier service interface for userland
     2 * sys_barrier.c - Access a POSIX barrier.
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * authors       Alain Greiner (2016,2017)
    65 *
    7  * This file is part of ALMOS-kernel.
     6 * Copyright (c) UPMC Sorbonne Universites
    87 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     8 * This file is part of ALMOS-MKH.
     9 *
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1718 *
    1819 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2021 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2122 */
    2223
    23 #include <types.h>
     24#include <hal_types.h>
     25#include <hal_special.h>
    2426#include <errno.h>
    2527#include <thread.h>
    26 #include <task.h>
    27 #include <kmem.h>
     28#include <printk.h>
    2829#include <vmm.h>
    29 #include <kmagics.h>
    30 #include <barrier.h>
     30#include <syscalls.h>
     31#include <remote_barrier.h>
    3132
    32 int sys_barrier(struct barrier_s **barrier, uint_t operation, uint_t count)
     33//////////////////////////////////
     34int sys_barrier( void     * vaddr,
     35                 uint32_t   operation,
     36                 uint32_t   count )
    3337{
    34         kmem_req_t req;
    35         struct barrier_s *ibarrier;
    36         error_t err = EINVAL;
     38        error_t      error;
     39    paddr_t      paddr;
    3740 
    38         if((err = vmm_check_address("usr barrier ptr",
    39                                     current_task,
    40                                     barrier,
    41                                     sizeof(struct barrier_s*))))
    42                 goto SYS_BARRIER_END;
     41    thread_t   * this = CURRENT_THREAD;
    4342
    44         if((err = cpu_copy_from_uspace(&ibarrier, barrier, sizeof(struct barrier_s *))))
    45                 goto SYS_BARRIER_END;
     43    // check vaddr in user vspace
     44        error = vmm_v2p_translate( false , vaddr , &paddr );
     45        if( error )
     46    {
     47        printk("\n[ERROR] in %s : illegal barrier virtual address = %x\n",
     48               __FUNCTION__ , (intptr_t)vaddr );
     49        this->errno = error;
     50        return -1;
     51    }
    4652
    47         switch(operation)
     53    // execute requested operation
     54        switch( operation )
    4855        {
    49         case BARRIER_INIT_PRIVATE:
    50         case BARRIER_INIT_SHARED:
    51                 req.type  = KMEM_BARRIER;
    52                 req.size  = sizeof(*ibarrier);
    53                 req.flags = AF_USER;
     56        //////////////////
     57            case BARRIER_INIT:
     58        {
     59            error = remote_barrier_create( (intptr_t)vaddr , count );
     60   
     61                    if( error )
     62            {
     63                printk("\n[ERROR] in %s : cannot create barrier = %x\n",
     64                       __FUNCTION__ , (intptr_t)vaddr );
     65                this->errno = error;
     66                return -1;
     67            }
     68                        break;
     69        }
     70        //////////////////
     71            case BARRIER_WAIT:
     72        {
     73            xptr_t barrier_xp = remote_barrier_from_ident( (intptr_t)vaddr );
    5474
    55                 if((ibarrier = kmem_alloc(&req)) == NULL)
    56                 {
    57                         err = ENOMEM;
    58                         break;
    59                 }
    60    
    61                 if((err = barrier_init(ibarrier, count, operation)))
    62                         break;
    63    
    64                 if((err = cpu_copy_to_uspace(barrier, &ibarrier, sizeof(struct barrier_s *))))
    65                 {
    66                         req.ptr = ibarrier;
    67                         kmem_free(&req);
    68                 }
    69                 break;
     75            if( barrier_xp == XPTR_NULL )     // user error
     76            {
     77                printk("\n[ERROR] in %s : barrier %x not registered\n",
     78                       __FUNCTION__ , (intptr_t)vaddr );
     79                this->errno = EINVAL;
     80                return -1;
     81            }
     82            else                          // success
     83            {
     84                remote_barrier_wait( barrier_xp );
     85            }
     86            break;
     87        }
     88        /////////////////////
     89            case BARRIER_DESTROY:
     90        {
     91            xptr_t barrier_xp = remote_barrier_from_ident( (intptr_t)vaddr );
    7092
    71         case BARRIER_WAIT:
     93            if( barrier_xp == XPTR_NULL )     // user error
     94            {
     95                printk("\n[ERROR] in %s : barrier %x not registered\n",
     96                       __FUNCTION__ , (intptr_t)vaddr );
     97                this->errno = EINVAL;
     98                return -1;
     99            }
     100            else                          // success
     101            {
     102                remote_barrier_destroy( barrier_xp );
     103            }
     104            break;
     105        }
     106        ////////
     107            default:
     108        {
     109            printk("\n[PANIC] in %s : illegal operation type\n", __FUNCTION__ );
     110            hal_core_sleep();
     111        }
     112        }  // end switch
    72113
    73                 if((err = vmm_check_object(ibarrier, struct barrier_s, BARRIER_ID)))
    74                         break;
     114        return 0;
    75115
    76                 err = barrier_wait(ibarrier);
    77                 break;
     116}  // end sys_barrier()
    78117
    79         case BARRIER_DESTROY:
    80    
    81                 if((err = vmm_check_object(ibarrier, struct barrier_s, BARRIER_ID)))
    82                         break;
    83    
    84                 if((err = barrier_destroy(ibarrier)))
    85                         break;
    86    
    87                 req.type = KMEM_BARRIER;
    88                 req.ptr  = ibarrier;
    89                 kmem_free(&req);
    90                 return 0;
    91 
    92         default:
    93                 err = EINVAL;
    94         }
    95 
    96 SYS_BARRIER_END:
    97         current_thread->info.errno = err;
    98         return err;
    99 }
    100 
    101 KMEM_OBJATTR_INIT(barrier_kmem_init)
    102 {
    103         attr->type   = KMEM_BARRIER;
    104         attr->name   = "KCM Barrier";
    105         attr->size   = sizeof(struct barrier_s);
    106         attr->aligne = 0;
    107         attr->min    = CONFIG_BARRIER_MIN;
    108         attr->max    = CONFIG_BARRIER_MAX;
    109         attr->ctor   = NULL;
    110         attr->dtor   = NULL;
    111         return 0;
    112 }
  • trunk/kernel/syscalls/sys_chdir.c

    r11 r23  
    11/*
    2  * sys_chdir: change process current work directory
     2 * sys_chdir: change process current working directory
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
     4 * Author    Alain Greiner (2016,2017)
     5 *
    56 * Copyright (c) 2011,2012 UPMC Sorbonne Universites
    67 *
    7  * This file is part of ALMOS-kernel.
     8 * This file is part of ALMOS-MKH.
    89 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1718 *
    1819 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2021 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2122 */
    2223
    23 #include <cpu.h>
     24#include <hal_types.h>
     25#include <hal_uspace.h>
    2426#include <chdev.h>
    25 #include <driver.h>
    2627#include <rwlock.h>
    2728#include <vfs.h>
    28 #include <sys-vfs.h>
     29#include <errno.h>
    2930#include <thread.h>
    30 #include <ku_transfert.h>
    31 #include <task.h>
     31#include <printk.h>
     32#include <process.h>
    3233
    33 int sys_chdir (char *pathname)
     34/////////////////////////////////
     35int sys_chdir ( char * pathname )
    3436{
    35         register error_t err = 0;
    36         register struct thread_s *this;
    37         register struct task_s *task;
    38         struct ku_obj ku_path;
     37        error_t   error;
     38    paddr_t   paddr;
     39    uint32_t  length;
     40    char      kbuf[CONFIG_VFS_MAX_PATH_LENGTH];
    3941
    40         this = current_thread;
    41         task = current_task;
     42        thread_t  * this    = CURRENT_THREAD;
     43    process_t * process = this->process;
    4244
    43         if(!pathname)
     45    // check pathname in user space
     46    error = vmm_v2p_translate( false , pathname , &paddr );
     47
     48        if( error )
    4449        {
    45                 this->info.errno = EINVAL;
     50        printk("\n[ERROR] in %s : user buffer unmapped  for thread %x in process %x\n",
     51               __FUNCTION__ , this->trdid , process->pid );
     52                this->errno = EINVAL;
    4653                return -1;
    4754        }       
    4855     
    49         KU_BUFF(ku_path, pathname);
    50         rwlock_wrlock(&task->cwd_lock);
     56    // get pathname length
     57    length = hal_strlen_from_uspace( pathname );
     58
     59    if( length >= CONFIG_VFS_MAX_PATH_LENGTH )
     60    {
     61        printk("\n[ERROR] in %s : pathname too long for thread %x in process %x\n",
     62               __FUNCTION__ , this->trdid , process->pid );
     63                this->errno = ENFILE;
     64        return -1;
     65    }
     66 
     67        // get pathname copy in kernel space
     68    hal_copy_from_uspace( kbuf, pathname, length );
     69
     70    // get cluster and local pointer on reference process
     71    xptr_t      ref_xp  = process->ref_xp;
     72    process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
     73    cxy_t       ref_cxy = GET_CXY( ref_xp );
     74
     75    // get extended pointer on cwd lock in reference process
     76    xptr_t lock_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
    5177       
    52         if((err = vfs_chdir(&ku_path, &task->vfs_cwd)))
     78    // get cwd lock in read mode
     79        remote_rwlock_rd_lock( lock_xp );
     80
     81    // call relevant VFS function
     82        error = vfs_chdir( process->vfs_cwd_xp , kbuf );
     83
     84    // release cwd lock
     85        remote_rwlock_rd_unlock( lock_xp );
     86
     87        if( error )
    5388        {
    54                 rwlock_unlock(&task->cwd_lock);
    55                 this->info.errno = (err < 0) ? -err : err;
     89        printk("\n[ERROR] in %s : cannot change current directory\n", __FUNCTION__ );
     90                this->errno = error;
    5691                return -1;
    5792        }
    5893   
    59         rwlock_unlock(&task->cwd_lock);
    6094        return 0;
    6195}
  • trunk/kernel/syscalls/sys_chmod.c

    r11 r23  
    11/*
    2  * sys_chmod: change file mode
     2 * sys_chmod.c - Change file access rights.
    33 *
     4 * Author    Alain Greiner  (2016,2017)
     5 *
    46 * Copyright (c) 2015 UPMC Sorbonne Universites
    57 *
    6  * This file is part of ALMOS-kernel.
     8 * This file is part of ALMOS-MKH.
    79 *
    8  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    911 * under the terms of the GNU General Public License as published by
    1012 * the Free Software Foundation; version 2.0 of the License.
    1113 *
    12  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1315 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1416 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1618 *
    1719 * You should have received a copy of the GNU General Public License
    18  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    1921 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2022 */
    2123
    22 #include <cpu.h>
    23 #include <chdev.h>
    24 #include <driver.h>
    25 #include <rwlock.h>
     24#include <hal_types.h>
     25#include <hal_uspace.h>
    2626#include <vfs.h>
    27 #include <sys-vfs.h>
     27#include <vmm.h>
     28#include <printk.h>
    2829#include <thread.h>
    29 #include <ku_transfert.h>
    30 #include <task.h>
     30#include <process.h>
    3131
    32 int sys_chmod (char *pathname, uint_t mode)
     32//////////////////////////////////
     33int sys_chmod( char    * pathname,
     34               uint32_t  rights )
    3335{
    34         register error_t err = 0;
    35         register struct thread_s *this;
    36         register struct task_s *task;
    37         struct ku_obj ku_path;
     36    error_t     error;
     37    paddr_t     paddr;
     38    uint32_t    length;
     39    char        kbuf[CONFIG_VFS_MAX_PATH_LENGTH];
     40       
     41        thread_t  * this    = CURRENT_THREAD;
     42        process_t * process = this->process;
    3843
    39         this = current_thread;
    40         task = current_task;
     44    // check pathname in user space
     45    error = vmm_v2p_translate( false , pathname , &paddr );
    4146
    42         if(!pathname || NOT_IN_USPACE(pathname))
     47        if( error )
    4348        {
    44                 this->info.errno = EINVAL;
     49        printk("\n[ERROR] in %s : user pathname unmapped for thread %x in process %x\n",
     50               __FUNCTION__ , this->trdid , process->pid );
     51                this->errno = EINVAL;
    4552                return -1;
    4653        }       
    47        
    48      
    49         KU_BUFF(ku_path, pathname);
    50         rwlock_wrlock(&task->cwd_lock);
    51        
    52         if((err = vfs_chmod(&ku_path, &task->vfs_cwd, mode)))
     54
     55    // get pathname length
     56    length = hal_strlen_from_uspace( pathname );
     57
     58    if( length >= CONFIG_VFS_MAX_PATH_LENGTH )
     59    {
     60        printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ );
     61                this->errno = ENFILE;
     62        return -1;
     63    }
     64 
     65        // get pathname copy in kernel space
     66    hal_copy_from_uspace( kbuf, pathname, length );
     67
     68    // get cluster and local pointer on reference process
     69    xptr_t      ref_xp  = process->ref_xp;
     70    process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
     71    cxy_t       ref_cxy = GET_CXY( ref_xp );
     72
     73    // get extended pointer on cwd inode
     74    xptr_t cwd_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->vfs_cwd_xp ) );
     75   
     76    // get the cwd lock in read mode from reference process
     77        remote_rwlock_rd_lock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
     78
     79    // call the relevant VFS function
     80        error = vfs_chmod( cwd_xp,
     81                       kbuf,
     82                       rights );
     83
     84    // release the cwd lock
     85        remote_rwlock_rd_unlock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
     86
     87    if( error )
    5388        {
    54                 rwlock_unlock(&task->cwd_lock);
    55                 this->info.errno = (err < 0) ? -err : err;
     89        printk("\n[ERROR] in %s : cannot remove directory %s\n",
     90               __FUNCTION__ , kbuf );
     91                this->errno = error;
    5692                return -1;
    5793        }
    5894   
    59         rwlock_unlock(&task->cwd_lock);
    6095        return 0;
    61 }
     96
     97}  // end sys_chmod()   
  • trunk/kernel/syscalls/sys_clock.c

    r1 r23  
    11/*
    2  * sys_clock: get system current time
     2 * sys_clock: get calling core cycles count
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * Author    Alain Greiner (2016,2017)
     5 * 
     6 * Copyright (c) UPMC Sorbonne Universites
    67 *
    7  * This file is part of ALMOS-kernel.
     8 * This file is part of ALMOS-MKH.
    89 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1718 *
    1819 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2021 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2122 */
    2223
     24#include <hal_types.h>
     25#include <hal_uspace.h>
    2326#include <errno.h>
    24 #include <config.h>
    25 #include <cpu.h>
     27#include <core.h>
    2628#include <thread.h>
     29#include <process.h>
     30#include <vmm.h>
     31#include <printk.h>
    2732
    28 int sys_clock(uint64_t *val)
     33//////////////////////////////////
     34int sys_clock (uint64_t * cycles )
    2935{
    30         error_t err;
    31         uint64_t cycles;
     36        error_t   error;
     37    paddr_t   paddr;
     38        uint64_t  k_cycles;
    3239
    33         if((val == NULL) || NOT_IN_USPACE((uint_t)val))
     40    thread_t  * this    = CURRENT_THREAD;
     41    process_t * process = this->process;
     42
     43    // check buffer in user space
     44    error = vmm_v2p_translate( false , cycles , &paddr );
     45
     46        if( error )
    3447        {
    35                 err = EINVAL;
    36                 goto fail_inval;
     48        printk("\n[ERROR] in %s : user buffer unmapped for thread %x in process %x\n",
     49               __FUNCTION__ , this->trdid , process->pid );
     50        this->errno = EFAULT;
     51                return -1;
    3752        }
    3853
    39         cycles = cpu_get_cycles(current_cpu);
    40         err    = cpu_copy_to_uspace(val, &cycles, sizeof(cycles));
     54    // call relevant core function
     55        k_cycles = core_get_cycles( this->core );
    4156
    42 fail_inval:
    43         current_thread->info.errno = err;
    44         return err;
    45 }
     57    // copy to user space
     58        hal_copy_to_uspace( cycles , &k_cycles , sizeof(uint64_t) );
     59
     60        return 0;
     61
     62}  // end sys_clock()
  • trunk/kernel/syscalls/sys_close.c

    r11 r23  
    11/*
    2  * sys_close.c  close a process open file
     2 * sys_close.c  close an open file
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * Author    Alain Greiner (2016,2017)
    65 *
    7  * This file is part of ALMOS-kernel.
     6 * Copyright (c) UPMC Sorbonne Universites
    87 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     8 * This file is part of ALMOS-MKH.
     9 *
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1718 *
    1819 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2021 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2122 */
    2223
    23 #include <cpu.h>
    24 #include <chdev.h>
    25 #include <driver.h>
     24#include <kernel_config.h>
     25#include <hal_types.h>
     26#include <hal_special.h>
    2627#include <vfs.h>
    27 #include <sys-vfs.h>
    2828#include <process.h>
    2929#include <thread.h>
    30 #include <config.h>
     30#include <printk.h>
    3131
    32 /////////////////////////////
    33 int sys_close ( uint32_t fd )
     32//////////////////////////////////
     33int sys_close ( uint32_t file_id )
    3434{
    35         register process_t * process = current_process;
    36         register thread_t  * this    = current_thread;
    37         struct vfs_file_s  * file    = NULL;
    38         error_t              err;
    39  
    40         if(( fd >= CONFIG_TASK_FILE_MAX_NR ) || (process_fd_lookup( process , fd , &file )))
     35    error_t     error;
     36    xptr_t      file_xp;
     37
     38        thread_t  * this    = CURRENT_THREAD;
     39        process_t * process = this->process;
     40
     41    // check file_id argument
     42        if( file_id >= CONFIG_PROCESS_FILE_MAX_NR )
    4143        {
    42                 this->info.errno = EBADFD;
     44        printk("\n[ERROR] in %s : illegal file descriptor index = %d\n",
     45               __FUNCTION__ , file_id );
     46                this->errno = EBADFD;
    4347                return -1;
    4448        }
    4549
    46         err = vfs_close( file , NULL );
    47         if( err )
     50    // get extended pointer on remote file descriptor
     51    file_xp = process_fd_get_xptr( process , file_id );
     52
     53    if( file_xp == XPTR_NULL )
     54    {
     55        printk("\n[ERROR] in %s : undefined file descriptor = %d\n",
     56               __FUNCTION__ , file_id );
     57                this->errno = EBADFD;
     58                return -1;
     59    }
     60
     61    // call the relevant VFS function
     62        error = vfs_close( file_xp , file_id );
     63
     64        if( error )
    4865        {
    49                 this->info.errno = err;
     66        printk("\n[ERROR] in %s : cannot close file descriptor = %d\n",
     67               __FUNCTION__ , file_id );
     68                this->errno = error;
    5069                return -1;
    5170        }
    5271
    53         process_fd_release( process , fd );
    54         cpu_wbflush();
     72        hal_wbflush();
     73
    5574        return 0;
    5675}
  • trunk/kernel/syscalls/sys_closedir.c

    r1 r23  
    11/*
    2  * sys_closedir.c close a process open directory
     2 * sys_closedir.c - Close an open directory.
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * Author    Alain Greiner  (2016, 2017)
    65 *
    7  * This file is part of ALMOS-kernel.
     6 * Copyright (c) UPMC Sorbonne Universites
    87 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     8 * This file is part of ALMOS-MKH.
     9 *
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1718 *
    1819 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2021 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2122 */
    2223
     24#include <hal_types.h>
    2325#include <vfs.h>
    24 #include <sys-vfs.h>
    2526#include <thread.h>
     27#include <printk.h>
    2628#include <process.h>
    2729
    28 ////////////////////////////////
    29 int sys_closedir ( uint32_t fd )
     30/////////////////////////////////////
     31int sys_closedir ( uint32_t file_id )
    3032{
    31         register thread_t  * this    = current-thread;
    32         register process_t * process = current_process;
    33         struct vfs_file_s  * file    = NULL;
    34         error_t              err;
     33        error_t        error;
     34        xptr_t         file_xp;   // extended pointer on searched directory file descriptor
    3535
    36         if(( fd >= CONFIG_TASK_FILE_MAX_NR ) || (process_fd_lookup( process , fd , &file )))
     36        thread_t     * this     = CURRENT_THREAD;
     37        process_t    * process  = this->process;
     38
     39    // check file_id argument
     40        if( file_id >= CONFIG_PROCESS_FILE_MAX_NR )
    3741        {
    38                 this->info.errno = EBADFD;
     42        printk("\n[ERROR] in %s : illegal file descriptor index %d\n",
     43               __FUNCTION__ , file_id );
     44        this->errno = EBADFD;
    3945                return -1;
    4046        }
    4147
    42         err  = vfs_closedir( file , NULL );
    43         if(err)
     48    // get extended pointer on remote file descriptor
     49    file_xp = process_fd_get_xptr( process , file_id );
     50
     51    if( file_xp == XPTR_NULL )
     52    {
     53        printk("\n[ERROR] in %s : undefined file descriptor index = %d\n",
     54               __FUNCTION__ , file_id );
     55                this->errno = EBADFD;
     56                return -1;
     57    }
     58
     59    // call relevant VFS function
     60        error  = vfs_close( file_xp , file_id );
     61
     62        if( error )
    4463        {
    45                 this->info.errno = (err < 0) ? -err : err;
     64        printk("\n[ERROR] in %s : cannot close the directory = %d\n",
     65               __FUNCTION__ , file_id );
     66                this->errno = error;
    4667                return -1;
    4768        }
    4869
    49         process_fd_release( process , fd );
    5070        return 0;
    51 }
     71
     72}  // end sys_closedir()
  • trunk/kernel/syscalls/sys_condvar.c

    r15 r23  
    11/*
    2  * sys_cond_var: interface to access condition vraibles service
     2 * sys_condvar.c - Access a POSIX condvar.
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * Author    Alain Greiner  (2016,2017)
    65 *
    7  * This file is part of ALMOS-kernel.
     6 * Copyright (c) UPMC Sorbonne Universites
    87 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     8 * This file is part of ALMOS-MKH.
     9 *
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1718 *
    1819 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2021 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2122 */
    2223
    23 #include <types.h>
     24#include <hal_types.h>
     25#include <hal_special.h>
    2426#include <errno.h>
    2527#include <thread.h>
    26 #include <kmem.h>
    27 #include <task.h>
     28#include <printk.h>
    2829#include <vmm.h>
    29 #include <kmagics.h>
    30 #include <semaphore.h>
    31 #include <cond_var.h>
     30#include <syscalls.h>
     31#include <remote_condvar.h>
    3232
    33 static inline bool_t isBadSem(struct semaphore_s *sem)
    34 {
    35         return vmm_check_object(sem, struct semaphore_s, SEMAPHORE_ID);
    36 }
     33////////////////////////////////////////
     34int sys_condvar( void         * condvar,
     35                 uint32_t       operation,
     36                 void         * mutex )
     37{
     38        error_t    error;
     39    paddr_t    paddr;
     40 
     41    thread_t * this = CURRENT_THREAD;
    3742
    38 static inline bool_t isBadCV(struct cv_s *cv)
    39 {
    40         return vmm_check_object(cv, struct cv_s, COND_VAR_ID);
    41 }
     43    // check condvar in user vspace
     44        error = vmm_v2p_translate( false , condvar , &paddr );
     45        if( error )
     46    {
     47        printk("\n[ERROR] in %s : illegal condvar virtual address = %x\n",
     48               __FUNCTION__ , (intptr_t)condvar );
     49        this->errno = error;
     50        return -1;
     51    }
    4252
    43 int sys_cond_var(struct cv_s **cv, uint_t operation, struct semaphore_s **sem)
    44 {
    45         kmem_req_t req;
    46         struct cv_s *icv;
    47         struct semaphore_s *isem;
    48         error_t err = EINVAL;
    49  
    50         if((err = vmm_check_address("usr cv ptr", current_task,cv,sizeof(struct cv_s*))))
    51                 goto SYS_COND_END;
     53    // execute requested operation
     54        switch( operation )
     55        {
     56        //////////////////
     57        case CONDVAR_INIT:
     58        {
     59            error = remote_condvar_create( (intptr_t)condvar );
     60   
     61                    if( error )
     62            {
     63                printk("\n[ERROR] in %s : cannot create condvar = %x\n",
     64                       __FUNCTION__ , (intptr_t)condvar );
     65                this->errno = error;
     66                return -1;
     67            }
     68                    break;
     69        }
     70        //////////////////
     71            case CONDVAR_WAIT:
     72        {
     73            // check mutex in user vspace
     74                error = vmm_v2p_translate( false , mutex , &paddr );
    5275
    53         if((err = cpu_copy_from_uspace(&icv, cv, sizeof(struct cv_s *))))
    54                 goto SYS_COND_END;
     76                if( error )
     77            {
     78                printk("\n[ERROR] in %s : illegal condvar virtual address = %x\n",
     79                       __FUNCTION__ , (intptr_t)condvar );
     80                this->errno = error;
     81                return -1;
     82            }
    5583
    56         switch(operation)
    57         {
    58         case CV_INIT:
    59                 req.type  = KMEM_CV;
    60                 req.size  = sizeof(*icv);
    61                 req.flags = AF_USER;
     84            xptr_t condvar_xp = remote_condvar_from_ident( (intptr_t)condvar );
     85
     86            if( condvar_xp == XPTR_NULL )     // user error
     87            {
     88                printk("\n[ERROR] in %s : condvar %x not registered\n",
     89                       __FUNCTION__ , (intptr_t)condvar );
     90                this->errno = EINVAL;
     91                return -1;
     92            }
    6293   
    63                 if((icv = kmem_alloc(&req)) == NULL)
    64                 {
    65                         err = ENOMEM;
    66                         break;
     94            xptr_t mutex_xp = remote_condvar_from_ident( (intptr_t)condvar );
     95            if( mutex_xp == XPTR_NULL )     // user error
     96            {
     97                printk("\n[ERROR] in %s : mutex %x not registered\n",
     98                       __FUNCTION__ , (intptr_t)condvar );
     99                this->errno = EINVAL;
     100                return -1;
     101            }
     102
     103            remote_condvar_wait( condvar_xp , mutex_xp );
     104
     105            break;
     106        }
     107        ////////////////////
     108            case CONDVAR_SIGNAL:
     109        {
     110            xptr_t condvar_xp = remote_condvar_from_ident( (intptr_t)condvar );
     111
     112            if( condvar_xp == XPTR_NULL )     // user error
     113            {
     114                printk("\n[ERROR] in %s : condvar %x not registered\n",
     115                       __FUNCTION__ , (intptr_t)condvar );
     116                this->errno = EINVAL;
     117                return -1;
     118            }
     119
     120            remote_condvar_signal( condvar_xp );
     121           
     122            break;
     123        }
     124        ///////////////////////
     125            case CONDVAR_BROADCAST:
     126        {
     127            xptr_t condvar_xp = remote_condvar_from_ident( (intptr_t)condvar );
     128
     129            if( condvar_xp == XPTR_NULL )     // user error
     130            {
     131                printk("\n[ERROR] in %s : condvar %x not registered\n",
     132                       __FUNCTION__ , (intptr_t)condvar );
     133                this->errno = EINVAL;
     134                return -1;
     135            }
     136
     137            remote_condvar_broadcast( condvar_xp );
     138
     139            break;
     140        }
     141        /////////////////////
     142            case CONDVAR_DESTROY:
     143        {
     144            xptr_t condvar_xp = remote_condvar_from_ident( (intptr_t)condvar );
     145
     146            if( condvar_xp == XPTR_NULL )     // user error
     147            {
     148                printk("\n[ERROR] in %s : condvar %x not registered\n",
     149                       __FUNCTION__ , (intptr_t)condvar );
     150                this->errno = EINVAL;
     151                return -1;
     152            }
     153
     154            remote_condvar_destroy( condvar_xp );
     155
     156            break;
    67157                }
    68    
    69                 if((err = cv_init(icv)))
    70                         break;
    71    
    72                 if((err = cpu_copy_to_uspace(cv, &icv, sizeof(struct cv_s *))))
    73                 {
    74                         req.ptr = icv;
    75                         kmem_free(&req);
    76                 }
     158        /////////
     159            default:
     160        {
     161            printk("\n[PANIC] in %s : illegal operation type\n", __FUNCTION__ );
     162            hal_core_sleep();
     163        }
     164        }   // end switch
    77165
    78                 break;
     166        return 0;
    79167
    80         case CV_WAIT:
    81                 err = vmm_check_address("usr sem ptr",
    82                                         current_task,
    83                                         sem, sizeof(struct semaphore_s*));
     168}  // enc sys_condvar()
    84169
    85                 if(err) break;
    86 
    87                 if((err = cpu_copy_from_uspace(&isem, sem, sizeof(struct semaphore_s *))))
    88                         break;
    89 
    90                 if(isBadSem(isem))
    91                         break;
    92 
    93                 if(isBadCV(icv))
    94                         break;
    95    
    96                 return cv_wait(icv, isem);
    97 
    98         case CV_SIGNAL:
    99                 if(isBadCV(icv))
    100                         break;
    101    
    102                 return cv_signal(icv);
    103 
    104         case CV_BROADCAST:
    105                 if(isBadCV(icv))
    106                         break;
    107    
    108                 return cv_broadcast(icv);
    109 
    110         case CV_DESTROY:
    111                 if(isBadCV(icv))
    112                         break;
    113    
    114                 if((err = cv_destroy(icv)))
    115                         break;
    116    
    117                 req.type = KMEM_CV;
    118                 req.ptr  = icv;
    119                 kmem_free(&req);
    120                 return 0;
    121 
    122         default:
    123                 err = EINVAL;
    124         }
    125 
    126 SYS_COND_END:
    127         current_thread->info.errno = err;
    128         return err;
    129 }
    130 
    131 KMEM_OBJATTR_INIT(cv_kmem_init)
    132 {
    133         attr->type   = KMEM_CV;
    134         attr->name   = "KCM Condition Variable";
    135         attr->size   = sizeof(struct cv_s);
    136         attr->aligne = 0;
    137         attr->min    = CONFIG_CONDTION_VAR_MIN;
    138         attr->max    = CONFIG_CONDTION_VAR_MAX;
    139         attr->ctor   = NULL;
    140         attr->dtor   = NULL;
    141  
    142         return 0;
    143 }
  • trunk/kernel/syscalls/sys_creat.c

    r1 r23  
    11/*
    2  * kern/sys_creat.c - create a file
     2 * sys_creat.c - create a file
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * Author    Alain Greiner (2016,2017)
     5 *
     6 * Copyright (c) UPMC Sorbonne Universites
    67 *
    78 * This file is part of ALMOS-kernel.
     
    2122 */
    2223
    23 #include <config.h>
     24#include <hal_types.h>
    2425#include <vfs.h>
    25 #include <sys-vfs.h>
    26 #include <spinlock.h>
    27 #include <process.h>
    28 #include <thread.h>
     26#include <syscalls.h>
    2927
    3028////////////////////////////////////
    31 int sys_creat ( char     * pathname,
    32                 uint32_t   mode )
     29int sys_creat( char     * pathname,
     30               uint32_t   mode )
    3331{
    34         CPU_HW_TRACE(sys_creat);
     32        uint32_t    flags = O_CREAT;
    3533
    36         register error_t     err;
    37         register uint32_t    flags;
    38         register thread_t  * this    = durrent_thread;
    39         register process_t * process = current_process;
    40         struct vfs_file_s    file;
    41         struct ku_obj        ku_path;
    42         uint32_t             fd      = (uint32_t)-1;
    43    
    44         if( process_fd_array_full( process ) )
    45         {
    46                 this->info.errno = ENFILE;
    47             CPU_HW_TRACE(sys_creat);
    48         return fd;
    49         }
    50 
    51         flags = 0;
    52         KU_BUFF( ku_path , pathname );
    53 
    54     // get the cwd lock
    55         rwlock_rdlock( &process->cwd_lock );
    56 
    57         err = vfs_create( &process->vfs_cwd , &ku_path , flags , mode , &file );
    58         if( err )
    59         {
    60                 this->info.errno = (err < 0 ) ? -err : err;
    61             rwlock_unlock( &process->cwd_lock );
    62             CPU_HW_TRACE(sys_creat);
    63             return fd;
    64         }
    65 
    66         err = process_fd_set( process , &file , &fd );
    67         if( err )
    68         {
    69                 vfs_close( &file , NULL );
    70                 this->info.errno = err;
    71         }
    72 
    73         rwlock_unlock( &process->cwd_lock );
    74         CPU_HW_TRACE(sys_creat);
    75         return fd;
     34    return sys_open( pathname , flags , mode );
    7635}
  • trunk/kernel/syscalls/sys_exec.c

    r14 r23  
    11/*
    2  * sys_exec.c - Kernel function implementing the "exec" syscall
     2 * sys_exec.c - Kernel function implementing the "exec" system call.
    33 *
    4  * Authors    Mohamed Lamine Karaoui (2015)
    5  *            Alain Greiner          (2016)
     4 * Authors   Alain Greiner (2016,2017)
    65 *
    76 * Copyright (c) UPMC Sorbonne Universites
     
    2524#include <kernel_config.h>
    2625#include <hal_types.h>
     26#include <hal_uspace.h>
    2727#include <errno.h>
    2828#include <printk.h>
     
    5151
    5252    // get string length
    53         hal_strlen_from_uspace( pathname , &length );
    54         if( length > 255 )
    55     {
    56         printk(ERROR, "%s: elf file pathname larger than 255 bytes\n", __FUNCTION__ );
    57         return EINVAL;
    58     }
     53        length = hal_strlen_from_uspace( pathname );
     54
     55        if( length >= CONFIG_VFS_MAX_PATH_LENGTH ) return EINVAL;
    5956
    6057    // copy string to exec_info
     
    7572// The max number of strings is 1024 (for both args and envs). The numbers of pages
    7673// to store the (args) and (envs) strings are configuration parameters.
    77 ////////////////////////////////////////////////i//////////////////////////////////////
     74///////////////////////////////////////////////////////////////////////////////////////
    7875// @ exec_info : pointer on the exec_info structure.
    7976// @ is_args   : true if called for (args) / false if called for (envs).
     
    8885    uint32_t     found_null;  // NULL pointer found in array of pointers
    8986    uint32_t     length;      // string length
    90     uint32_t     strings;     // actual number of strings
    9187    kmem_req_t   req;         // kmem request
    9288    page_t     * page;        // page descriptor
    9389    uint32_t     order;       // ln2( number of pages to store strings )
    94     char      ** k_pointers;  // base of kernel buffer containing array of pointers
    95     char       * buf_ptr;     // pointer on first empty slot in kernel strings buffer
    96     char       * buf_base;    // base address of the kernel strings buffer
     90    char      ** k_pointers;  // base of kernel array of pointers
     91    char       * k_buf_ptr;   // pointer on first empty slot in kernel strings buffer
     92    char       * k_buf_base;  // base address of the kernel strings buffer
    9793
    9894    // compute ln2( number of pages for kernel strings buffer )
    99     if( is_args ) order = CONFIG_PROCESS_ARGS_ORDER;
    100     else          order = CONFIG_PROCESS_ENVS_ORDER;
     95    if( is_args ) order = bits_log2( CONFIG_VMM_ARGS_SIZE );
     96    else          order = bits_log2( CONFIG_VMM_ENVS_SIZE );
    10197
    10298        req.type   = KMEM_PAGE;
     
    106102    req.type   = 0;
    107103    page       = kmem_alloc( &req );
    108     if( page == NULL )
    109     {
    110         printk("ERROR in %s : cannot allocate memory for pointers\n", __FUNCTION__ );
    111         return ENOMEM;
    112     }
     104
     105    if( page == NULL ) return ENOMEM;
     106
    113107    k_pointers = ppm_page2base( page );
    114108   
     
    116110    req.type   = order;
    117111    page       = kmem_alloc( &req );
    118     if( page == NULL )
    119     {
    120         printk("ERROR in %s : cannot allocate memory for strings\n", __FUNCTION__ );
    121         return ENOMEM;
    122     }
    123     buf_base    = ppm_page2base( page );
     112
     113    if( page == NULL ) return ENOMEM;
     114
     115    k_buf_base = ppm_page2base( page );
    124116   
    125117    // copy the array of pointers to kernel buffer
     
    128120                          CONFIG_PPM_PAGE_SIZE );
    129121
    130     // scan local copy of array of pointers to copy the strings
     122    // scan kernel array of pointers to copy the strings
    131123    found_null = 0;
    132     buf_ptr    = buf_base;
     124    k_buf_ptr  = k_buf_base;
    133125    for( index = 0 ; index < 1024 ; index++ )
    134126    {
     
    140132
    141133        // compute string length
    142             hal_strlen_from_uspace( k_pointers[index] , &length );
     134            length = hal_strlen_from_uspace( k_pointers[index] );
    143135 
    144136        // copy the user string to kernel buffer
    145         hal_copy_from_uspace( k_strings,
    146                               k_pointers[index];
     137        hal_copy_from_uspace( k_buf_ptr,
     138                              k_pointers[index],
    147139                              length );
    148140
    149141        // update k_pointer[index] entry
    150         k_pointers[index] = buf_ptr;
     142        k_pointers[index] = k_buf_ptr;
    151143
    152144        // increment pointer on kernel strings buffer
    153         buf_ptr += (length + 1);
     145        k_buf_ptr += (length + 1);
    154146    }
    155147
     
    158150    {
    159151        exec_info->args_pointers  =  k_pointers;
    160         exec_info->args_buf_base  =  buf_base;
     152        exec_info->args_buf_base  =  k_buf_base;
    161153        exec_info->args_nr        =  index;
    162154    }
     
    164156    {
    165157        exec_info->envs_pointers  =  k_pointers;
    166         exec_info->envs_buf_base  =  buf_base;
    167         exec_info->envs_buf_free  =  buf_ptr;
     158        exec_info->envs_buf_base  =  k_buf_base;
     159        exec_info->envs_buf_free  =  k_buf_ptr;
    168160        exec_info->envs_nr        =  index;
    169161    }
    170162    else
    171163    {
    172         printk("ERROR in %s : number of strings larger than 1024\n", __FUNCTION__ );
    173164        return EINVAL;
    174165    }
     
    177168} // end process_exec_get_strings()
    178169
    179 /////////////////////////////////////////////////////////////////////////////////////////
    180 // This function is executed in a "client" cluster by a process whose PID can belong
    181 // to another "server" cluster (defined by the MSB bits of the calling process PID).
    182 // A new process descriptor, and the associated main thread descriptor must be created
    183 // in the "server" cluster, using directly the process_make_exec() function if local,
    184 // or the rpc_process_exec_client() function if server is remote.
    185170/////////////////////////////////////////////////////////////////////////////////////////
    186171// Implementation note:
     
    189174// It calls the static process_exec_get_path() and process_exec_get_strings() functions
    190175// to copy the .elf pathname, the main() arguments and the environment variables from
    191 // user buffers to the exec_info_t, and calls the static process_make_exec() function.
     176// user buffers to the exec_info_t structure, and call the process_make_exec() function.
    192177/////////////////////////////////////////////////////////////////////////////////////////
    193178int sys_exec( char  * filename,     // .elf file pathname
    194               char ** argv,         // process arguments
    195               char ** envp )        // environment variables
     179              char ** args,         // process arguments
     180              char ** envs )        // environment variables
    196181{
    197182    exec_info_t  exec_info;         // structure to pass to process_make_exec()
    198     thread_t   * thread;            // pointer on thread created in server cluster
    199         error_t      error   = 0;
    200         process_t  * process = CURRENT_PROCESS;
    201 
    202     // check arguments
    203         if((filename == NULL) || (argv == NULL) || (envp == NULL))
    204     {
    205         printk("\n[ERROR] in %s : missing arguments / file = %x / argv = %x / envp = %x\n",
    206                __FUNCTION__ , filename , argv , envp );
    207         return EINVAL;
     183        error_t      error;
     184    paddr_t      paddr;
     185
     186    thread_t   * this    = CURRENT_THREAD;
     187        process_t  * process = this->process;
     188
     189    // check argument fileme
     190    error = vmm_v2p_translate( false , filename , &paddr );
     191
     192        if( error )
     193    {
     194        printk("\n[ERROR] in %s : filename unmapped\n", __FUNCTION__ );
     195        this->errno = EINVAL;
     196        return -1;
     197    }
     198
     199    // check argument fileme
     200    error = vmm_v2p_translate( false , args , &paddr );
     201
     202        if( error )
     203    {
     204        printk("\n[ERROR] in %s : args unmapped\n", __FUNCTION__ );
     205        this->errno = EINVAL;
     206        return -1;
     207    }
     208
     209    // check argument fileme
     210    error = vmm_v2p_translate( false , envs , &paddr );
     211
     212        if( error )
     213    {
     214        printk("\n[ERROR] in %s : envs unmapped\n", __FUNCTION__ );
     215        this->errno = EINVAL;
     216        return -1;
    208217    }
    209218
     
    218227                 cxy_client, cxy_server, hal_time_stamp());
    219228
    220     // Change process's state to prevent any concurent access TODO ??? [AG]
    221 
    222229    // initialize exec_info structure
    223     exec_info->pid      = process->pid;
    224     exec_info->ppid     = process->ppid;
    225     exec_info->fd_array = &process->fd_array;
    226     exec_info->vfs_root = &process->vfs_root;
    227     exec_info->vfs_cwd  = &process->vfs_cwd;
    228     exec_info->vfs_bin  = &process->vfs_bin;
     230    exec_info.pid         = process->pid;
     231    exec_info.ppid        = process->ppid;
     232    exec_info.fd_array_xp = XPTR( local_cxy , &process->fd_array );
     233    exec_info.vfs_root_xp = process->vfs_root_xp;
     234    exec_info.vfs_cwd_xp  = process->vfs_cwd_xp;
     235    exec_info.vfs_bin_xp  = process->vfs_bin_xp;
    229236
    230237        // check pathname and store it in exec_info structure
    231238        error = process_exec_get_path( &exec_info , filename );
    232         if ( error ) return EINVAL;
    233 
    234         // check and store argv in exec_info structure
    235         error = process_exec_get_strings( &exec_info , true , argv );
    236         if( error )  return EINVAL;
     239
     240        if ( error )
     241    {
     242        printk("\n[ERROR] in %s : elf pathname too long\n", __FUNCTION__ );
     243        this->errno = error;
     244        return -1;
     245    }
     246
     247        // check and store args in exec_info structure
     248        error = process_exec_get_strings( &exec_info , true , args );
     249
     250        if( error ) 
     251    {
     252        printk("\n[ERROR] in %s : cannot access args\n", __FUNCTION__ );
     253        this->errno = error;
     254        return -1;
     255    }
    237256       
    238         // check and store envp in exec_info structure
    239         error = process_exec_get_strings( &exec_info , false , envp );
    240         if( error )  return EINVAL;
     257        // check and store envs in exec_info structure
     258        error = process_exec_get_strings( &exec_info , false , envs );
     259
     260        if( error )
     261    {
     262        printk("\n[ERROR] in %s : cannot access envs\n", __FUNCTION__ );
     263        this->errno = error;
     264        return -1;
     265    }
    241266       
    242     if( is_local )  ////////////// local exec //////////////////////////
    243     {
    244         exec_dmsg("\n[INFO] %s starts local exec for process %x at cycle %d\n",
    245                   __FUNCTION__, process->pid, hal_time_stamp());
    246 
    247         // call directly the local process_make_exec() function
    248         error = process_make_exec( &exec_info , &thread );
    249         if error
    250         {
    251             printk("\n[ERROR] in %s : failed in local exec for process %x\n",
    252                    __FUNCTION__ , process->pid );
    253             return EINVAL;
    254         }
    255 
    256         exec_dmsg("\n[INFO] %s completes local exec for process %x at cycle %d\n",
    257                   __FUNCTION__, process->pid , hal_time_stamp() );
    258     }
    259     else             ///////////// remote exec /////////////////////////
    260     {
    261         exec_dmsg("\n[INFO] %s starts remote exec for process %x at cycle %d\n",
    262                   __FUNCTION__, process->pid, hal_time_stamp() );
    263 
    264         // call the rpc_process_exec_client() function   
    265         rpc_process_exec_client( cxy_server , &exec_info , &thread , &error );
    266 
    267         if( error )
    268         {
    269             printk("\n[ERROR] in %s : failed in remote exec for process %x\n",
    270                    __FUNCTION__ , process->pid );
    271             return EINVAL;
    272         }
    273 
    274         exec_dmsg("\n[INFO] %s completes remote exec for process %x at cycle %d\n",
    275                   __FUNCTION__, process->pid , hal_time_stamp() );
    276     }
    277 
    278     // If no error, delete the current thread an process descriptors.
     267    exec_dmsg("\n[INFO] %s starts exec for process %x at cycle %d\n",
     268              __FUNCTION__, process->pid, hal_time_stamp() );
     269
     270    if( is_local )  error = process_make_exec( &exec_info );
     271    else            rpc_process_exec_client( cxy_server , &exec_info , &error );
     272
     273    if( error )
     274    {
     275        printk("\n[ERROR] in %s : cannot create new process %x\n",
     276               __FUNCTION__ , process->pid );
     277        this->errno = error;
     278        return -1;
     279    }
     280
     281    exec_dmsg("\n[INFO] %s completes exec for process %x at cycle %d\n",
     282              __FUNCTION__, process->pid , hal_time_stamp() );
     283
     284    // delete the calling thread an process
    279285    thread_kill( CURRENT_THREAD );
    280     process_kill( CURRENT_PROCESS );
     286    process_kill( CURRENT_THREAD->process );
    281287
    282288    return 0;
     289
    283290} // end sys_exec()
    284291
  • trunk/kernel/syscalls/sys_fork.c

    r1 r23  
    11/*
    2  * sys_fork.c - fork the current process
     2 * sys_fork.c - Fork the current process.
    33 *
    4  * Authors  Ghassan Almaless (2008,2009,2010,2011,2012)
    5  *          Mohamed Lamine Karaoui (2015)
    6  *          Alain Greiner (2016)
     4 * Authors  Alain Greiner  (2016,2017)
    75 *
    86 * Copyright (c) UPMC Sorbonne Universites
     
    2422 */
    2523
     24#include <kernel_config.h>
     25#include <hal_types.h>
     26#include <hal_atomic.h>
    2627#include <errno.h>
    27 #include <config.h>
    28 #include <cpu.h>
     28#include <printk.h>
     29#include <core.h>
    2930#include <cluster.h>
    30 #include <event.h>
    3131#include <list.h>
    3232#include <thread.h>
     
    3636#include <process.h>
    3737
    38 #if CONFIG_FORK_DEBUG
    39 #define fork_debug(...) printk(__VA_ARGS__)
    40 #else
    41 #define fork_debug(...) /**/
    42 #endif
    43 
    44 /***********************************************************************************************
    45  * This kernel function implement the "fork" system call.
    46  * The calling process descriptor (parent process), and the associated thread descriptor are
    47  * replicated in the same cluster as the calling thread, but the new process (child process)
    48  * is registered in another target cluster, that will become the process owner.
    49  * The child process and the associated main thread will be migrated to the target cluster
    50  * later, when the child process makes an "exec" or any other system call.
    51  * The target cluster depends on the "fork_user" flag and "fork_cxy" variable that can be
    52  * stored in the calling thread descriptor by the specific fork_place() system call.
    53  * If not, the sys_fork() function makes a query to the DQDT to select the target cluster.
    54  * @ returns child process PID if success / returns -1 if failure
    55  **********************************************************************************************/
    56 int sys_fork();
     38//////////////
     39int sys_fork()
    5740{
    5841        process_t          * parent_process;  // pointer on parent process descriptor
     
    6346        thread_t           * child_thread;    // pointer on child main thread descriptor
    6447    trdid_t              child_trdid;     // child main thread identifier
    65     core_t             * child_core;      // pointer on core for child main thread
    6648    lid_t                child_core_lid;  // core local index for the child main thread
    6749    cxy_t                target_cxy;      // final target cluster for forked child process
    6850        error_t              error;
    6951
    70     cluster_t          * parent_cluster = LOCAL_CLUSTER;
    71 
    7252    // get pointers on parent process and thread
    7353        parent_thread  = CURRENT_THREAD;
    7454        parent_process = parent_thread->process;
     55    parent_pid     = parent_process->pid;
    7556
    7657    // check parent process children number
    77         if( hal_atomic_add( &parent_process->childs_nr , 1 ) >= CONFIG_PROCESS_CHILDS_MAX_NR )
    78         {
    79             printk("ERROR in %s : too much children processes\n", __FUNCTION__);
    80             hal_atomic_add ( &parent_process->childs_nr , -1 );
    81         return EAGAIN;
    82         }
    83 
    84         fork_debug("INFO : %s enters for process %d at cycle [%d]\n",
     58        if( hal_atomic_add( &parent_process->children_nr , 1 ) >= CONFIG_PROCESS_MAX_CHILDREN )
     59        {
     60            printk("\n[ERROR] in %s : too much children processes\n", __FUNCTION__);
     61            hal_atomic_add ( &parent_process->children_nr , -1 );
     62        return EAGAIN;
     63        }
     64
     65        fork_dmsg("\n[INFO] %s : enters for process %d at cycle [%d]\n",
    8566                  __FUNCTION__, parent_process->pid, hal_time_stamp());
    8667
     
    9071        {
    9172                hal_fpu_context_save( parent_thread );
    92                 fork_debug("INFO : %s save FPU\n", __FUNCTION__);
     73                fork_dmsg("\n[INFO] %s : save FPU\n", __FUNCTION__);
    9374        }
    9475
    9576    // Select target cluster for future migration of child process and main thread.
    96     // The placement can be specified by user. If placement is not user-defined,
    97     // the placement is defined by the DQDT.
    98     // The two first processes ("init" and "sh") on boot cluster will not migrate.
    99         if( parent_threads->fork_user )
     77    // If placement is not user-defined, the placement is defined by the DQDT.
     78    // The two first processes ("init" and "sh") on boot cluster do not migrate.
     79
     80        if( parent_thread->fork_user )
    10081        {
    10182        // user defined placement
    102         target_cxy = parent->thread.fork_cxy;
    103         parent->thread.fork_cxy = false;
    104         }
    105     else if( (LPID_FROM_PID(parent_process->pid) < 2 ) 
    106              && ( parent_cluster->cxy == parent_cluster->boot_cxy ) )
     83        target_cxy = parent_thread->fork_cxy;
     84        parent_thread->fork_user = false;
     85        }
     86    else if( (LPID_FROM_PID(parent_process->pid) < 2)  && (local_cxy == 0) )
    10787    {
    10888        // 2 first process stay in boot cluster
    109         target_cxy = parent_cluster->cxy;
     89        target_cxy = local_cxy;
    11090    }
    11191        else
     
    11595        }
    11696
    117         fork_debug("INFO : %s select target_cluster = %x\n",
     97        fork_dmsg("INFO : %s select target_cluster = %x\n",
    11898              __FUNCTION__ , target_cxy );
    11999
    120100    // allocates memory in local cluster for the child process descriptor
    121101        child_process = process_alloc();
     102
    122103        if( child_process == NULL )
    123104        {
    124             printk("ERROR in %s : cannot allocate memory for child process\n", __FUNCTION__ );
    125             hal_atomic_add ( &parent_process->childs_nr , -1 );
    126         return EAGAIN;
    127         }
    128 
    129     // get a new PID for child process
    130     // it requires an RPC if target cluster is remote
    131     xptr_t xp = XPTR( target_cxy , child_process );
    132     if( target_cxy == parent_cluster->cxy )   // local cluster
    133     {
    134         error = process_pid_alloc( xp , &child_pid );
    135     }
    136     else                            // remote cluster
    137     {
    138         rpc_process_pid_alloc_server( target_cxy , xp , &error , &child_pid );
    139     }
     105            printk("\n[ERROR] in %s : cannot allocate child process\n", __FUNCTION__ );
     106            hal_atomic_add ( &parent_process->children_nr , -1 );
     107        return EAGAIN;
     108        }
     109
     110    // get a new PID for child process,
     111    if( target_cxy == local_cxy )                // target cluster is local
     112    {
     113        error = cluster_pid_alloc( XPTR( target_cxy , child_process ) , &child_pid );
     114    }
     115    else                                         // target cluster is remote
     116    {
     117        rpc_process_pid_alloc_client( target_cxy , child_process , &error , &child_pid );
     118    }
     119
    140120    if( error )
    141121    {
    142             printk("ERROR in %s : cannot allocate PID\n", __FUNCTION__ );
    143             atomic_add ( &parent_process->childs_nr , -1 );
     122            printk("\n[ERROR] in %s : cannot allocate PID\n", __FUNCTION__ );
     123            hal_atomic_add ( &parent_process->children_nr , -1 );
    144124        process_destroy( child_process );
    145125        return EAGAIN;
     
    147127
    148128    // initialize and register the child process descriptor
    149     error = process_reference_init( child_process , child_pid , parent_pid );
    150     if( error )
    151     {
    152             printk("ERROR in %s : cannot initialise child process\n", __FUNCTION__ );
    153             atomic_add ( &parent_process->childs_nr , -1 );
    154         process_destroy( child_process );
    155         return EAGAIN;
    156     }
    157 
    158         fork_debug("INFO : %s created child process : pid = %x / ppid = %x\n",
     129    process_reference_init( child_process , child_pid , parent_pid );
     130
     131        fork_dmsg("\n[INFO] : %s created child process : pid = %x / ppid = %x\n",
    159132              __FUNCTION__, child_pid , parent_pid );
    160 
    161     // set IS_REFERENCE flag in child process descriptor
    162     child_process->flags = PDF_IS_REFERENCE;
    163133
    164134    // initialises child process standard files structures
    165135    // ( root / cwd / bin ) from parent process descriptor
    166         spinlock_lock( &parent_process->cwd_lock );
    167 
    168         vfs_file_count_up( &parent_process->vfs_root );
    169         child_process->vfs_root = parent_process->vfs_root;
    170 
    171         vfs_file_count_up( &parent_process->vfs_cwd );
    172         child_process->vfs_cwd  = parent_process->vfs_cwd;
    173 
    174         vfs_file_count_up( &parent_process->vfs_bin );
    175     child_process->vfs_bin = parent_process->vfs_bin;
    176 
    177         spinlock_unlock( &parent_process->cwd_lock );
     136
     137        vfs_file_count_up( parent_process->vfs_root_xp );
     138        child_process->vfs_root_xp = parent_process->vfs_root_xp;
     139
     140        vfs_file_count_up( parent_process->vfs_cwd_xp );
     141        child_process->vfs_cwd_xp  = parent_process->vfs_cwd_xp;
     142
     143        vfs_file_count_up( parent_process->vfs_bin_xp );
     144    child_process->vfs_bin_xp = parent_process->vfs_bin_xp;
     145
     146    // copy the parent process fd_array to the child process fd_array
     147        process_fd_remote_copy( XPTR( local_cxy , &child_process->fd_array ),
     148                            XPTR( local_cxy , &parent_process->fd_array ) );
     149
     150        fork_dmsg("\n[INFO] %s : duplicated child process from parent process\n",
     151                  __FUNCTION__ );
     152
     153    // replicates virtual memory manager
     154        error = vmm_copy( child_process , parent_process );
     155
     156        if( error )
     157    {
     158            printk("\n[ERROR] in %s : cannot duplicate VMM\n", __FUNCTION__ );
     159            hal_atomic_add ( &parent_process->children_nr , -1 );
     160        process_destroy( child_process );
     161        return ENOMEM;
     162    }
    178163 
    179     // copy the parent process fd_array to the child process fd_array
    180         process_fd_fork( child_process , parent_process );
    181 
    182     // initialise child process signal manager TODO ???
    183         signal_manager_init( child_process );
    184  
    185         fork_debug("INFO : %s duplicated child process from parent process\n",
    186                   __FUNCTION__ );
    187 
    188     // replicates virtual memory manager
    189         error = vmm_dup( &child_process->vmm , &parent_process->vmm );
     164        fork_dmsg("\n[INFO] %s : parent vmm duplicated in child process\n", __FUNCTION__ );
     165
     166    // create child main thread descriptor in local cluster
     167    error = thread_user_fork( parent_process , &child_thread );
     168
    190169        if( error )
    191170    {
    192             printk("ERROR in %s : cannot duplicate VMM\n", __FUNCTION__ );
    193             atomic_add ( &parent_process->childs_nr , -1 );
    194         process_destroy( child_process );
    195         return EAGAIN;
    196     }
    197  
    198         fork_debug("INFO : %s: parent vmm duplicated in child process\n", __FUNCTION__ );
    199 
    200     // create child main thread descriptor in local cluster TODO stack ???
    201     error = thread_user_fork( &child_thread , process , parent_thread );
    202         if( error )
    203     {
    204             printk("ERROR in %s : cannot duplicate thread\n", __FUNCTION__ );
    205             atomic_add ( &parent_process->childs_nr , -1 );
    206         process_destroy( child_process );
    207         return EAGAIN;
     171            printk("\n[ERROR] in %s : cannot duplicate thread\n", __FUNCTION__ );
     172            hal_atomic_add( &parent_process->children_nr , -1 );
     173        process_destroy( child_process );
     174        return ENOMEM;
    208175    }
    209176
    210177    // register child thread in child process, and get a TRDID
    211     spinlock_lock( &child->process->th_lock );
    212     error = process_register_thread( child->process, child->thread , &child_trdid );
    213     spinlock_unlock( &process->th_lock );
     178    spinlock_lock( &child_process->th_lock );
     179    error = process_register_thread( child_process, child_thread , &child_trdid );
     180    spinlock_unlock( &child_process->th_lock );
    214181
    215182    if( error )
    216183    {
    217         printk("ERROR in %s : cannot register thread\n", __FUNCTION__ );
    218             atomic_add ( &parent_process->childs_nr , -1 );
     184        printk("\n[ERROR] in %s : cannot register thread\n", __FUNCTION__ );
     185            hal_atomic_add ( &parent_process->children_nr , -1 );
    219186        thread_destroy( child_thread );
    220187        process_destroy( child_process );
     
    226193
    227194        // Update child thread descriptor
    228         child_thread->core    = process->core_tbl[child_core_lid];
     195        child_thread->core    = &LOCAL_CLUSTER->core_tbl[child_core_lid];
    229196        child_thread->process = child_process;
    230     child_thread->trdid   = chid_trdid;
    231 
    232         fork_debug("INFO : %s initialised child main thread\n", __FUNCTION__ );
     197    child_thread->trdid   = child_trdid;
     198
     199        fork_dmsg("\n[INFO] %s : initialised child main thread\n", __FUNCTION__ );
    233200
    234201    // register local child thread into local child process th_tbl[]
    235202    // we don't use the th_lock because there is no concurrent access
    236     ltid_t ltid = LTID_FROM_TRDID( trdid );
    237         child_process->th_tbl[ltid] = XPTR( local_cxy , child_thread );
    238         child_process->threads_nr = 1;
     203    ltid_t ltid = LTID_FROM_TRDID( child_trdid );
     204        child_process->th_tbl[ltid] = child_thread;
     205        child_process->th_nr = 1;
    239206
    240207    // register child thread in scheduler
    241         sched_register( child_thread->core , child_thread );
     208        sched_register_thread( child_thread->core , child_thread );
    242209 
    243         fork_debug("INFO : %s registered main thread in scheduler\n", __FUNCTION__);
     210        fork_dmsg("\n[INFO] %s : registered main thread in scheduler\n", __FUNCTION__);
    244211
    245212        // update DQDT for the child thread
    246     dqdt_update_threads_number( 1 );
    247 
    248         fork_debug("INFO :%s completed / parent pid = %x / child pid = %x / at cycle [%d]\n",
     213    dqdt_local_update_threads( 1 );
     214
     215        fork_dmsg("\n[INFO] %s : completed / parent pid = %x / child pid = %x / at cycle [%d]\n",
    249216                  __FUNCTION__, parent_process->pid, child_process->pid, hal_time_stamp() );
    250217
  • trunk/kernel/syscalls/sys_getcwd.c

    r1 r23  
    11/*
    2  * kern/sys_getcwd.c - get process current work directory
     2 * sys_getcwd.c - get process current work directory
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * Author    Alain Greiner (2016,2017)
    65 *
    7  * This file is part of ALMOS-kernel.
     6 * Copyright (c)  UPMC Sorbonne Universites
    87 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     8 * This file is part of ALMOS-MKH.
     9 *
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1718 *
    1819 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2021 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2122 */
    2223
    23 #include <libk.h>
     24#include <kernel_config.h>
     25#include <hal_types.h>
     26#include <hal_uspace.h>
     27#include <hal_special.h>
     28#include <errno.h>
    2429#include <vfs.h>
    25 #include <sys-vfs.h>
    26 #include <task.h>
    27 #include <kmem.h>
    28 #include <ppm.h>
     30#include <vmm.h>
     31#include <process.h>
    2932#include <thread.h>
     33#include <printk.h>
    3034
    31 /* TODO: user page need to be locked as long as its region */
     35/* TODO: user page(s) need to be locked  [AG] */
    3236
    33 int sys_getcwd (char *buff, size_t size)
     37////////////////////////////////
     38int sys_getcwd ( char     * buf,
     39                 uint32_t   nbytes )
    3440{
    35         register struct thread_s *this;
    36         register struct task_s *task;
    37         register error_t err;
    38         struct ku_obj ku_buff;
     41        error_t    error;
     42    paddr_t    paddr;
     43    char       kbuf[CONFIG_VFS_MAX_PATH_LENGTH];
    3944 
    40         this      = current_thread;
    41         task      = current_task;
     45        thread_t  * this    = CURRENT_THREAD;
     46    process_t * process = this->process;
    4247
    43         if((size < VFS_MAX_NAME_LENGTH) || (!buff))
     48    // check buffer size
     49        if( nbytes < CONFIG_VFS_MAX_PATH_LENGTH )
    4450        {
    45                 err = ERANGE;
    46                 goto SYS_GETCWD_ERROR;
     51        printk("\n[ERROR] in %s : buffer too small\n", __FUNCTION__ );
     52                this->errno = ERANGE;
     53        return -1;
    4754        }
    4855
    49         if(vmm_check_address("usr cwd buffer", task, buff, size))
     56    // check buffer in user space
     57    error = vmm_v2p_translate( false , buf , &paddr );
     58
     59        if( error )
    5060        {
    51                 err = EFAULT;
    52                 goto SYS_GETCWD_ERROR;
     61        printk("\n[ERROR] in %s : user buffer unmapped\n", __FUNCTION__ );
     62                this->errno = EFAULT;
     63        return -1;
    5364        }
    5465
    55         KU_SZ_BUFF(ku_buff, buff, size);
     66    // get reference process cluster and local pointer
     67    xptr_t      ref_xp  = process->ref_xp;
     68    cxy_t       ref_cxy = GET_CXY( ref_xp );
     69    process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
    5670
    57         rwlock_rdlock(&task->cwd_lock);
     71    // get CWD lock in read mode
     72        remote_rwlock_rd_lock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
    5873
    59         err = vfs_get_path(&task->vfs_cwd, &ku_buff);
     74    // call relevant VFS function
     75        error = vfs_get_path( XPTR( ref_cxy , &ref_ptr->vfs_cwd_xp ) ,
     76                          kbuf , CONFIG_VFS_MAX_PATH_LENGTH );
    6077
    61         rwlock_unlock(&task->cwd_lock);
     78    // release CWD lock
     79        remote_rwlock_rd_unlock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
    6280
     81    // copy kernel buffer to user space
     82    hal_copy_to_uspace( buf , kbuf , CONFIG_VFS_MAX_PATH_LENGTH );
    6383
    64 SYS_GETCWD_ERROR:
    65         this->info.errno = err;
    66         return (int)buff;
    67 }
     84    hal_wbflush();
     85
     86        return 0;
     87
     88}  // end sys_getcwd()
  • trunk/kernel/syscalls/sys_getpid.c

    r1 r23  
    22 * kern/sys_getpid.c - get process id
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * Author     Alain Greiner  (2016,2017)
    65 *
    7  * This file is part of ALMOS-kernel.
     6 * Copyright (c) UPMC Sorbonne Universites
    87 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     8 * This file is part of ALMOS-MKH.
     9 *
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1718 *
    1819 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2021 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2122 */
    2223
    23 #include <task.h>
    2424#include <thread.h>
    2525
     26////////////////
    2627int sys_getpid()
    2728{
    28         return current_task->pid;
     29        return CURRENT_THREAD->process->pid;
    2930}
  • trunk/kernel/syscalls/sys_gettimeofday.c

    r1 r23  
    11/*
    2  * sys_gettimeofday: get current time
    3  *
    4  * Copyright (c) 2015 UPMC Sorbonne Universites
     2 * sys_gettimeofday.c - Get current time
    53 *
    6  * This file is part of ALMOS-kernel.
     4 * Author    Alain Greiner (2016,2017)
    75 *
    8  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     6 * Copyright (c) UPMC Sorbonne Universites
     7 *
     8 * This file is part of ALMOS-MKH.
     9 *
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    911 * under the terms of the GNU General Public License as published by
    1012 * the Free Software Foundation; version 2.0 of the License.
    1113 *
    12  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1315 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1416 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1618 *
    1719 * You should have received a copy of the GNU General Public License
    18  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    1921 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2022 */
    2123
    22 #include <cpu.h>
     24#include <hal_types.h>
     25#include <hal_uspace.h>
    2326#include <thread.h>
     27#include <printk.h>
     28#include <errno.h>
     29#include <process.h>
     30#include <vmm.h>
     31#include <core.h>
    2432#include <time.h>
    2533
    26 int sys_gettimeofday(struct timeval *tv, struct timezone *tz)
     34///////////////////////////////////////////
     35int sys_gettimeofday( struct timeval  * tv,
     36                      struct timezone * tz )
    2737{
    28         error_t err;
    29         uint_t tm_ms, tm_us;
    30         struct timeval time;
     38        error_t        error;
     39    paddr_t        paddr;
    3140
    32         if((tv == NULL) || NOT_IN_USPACE(tv) || NOT_IN_USPACE(tv+sizeof(*tv)))
    33         {
    34                 err = EINVAL;
    35                 goto fail_inval;
    36         }
     41        uint32_t       tm_s;
     42    uint32_t       tm_us;
    3743
    38         if(tz)
    39                 return ENOTSUPPORTED;
     44        struct timeval k_tv;
    4045
    41         cpu_get_time(current_cpu, &tm_ms, &tm_us);
    42         time.tv_sec = tm_ms/1000;
    43         time.tv_usec = ((tm_ms%1000)*1000)+tm_us;
     46        thread_t  *    this    = CURRENT_THREAD;
     47        process_t *    process = this->process;
    4448
    45         //printk(INFO, "%s: [%d] (%u ms) sec %u, usec %u\n", __FUNCTION__,
    46         //current_cpu->gid, tm_ms, (uint32_t)time.tv_sec, (uint32_t)time.tv_usec);
     49    // check tz (non supported / must be null)
     50    if( tz )
     51    {
     52        printk("\n[ERROR] in %s for thread %x in process %x : tz argument must be NULL\n",
     53               __FUNCTION__ , this->trdid , process->pid );
     54        this->errno = EINVAL;
     55        return -1;
     56    }
     57 
     58    // check tv
     59    error = vmm_v2p_translate( false , tv , &paddr );
    4760
    48         err    = cpu_copy_to_uspace(tv, &time, sizeof(time));
     61    if( error )
     62    {
     63        printk("\n[ERROR] in %s for thread %x in process %x : tv argument unmapped\n",
     64        __FUNCTION__ , this->trdid , process->pid );
     65        this->errno = EINVAL;
     66        return -1;
     67    }
    4968
    50 fail_inval:
    51         current_thread->info.errno = err;
    52         return err;
    53 }
     69    // get time from calling core descriptor
     70    core_get_time( this->core , &tm_s , &tm_us );
     71        k_tv.tv_sec  = tm_s;
     72        k_tv.tv_usec = tm_us;
     73
     74    // copy values to user space
     75        hal_copy_to_uspace( tv , &k_tv , sizeof(struct timeval) );
     76
     77    hal_wbflush();
     78
     79        return 0;
     80
     81}  // end sys_timeofday()
  • trunk/kernel/syscalls/sys_lseek.c

    r1 r23  
    2121 */
    2222
    23 #include <types.h>
     23#include <kernel_config.h>
     24#include <hal_types.h>
     25#include <hal_uspace.h>
     26#include <errno.h>
    2427#include <vfs.h>
     28#include <vmm.h>
    2529#include <thread.h>
    26 #include <sys-vfs.h>
    27 #include <task.h>
     30#include <printk.h>
     31#include <process.h>
    2832
    29 int sys_lseek (uint_t fd, off_t offset, int whence)
     33////////////////////////////////
     34int sys_lseek (uint32_t file_id,
     35               uint32_t offset,
     36               uint32_t whence )
    3037{
    31         error_t err = 0;
    32         size_t new_offset;
    33         struct thread_s *this;
    34         struct task_s *task;
    35         struct vfs_file_s *file;
     38        error_t    error;
     39    xptr_t     file_xp;
     40    uint32_t   new_offset;
    3641
    37         file = NULL;
    38         this = current_thread;
    39         task = current_task;
     42        thread_t  * this    = CURRENT_THREAD;
     43        process_t * process = this->process;
     44
     45    // check file_id argument
     46        if( file_id >= CONFIG_PROCESS_FILE_MAX_NR )
     47        {
     48        printk("\n[ERROR] in %s : illegal file descriptor index = %d\n",
     49               __FUNCTION__ , file_id );
     50                this->errno = EBADFD;
     51                return -1;
     52        }
     53
     54    // get extended pointer on remote file descriptor
     55    file_xp = process_fd_get_xptr( process , file_id );
     56
     57    if( file_xp == XPTR_NULL )
     58    {
     59        printk("\n[ERROR] in %s : undefined file descriptor index = %d\n",
     60               __FUNCTION__ , file_id );
     61                this->errno = EBADFD;
     62                return -1;
     63    }
    4064
    4165        /* FIXME: file may be closed in parallel
    4266         * of seek/read/write/mmap ..etc
    4367         * so file may be NULL or invalid */
    44         if((fd >= CONFIG_TASK_FILE_MAX_NR) || (task_fd_lookup(task, fd, &file)))
     68
     69    // call relevant VFS function
     70        error = vfs_lseek( file_xp , offset , whence , &new_offset );
     71
     72        if( error )
    4573        {
    46                 this->info.errno = EBADFD;
    47                 return -1;
    48         }
    49 
    50         if((err = vfs_lseek(file, offset, whence, &new_offset)))
    51         {
    52                 this->info.errno = (err < 0) ? -err : err;
     74        printk("\n[ERROR] in %s : cannot seek file = %d\n",
     75               __FUNCTION__ , file_id );
     76                this->errno = error;
    5377                return -1;
    5478        }
  • trunk/kernel/syscalls/sys_mkdir.c

    r1 r23  
    11/*
    2  * kern/sys_mkdir.c - creates new directory
     2 * sys_mkdir.c - Create a new directory
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * Author    Alain Greiner (2016,2017)
    65 *
    7  * This file is part of ALMOS-kernel.
     6 * Copyright (c) UPMC Sorbonne Universites
    87 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     8 * This file is part of ALMOS-MKH.
     9 *
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1718 *
    1819 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2021 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2122 */
    2223
     24#include <hal_types.h>
     25#include <hal_uspace.h>
    2326#include <vfs.h>
    24 #include <sys-vfs.h>
    25 #include <task.h>
     27#include <vmm.h>
     28#include <errno.h>
     29#include <process.h>
    2630#include <thread.h>
     31#include <printk.h>
    2732
    28 int sys_mkdir (char *pathname, uint_t mode)
     33///////////////////////////////////
     34int sys_mkdir( char     * pathname,
     35               uint32_t   mode )
    2936{
    30         register error_t err = 0;
    31         struct task_s *task = current_task;
    32         struct ku_obj ku_path;
     37        error_t        error;
     38    paddr_t        paddr;
     39    uint32_t       length;
     40    char           kbuf[CONFIG_VFS_MAX_PATH_LENGTH];
    3341
    34         KU_BUFF(ku_path, pathname);
    35         rwlock_rdlock(&task->cwd_lock);
     42        thread_t     * this     = CURRENT_THREAD;
     43        process_t    * process  = this->process;
    3644
    37         if((err = vfs_mkdir(&task->vfs_cwd, &ku_path, mode)))
     45    // check pathname in user space
     46    error = vmm_v2p_translate( false , pathname , &paddr );
     47
     48        if( error )
    3849        {
    39                 current_thread->info.errno = (err < 0) ? -err : err;
    40                 rwlock_unlock(&task->cwd_lock);
     50        printk("\n[ERROR] in %s : user buffer unmapped  for thread %x in process %x\n",
     51               __FUNCTION__ , this->trdid , process->pid );
     52                this->errno = EINVAL;
     53                return -1;
     54        }       
     55     
     56    // check fd_array not full
     57        if( process_fd_array_full() )
     58        {
     59        printk("\n[ERROR] in %s : file descriptor array full for process %x\n",
     60               __FUNCTION__ , process->pid );
     61                this->errno = ENFILE;
     62        return -1;
     63        }
     64   
     65    // get pathname length
     66    length = hal_strlen_from_uspace( pathname );
     67
     68    if( length >= CONFIG_VFS_MAX_PATH_LENGTH )
     69    {
     70        printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ );
     71                this->errno = ENFILE;
     72        return -1;
     73    }
     74 
     75        // get pathname copy in kernel space
     76    hal_copy_from_uspace( kbuf, pathname, length );
     77
     78    // get cluster and local pointer on reference process
     79    xptr_t      ref_xp  = process->ref_xp;
     80    process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
     81    cxy_t       ref_cxy = GET_CXY( ref_xp );
     82
     83    // get extended pointer on cwd inode
     84    xptr_t cwd_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->vfs_cwd_xp ) );
     85   
     86    // get the cwd lock in read mode from reference process
     87        remote_rwlock_rd_lock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
     88
     89    // call the relevant VFS function
     90        error = vfs_mkdir( cwd_xp,
     91                       kbuf,
     92                       mode );
     93
     94    // release the cwd lock
     95        remote_rwlock_rd_unlock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
     96
     97    if( error )
     98        {
     99        printk("\n[ERROR] in %s : cannot create directory %s\n",
     100               __FUNCTION__ , kbuf );
     101                this->errno = error;
    41102                return -1;
    42103        }
    43104   
    44         rwlock_unlock(&task->cwd_lock);
    45105        return 0;
    46106}
  • trunk/kernel/syscalls/sys_mkfifo.c

    r1 r23  
    11/*
    2  * kern/sys_mkfifo.c - creates a FIFO named file
     2 * sys_mkfifo.c - creates a named FIFO file.
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * Author    Alain Greiner (2016,2017)
    65 *
    7  * This file is part of ALMOS-kernel.
     6 * Copyright (c) UPMC Sorbonne Universites
    87 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     8 * This file is part of ALMOS-MKH.
     9 *
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1718 *
    1819 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2021 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2122 */
    2223
    23 #include <kdmsg.h>
     24#include <hal_types.h>
     25#include <hal_uspace.h>
     26#include <printk.h>
    2427#include <vfs.h>
    25 #include <sys-vfs.h>
    26 #include <task.h>
     28#include <process.h>
    2729#include <thread.h>
    2830
    29 int sys_mkfifo (char *pathname, uint_t mode)
     31////////////////////////////////////
     32int sys_mkfifo ( char    * pathname,
     33                 uint32_t  mode )
    3034{
    31         register error_t err = 0;
    32         struct task_s *task = current_task;
    33         struct ku_obj ku_path;
     35    error_t        error;
     36    uint32_t       length;                           // pathname length (bytes)
     37    char           kbuf[CONFIG_VFS_MAX_PATH_LENGTH];
    3438
    35         current_thread->info.errno = ENOSYS;
    36         return -1;
     39    thread_t  * this    = CURRENT_THREAD;
     40        process_t * process = this->process;
    3741
    38         KU_BUFF(ku_path, pathname);
    39         rwlock_rdlock(&task->cwd_lock);
    40         if((err = vfs_mkfifo(&task->vfs_cwd, &ku_path, mode)))
     42        if( pathname == NULL )
    4143        {
    42                 printk(INFO, "INFO: sys_mkfifo: Thread %x, CPU %d, Error Code %d\n",
    43                        current_thread,
    44                        cpu_get_id(),
    45                        err);
     44        printk("\n[ERROR] in %s : pathname is NULL\n", __FUNCTION__ );
     45                this->errno = EINVAL;
     46                return -1;
     47        }       
    4648
    47                 rwlock_unlock(&task->cwd_lock);
     49    // check fd_array not full
     50        if( process_fd_array_full() )
     51        {
     52        printk("\n[ERROR] in %s : file descriptor array full for process %x\n",
     53               __FUNCTION__ , process->pid );
     54                this->errno = ENFILE;
     55        return -1;
     56        }
     57   
     58    // get pathname length
     59    length = hal_strlen_from_uspace( pathname );
     60
     61    if( length >= CONFIG_VFS_MAX_PATH_LENGTH )
     62    {
     63        printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ );
     64                this->errno = ENFILE;
     65        return -1;
     66    }
     67 
     68        // get pathname copy in kernel space
     69    hal_copy_from_uspace( kbuf, pathname, length );
     70
     71    // get cluster and local pointer on reference process
     72    xptr_t      ref_xp  = process->ref_xp;
     73    process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
     74    cxy_t       ref_cxy = GET_CXY( ref_xp );
     75
     76    // get extended pointer on cwd inode
     77    xptr_t cwd_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->vfs_cwd_xp ) );
     78   
     79    // get the cwd lock in read mode from reference process
     80        remote_rwlock_rd_lock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
     81
     82    // call the relevant VFS function
     83        error = vfs_mkfifo( cwd_xp,
     84                        kbuf,
     85                        mode );
     86
     87    // release the cwd lock
     88        remote_rwlock_rd_unlock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
     89
     90    if( error )
     91        {
     92        printk("\n[ERROR] in %s : cannot create named FIFO %s\n",
     93               __FUNCTION__ , kbuf );
     94                this->errno = error;
    4895                return -1;
    4996        }
    50         rwlock_unlock(&task->cwd_lock);
    5197   
    5298        return 0;
    53 }
     99
     100} // end sys_mkfifo()
  • trunk/kernel/syscalls/sys_mmap.c

    r1 r23  
    11/*
    2  * kern/sys_mmap.c - map files, memory or devices into process's
    3  *                   virtual address space
     2 * sys_mmap.c - map files, memory or devices into process virtual address space
    43 *
    5  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    6  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * Authors       Ghassan Almaless (2008,2009,2010,2011,2012)
     5 *               Alain Greiner (2016,2017)
    76 *
    8  * This file is part of ALMOS-kernel.
     7 * Copyright (c) UPMC Sorbonne Universites
    98 *
    10  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     9 * This file is part of ALMOS-MKH.
     10 *
     11 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1112 * under the terms of the GNU General Public License as published by
    1213 * the Free Software Foundation; version 2.0 of the License.
    1314 *
    14  * ALMOS-kernel is distributed in the hope that it will be useful, but
     15 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1516 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1617 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1819 *
    1920 * You should have received a copy of the GNU General Public License
    20  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     21 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2122 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2223 */
    2324
     25#include <hal_types.h>
    2426#include <errno.h>
    2527#include <thread.h>
     28#include <printk.h>
    2629#include <vfs.h>
    27 #include <sys-vfs.h>
    2830#include <process.h>
    2931#include <vmm.h>
    3032
    3133///////////////////////////////////
    32 int sys_mmap( mmap_attr_t * mattr )
     34int sys_mmap( mmap_attr_t * attr )
    3335{
     36    printk("\n[WARNING] function %s not implemented\n", __FUNCTION__ );
     37    return 0;
     38/*   
    3439        error_t err;
    3540        uint_t count;
     
    4651        file = NULL;
    4752
    48         if((err = cpu_copy_from_uspace(&attr, mattr, sizeof(mmap_attr_t))))
     53        if((err = cpu_copy_from_uspace(&attr, attr, sizeof(mmap_attr_t))))
    4954        {
    5055                printk(INFO, "%s: failed, copying from uspace @%x\n",
    5156                       __FUNCTION__,
    52                        mattr);
     57                       attr);
    5358
    5459                this->info.errno = EFAULT;
     
    8287        else
    8388        {     
    84                 /* FIXEME: possible concurent delete of file from another bugy thread closing it */
     89                // FIXME: possible concurent delete of file from another bugy thread closing it
    8590                if((attr.fd >= CONFIG_TASK_FILE_MAX_NR) || (process_fd_lookup(process, attr.fd, &file)))
    8691                {
     
    145150
    146151        return (int)VM_FAILED;
    147 }
     152*/
     153}  // end sys_mmap()
  • trunk/kernel/syscalls/sys_mutex.c

    r15 r23  
    11/*
    2  * kern/sys_rwlock.c - interface to access Read-Write locks service
     2 * sys_mutex.c - Access a POSIX mutex.
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * Author    Alain Greiner (2016,2017)
    65 *
    7  * This file is part of ALMOS-kernel.
     6 * Copyright (c) UPMC Sorbonne Universites
    87 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     8 * This file is part of ALMOS-MKH.
     9 *
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1718 *
    1819 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2021 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2122 */
    2223
    23 #include <types.h>
     24#include <hal_types.h>
     25#include <hal_special.h>
    2426#include <errno.h>
    2527#include <thread.h>
    26 #include <kmem.h>
    27 #include <task.h>
     28#include <printk.h>
    2829#include <vmm.h>
    29 #include <kmagics.h>
    30 #include <rwlock.h>
     30#include <syscalls.h>
     31#include <remote_mutex.h>
    3132
    3233
    33 static inline bool_t isBadLock(struct rwlock_s *rwlock)
    34 {
    35         return vmm_check_object(rwlock, struct rwlock_s, RWLOCK_ID);
    36 }
     34/////////////////////////////////
     35int sys_mutex( void     * vaddr,
     36               uint32_t   operation,
     37               uint32_t   attr )
     38{
     39        error_t    error;
     40    paddr_t    paddr;
    3741
    38 int sys_rwlock(struct rwlock_s **rwlock, uint_t operation)
    39 {
    40         kmem_req_t req;
    41         struct rwlock_s *irwlock;
    42         error_t err;
    43  
    44         err = vmm_check_address("usr rwlock ptr",
    45                                 current_task,
    46                                 rwlock,
    47                                 sizeof(struct rwlock_s*));
    48         if(err)
    49                 goto SYS_RWLOCK_END;
     42    thread_t * this = CURRENT_THREAD;
    5043
    51         if((err = cpu_copy_from_uspace(&irwlock, rwlock, sizeof(struct rwlock_s *))))
    52                 goto SYS_RWLOCK_END;
    53  
    54         switch(operation)
    55         {   
    56         case RWLOCK_INIT:   
    57                 req.type  = KMEM_RWLOCK;
    58                 req.size  = sizeof(*irwlock);
    59                 req.flags = AF_USER;
     44    // check vaddr in user vspace
     45        error = vmm_v2p_translate( false , vaddr , &paddr );
     46        if( error )
     47    {
     48        printk("\n[ERROR] in %s : illegal virtual address = %x\n",
     49               __FUNCTION__ , (intptr_t)vaddr );
     50        this->errno = error;
     51        return -1;
     52    }
    6053
    61                 if((irwlock = kmem_alloc(&req)) == NULL)
    62                 {
    63                         err = ENOMEM;
    64                         break;
     54    // execute requested operation
     55        switch( operation )
     56        {   
     57        ////////////////
     58            case MUTEX_INIT:
     59        {
     60            if( attr != 0 )
     61            {
     62                printk("\n[ERROR] in %s : mutex attributes non supported yet\n",
     63                       __FUNCTION__ );
     64                this->errno = error;
     65                return -1;
     66            }
     67   
     68            error = remote_mutex_create( (intptr_t)vaddr );
     69
     70            if( error )
     71            {
     72                printk("\n[ERROR] in %s : cannot create mutex\n",
     73                       __FUNCTION__ );
     74                this->errno = error;
     75                return -1;
     76            }
     77                    break;
    6578                }
    66    
    67                 if((err = rwlock_init(irwlock)))
    68                         break;
    69    
    70                 if((err = cpu_copy_to_uspace(rwlock, &irwlock, sizeof(struct rwlock_s *))))
    71                 {
    72                         req.ptr = irwlock;
    73                         kmem_free(&req);
    74                 }
    75                 break;
     79        ///////////////////
     80            case MUTEX_DESTROY:
     81        {
     82            xptr_t mutex_xp = remote_mutex_from_ident( (intptr_t)vaddr );
    7683
    77         case RWLOCK_WRLOCK:
    78                 if(isBadLock(irwlock))
    79                         break;
    80    
    81                 return rwlock_wrlock(irwlock);
     84            if( mutex_xp == XPTR_NULL )     // user error
     85            {
     86                printk("\n[ERROR] in %s : mutex %x not registered\n",
     87                       __FUNCTION__ , (intptr_t)vaddr );
     88                this->errno = EINVAL;
     89                return -1;
     90            }
     91            else                          // success
     92            {
     93                remote_mutex_destroy( mutex_xp );
     94            }
     95            break;
     96        }
     97        ////////////////
     98            case MUTEX_LOCK:
     99        {
     100            xptr_t mutex_xp = remote_mutex_from_ident( (intptr_t)vaddr );
    82101
    83         case RWLOCK_RDLOCK:
    84                 if(isBadLock(irwlock))
    85                         break;
    86    
    87                 return rwlock_rdlock(irwlock);
     102            if( mutex_xp == XPTR_NULL )     // user error
     103            {
     104                printk("\n[ERROR] in %s : mutex %x not registered\n",
     105                       __FUNCTION__ , (intptr_t)vaddr );
     106                this->errno = EINVAL;
     107                return -1;
     108            }
     109            else                          // success
     110            {
     111                remote_mutex_lock( mutex_xp );
     112            }
     113            break;
     114        }
     115        //////////////////
     116            case MUTEX_UNLOCK:
     117        {
     118            xptr_t mutex_xp = remote_mutex_from_ident( (intptr_t)vaddr );
    88119
    89         case RWLOCK_TRYWRLOCK:
    90                 if(isBadLock(irwlock))
    91                         break;
    92    
    93                 return rwlock_trywrlock(irwlock);
    94 
    95         case RWLOCK_TRYRDLOCK:
    96                 if(isBadLock(irwlock))
    97                         break;
    98    
    99                 return rwlock_tryrdlock(irwlock);
    100 
    101         case RWLOCK_UNLOCK:
    102                 if(isBadLock(irwlock))
    103                         break;
    104    
    105                 if((err = rwlock_unlock(irwlock)))
    106                         break;
    107 
    108         case RWLOCK_DESTROY:
    109                 if(isBadLock(irwlock))
    110                         break;
    111    
    112                 if((err = rwlock_destroy(irwlock)))
    113                         break;
    114 
    115                 req.type = KMEM_RWLOCK;
    116                 req.ptr  = irwlock;
    117                 kmem_free(&req);
    118                 return 0;
    119 
    120         default:
    121                 err = EINVAL;
     120            if( mutex_xp == XPTR_NULL )     // user error
     121            {
     122                printk("\n[ERROR] in %s : mutex %x not registered\n",
     123                       __FUNCTION__ , (intptr_t)vaddr );
     124                this->errno = EINVAL;
     125                return -1;
     126            }
     127            else                          // success
     128            {
     129                remote_mutex_unlock( mutex_xp );
     130            }
     131            break;
     132        }
     133        ////////
     134            default:
     135        {
     136            printk("\n[PANIC] in %s : illegal operation type\n", __FUNCTION__ );
     137                    hal_core_sleep();
     138        }
    122139        }
    123140
    124 SYS_RWLOCK_END:
    125         current_thread->info.errno = err;
    126         return err;
    127 }
     141        return 0;
    128142
    129 KMEM_OBJATTR_INIT(rwlock_kmem_init)
    130 {
    131         attr->type   = KMEM_RWLOCK;
    132         attr->name   = "KCM RWLOCK";
    133         attr->size   = sizeof(struct rwlock_s);
    134         attr->aligne = 0;
    135         attr->min    = CONFIG_RWLOCK_MIN;
    136         attr->max    = CONFIG_RWLOCK_MAX;
    137         attr->ctor   = NULL;
    138         attr->dtor   = NULL;
    139  
    140         return 0;
    141 }
     143}  // end sys_mutex()
     144
  • trunk/kernel/syscalls/sys_open.c

    r1 r23  
    11/*
    2  * kern/sys_open.c - open a named file
     2 * sys_open.c - open a file.
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * Author        Alain Greiner (2016,2017)
    65 *
    7  * This file is part of ALMOS-kernel.
     6 * Copyright (c) UPMC Sorbonne Universites
    87 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     8 * This file is part of ALMOS-MKH.
     9 *
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1718 *
    1819 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2021 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2122 */
    2223
     24#include <kernel_config.h>
     25#include <hal_types.h>
     26#include <hal_uspace.h>
    2327#include <errno.h>
    2428#include <thread.h>
     29#include <printk.h>
    2530#include <vfs.h>
    26 #include <sys-vfs.h>
    2731#include <process.h>
    28 #include <spinlock.h>
    29 #include <cpu-trace.h>
     32#include <remote_spinlock.h>
     33#include <remote_rwlock.h>
    3034
    3135///////////////////////////////////
     
    3438               uint32_t   mode )
    3539{
    36         CPU_HW_TRACE(sys_open);
    3740
    38         error_t            err;
    39         struct vfs_file_s  file;   
    40         struct ku_obj      ku_path;
    41         thread_t         * this     = current_thread;
    42         process_t        * process  = current_process;
    43         uint32_t           fd       = (uint32_t)-1;
     41        error_t        error;
     42        xptr_t         file_xp;                          // extended pointer on vfs_file_t
     43        uint32_t       file_id;                          // file descriptor index
     44    uint32_t       length;                           // pathname length (bytes)
     45    char           kbuf[CONFIG_VFS_MAX_PATH_LENGTH];
    4446
    45         cpu_trace_write(current_cpu, sys_open);
     47        thread_t     * this     = CURRENT_THREAD;
     48        process_t    * process  = this->process;
    4649
    47         if( process_fd_aray_full( process ) )
     50        if( pathname == NULL )
    4851        {
    49                 this->info.errno = ENFILE;
    50         CPU_HW_TRACE(sys_open);
    51         return fd;
     52        printk("\n[ERROR] in %s : pathname is NULL\n", __FUNCTION__ );
     53                this->errno = EINVAL;
     54                return -1;
     55        }       
     56
     57    // check fd_array not full
     58        if( process_fd_array_full() )
     59        {
     60        printk("\n[ERROR] in %s : file descriptor array full for process %x\n",
     61               __FUNCTION__ , process->pid );
     62                this->errno = ENFILE;
     63        return -1;
    5264        }
    5365   
    54         if( VFS_IS( flags , VFS_O_DIRECTORY ) ) VFS_SET( flags , VFS_DIR );
     66    // get pathname length
     67    length = hal_strlen_from_uspace( pathname );
    5568
    56         KU_BUFF( ku_path , pathname );
     69    if( length >= CONFIG_VFS_MAX_PATH_LENGTH )
     70    {
     71        printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ );
     72                this->errno = ENFILE;
     73        return -1;
     74    }
     75 
     76        // get pathname copy in kernel space
     77    hal_copy_from_uspace( kbuf, pathname, length );
    5778
    58     // get the cwd lock
    59         rwlock_rdlock( &process->cwd_lock );
     79    // get cluster and local pointer on reference process
     80    xptr_t      ref_xp  = process->ref_xp;
     81    process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
     82    cxy_t       ref_cxy = GET_CXY( ref_xp );
     83
     84    // get extended pointer on cwd inode
     85    xptr_t cwd_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->vfs_cwd_xp ) );
    6086   
    61         err = vfs_open( &process->vfs_cwd , &ku_path , flags , mode , &file );
    62         if( err )
     87    // get the cwd lock in read mode from reference process
     88        remote_rwlock_rd_lock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
     89
     90    // call the relevant VFS function
     91        error = vfs_open( cwd_xp,
     92                      kbuf,
     93                      flags,
     94                      mode,
     95                      &file_xp,
     96                      &file_id );
     97
     98    // release the cwd lock
     99        remote_rwlock_rd_unlock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
     100
     101        if( error )
    63102        {
    64                 this->info.errno = (err < 0 ) ? -err : err;
    65             rwlock_unlock( &process->cwd_lock );
    66             CPU_HW_TRACE(sys_open);
    67             return fd;
    68         }
    69        
    70         err = process_fd_set( process , &file , &fd );
    71         if( err )
    72         {
    73                 vfs_close(&file, NULL);
    74                 this->info.errno = err;
     103        printk("\n[ERROR] in %s : cannot create file descriptor\n", __FUNCTION__ );
     104                this->errno = ENFILE;
     105            return -1;
    75106        }
    76107
    77         rwlock_unlock( &process->cwd_lock );
    78         CPU_HW_TRACE(sys_open);
    79         return fd;
     108    // update local fd_array
     109    remote_spinlock_lock( XPTR( local_cxy , &process->fd_array.lock ) );
     110        process->fd_array.array[file_id] = file_xp;
     111    remote_spinlock_unlock( XPTR( local_cxy , &process->fd_array.lock ) );
     112
     113        return file_id;
    80114}
  • trunk/kernel/syscalls/sys_opendir.c

    r1 r23  
    11/*
    2  * kern/sys_opendir.c - open a directory
     2 * sys_opendir.c - open a directory.
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * Author        Alain Greiner (2016,2017)
    65 *
    7  * This file is part of ALMOS-kernel.
     6 * Copyright (c) UPMC Sorbonne Universites
    87 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     8 * This file is part of ALMOS-MKH.
     9 *
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1718 *
    1819 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2021 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2122 */
    2223
     24#include <hal_types.h>
    2325#include <vfs.h>
    24 #include <sys-vfs.h>
    25 #include <process.h>
    26 #include <thread.h>
    27 #include <spinlock.h>
     26#include <syscalls.h>
    2827
    2928///////////////////////////////////
    3029int sys_opendir ( char * pathname )
    3130{
    32         error_t             err;
    33         struct vfs_file_s   file;
    34         struct ku_obj       ku_path;
    35         thread_t          * this    = current_thread;
    36         process_t         * process = current_process;
    37         uint32_t            fd        = (uint32_t)-1;
    38         uint32_t            mode      = 0;
    39    
    40         if( process_fd_array_full( process ) )
    41         {
    42                 this->info.errno = ENFILE;
    43             return fd;
    44         }
     31        uint32_t   mode  = 0;
     32    uint32_t   flags = O_DIR;
    4533
    46         KU_BUFF(ku_path, pathname);
    47 
    48         rwlock_rdlock( &process->cwd_lock );
    49 
    50         err = vfs_opendir( &process->vfs_cwd , &ku_path , mode , &file );
    51         if( err )
    52         {
    53                 this->info.errno = (err < 0 ) ? -err : err;
    54             rwlock_unlock( &process->cwd_lock );
    55             return fd;
    56         }
    57 
    58         err = process_fd_set( process , &file , &fd);
    59         if( err )
    60         {
    61                 vfs_close(&file, NULL);
    62                 this->info.errno = err;
    63         }
    64    
    65         rwlock_unlock( &process->cwd_lock );
    66         return fd;
     34    return sys_open( pathname , flags , mode );
    6735}
  • trunk/kernel/syscalls/sys_pipe.c

    r1 r23  
    11/*
    2  * kern/sys_pipe.c - open a pipe communication channel
     2 * sys_pipe.c - open a pipe communication channel
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * Author    Alain Greiner  (2016,1017)
    65 *
    7  * This file is part of ALMOS-kernel.
     6 * Copyright (c)  UPMC Sorbonne Universites
    87 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     8 * This file is part of ALMOS-MKH.
     9 *
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1718 *
    1819 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2021 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2122 */
    2223
     24#include <hal_types.h>
    2325#include <vfs.h>
    24 #include <sys-vfs.h>
    25 #include <task.h>
     26#include <process.h>
    2627#include <thread.h>
    27 #include <spinlock.h>
     28#include <printk.h>
    2829
    29 int sys_pipe (uint_t *pipefd)
     30//////////////////////////////////////
     31int sys_pipe ( uint32_t * file_fd[2] )
    3032{
    31         current_thread->info.errno = ENOSYS;
    32         return -1;
     33    thread_t * this = CURRENT_THREAD;
     34
     35    printk("\n[ERROR] in %d : not implemented yet\n", __FUNCTION__ );
     36    this->errno = ENOSYS;
     37    return -1;
     38
    3339}
  • trunk/kernel/syscalls/sys_read.c

    r1 r23  
    11/*
    2  * kern/sys_read.c - read bytes from an opened file
     2 * sys_read.c - read bytes from a file
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * Author     Alain Greiner (2016,2017)
    65 *
    7  * This file is part of ALMOS-kernel.
     6 * Copyright (c) UPMC Sorbonne Universites
    87 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     8 * This file is part of ALMOS-MKH.
     9 *
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1718 *
    1819 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2021 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2122 */
    2223
     24#include <kernel_config.h>
     25#include <hal_types.h>
     26#include <hal_uspace.h>
     27#include <hal_special.h>
    2328#include <errno.h>
     29#include <vfs.h>
     30#include <vmm.h>
    2431#include <thread.h>
    25 #include <vfs.h>
    26 #include <sys-vfs.h>
    27 #include <task.h>
     32#include <printk.h>
     33#include <process.h>
    2834
    29 int sys_read (uint_t fd, void *buf, size_t count)
     35/* TODO: user page(s) need to be locked  [AG] */
     36
     37/////////////////////////////////
     38int sys_read( uint32_t   file_id,
     39              void     * buf,
     40              uint32_t   count )
    3041{
    31         struct ku_obj kub;
    32         ssize_t err;
    33         struct thread_s *this;
    34         struct task_s *task;
    35         struct vfs_file_s *file;
     42    error_t      error;
     43    paddr_t      paddr;
     44    char         kbuf[CONFIG_VFS_KBUF_SIZE];
    3645
    37         file = NULL;
    38         this = current_thread;
    39         task = current_task;
     46        xptr_t       file_xp;     // remote file extended pointer
     47    uint32_t     nbytes;      // number of bytes in one iteration
    4048
    41         if((fd >= CONFIG_TASK_FILE_MAX_NR) || (task_fd_lookup(task, fd, &file)))
     49        thread_t  *  this    = CURRENT_THREAD;
     50        process_t *  process = this->process;
     51 
     52    // check file_id argument
     53        if( file_id >= CONFIG_PROCESS_FILE_MAX_NR )
    4254        {
    43                 this->info.errno = EBADFD;
     55        printk("\n[ERROR] in %s : illegal file descriptor index = %d\n",
     56               __FUNCTION__ , file_id );
     57                this->errno = EBADFD;
    4458                return -1;
    4559        }
    4660
    47         KU_SLICE_BUFF(kub, buf, count);
    48         if((err = vfs_read(file, &kub)) < 0)
     61    // check user buffer in user space
     62    error = vmm_v2p_translate( false , buf , &paddr );
     63
     64    if ( error )
     65    {
     66        printk("\n[ERROR] in %s : user buffer unmapped = %x\n",
     67               __FUNCTION__ , (intptr_t)buf );
     68                this->errno = EINVAL;
     69                return -1;
     70    }
     71
     72    // get extended pointer on remote file descriptor
     73    file_xp = process_fd_get_xptr( process , file_id );
     74
     75    if( file_xp == XPTR_NULL )
     76    {
     77        printk("\n[ERROR] in %s : undefined file descriptor index = %d\n",
     78               __FUNCTION__ , file_id );
     79        this->errno = EBADFD;
     80        return -1;
     81    }
     82
     83    // get file descriptor cluster and local pointer
     84    vfs_file_t * file_ptr = (vfs_file_t *)GET_PTR( file_xp );
     85    cxy_t        file_cxy = GET_CXY( file_xp );
     86
     87    // check file readable
     88    uint32_t attr = hal_remote_lw( XPTR( file_cxy , &file_ptr->attr ) );
     89    if( (attr & FD_ATTR_READ_ENABLE) == 0 )
    4990        {
    50                 this->info.errno = -err;
    51                 printk(INFO, "INFO: sys_read: Error %d\n", this->info.errno);
     91        printk("\n[ERROR] in %s : file %d not readable\n",
     92               __FUNCTION__ , file_id );
     93                this->errno = EBADFD;
    5294                return -1;
    5395        }
    5496   
    55         return err;
    56 }
     97    // transfer at most CONFIG_VFS_KBUF_SIZE bytes per iteration
     98    while( count )
     99    {
     100        if( count <= CONFIG_VFS_KBUF_SIZE )
     101        {
     102            nbytes = count;
     103            count  = 0;
     104        }
     105        else
     106        {
     107            nbytes = CONFIG_VFS_KBUF_SIZE;
     108            count  = count - CONFIG_VFS_KBUF_SIZE;
     109        }
     110
     111        // transfer nbytes to kernel buffer
     112        error = vfs_move( true,               // read => (to_buffer = true)
     113                          file_xp ,
     114                          kbuf ,
     115                          nbytes );
     116
     117        if( error )
     118        {
     119            printk("\n[ERROR] in %s cannot read data from file %d\n",
     120                   __FUNCTION__ , file_id );
     121            this->errno = error;
     122            return -1;
     123        }
     124
     125        // copy kernel buffer to user space
     126        hal_copy_to_uspace( buf , kbuf , nbytes );
     127    }
     128
     129    hal_wbflush();
     130
     131        return 0;
     132
     133}  // end sys_read()
  • trunk/kernel/syscalls/sys_readdir.c

    r1 r23  
    11/*
    2  * sys_read.c: read entries from an opened directory
    3  *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     2 * sys_readdir.c - Read one entry from an open directory.
    63 *
    7  * This file is part of ALMOS-kernel.
     4 * Author    Alain Greiner (2016,2017)
    85 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     6 * Copyright (c) UPMC Sorbonne Universites
     7 *
     8 * This file is part of ALMOS-MKH.
     9 *
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1718 *
    1819 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2021 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2122 */
    2223
     24#include <kernel_config.h>
     25#include <hal_types.h>
     26#include <hal_uspace.h>
     27#include <errno.h>
     28#include <thread.h>
     29#include <printk.h>
    2330#include <vfs.h>
    24 #include <sys-vfs.h>
    25 #include <task.h>
    26 #include <thread.h>
     31#include <process.h>
     32#include <syscalls.h>
    2733
    28 /* FIXEME: reading dirent from user without any protection */
     34//////////////////////////////////////////
     35int sys_readdir ( uint32_t       file_id,
     36                  vfs_dirent_t * dirent )
     37{
     38        error_t        error;
     39    paddr_t        paddr;
     40        xptr_t         file_xp;    // extended pointer on searched directory file descriptor
     41    vfs_dirent_t   k_dirent;   // kernel copy of dirent
    2942
    30 int sys_readdir (uint_t fd, struct vfs_usp_dirent_s *dirent)
    31 {
    32         error_t err;
    33         struct ku_obj dir;
    34         struct task_s *task;
    35         struct thread_s *this;
    36         struct vfs_file_s *file;
    37  
    38         file = NULL;
    39         task = current_task;
    40         this = current_thread;
     43        thread_t     * this     = CURRENT_THREAD;
     44        process_t    * process  = this->process;
    4145
    42         if((dirent == NULL)                ||
    43            (fd >= CONFIG_TASK_FILE_MAX_NR) ||
    44            (task_fd_lookup(task, fd, &file)))
     46    // check file_id argument
     47        if( file_id >= CONFIG_PROCESS_FILE_MAX_NR )
    4548        {
    46                 this->info.errno = EBADFD;
     49        printk("\n[ERROR] in %s : illegal file descriptor index\n", __FUNCTION__ );
     50        this->errno = EBADFD;
    4751                return -1;
    4852        }
    4953
    50         KU_OBJ(dir, dirent);
    51         if((err = vfs_readdir(file, &dir)))
     54    // check dirent structure in user space
     55    error = vmm_v2p_translate( false , dirent , &paddr );
     56
     57    if ( error )
     58    {
     59        printk("\n[ERROR] in %s : user buffer for dirent unmapped = %x\n",
     60               __FUNCTION__ , (intptr_t)dirent );
     61                this->errno = EFAULT;
     62                return -1;
     63    }
     64
     65    // get extended pointer on remote file descriptor
     66    file_xp = process_fd_get_xptr( process , file_id );
     67
     68    if( file_xp == XPTR_NULL )
     69    {
     70        printk("\n[ERROR] in %s : undefined file descriptor index = %d\n",
     71               __FUNCTION__ , file_id );
     72            this->errno = EBADFD;
     73        return -1;
     74    }
     75 
     76    // call the relevant VFS function
     77        error = vfs_readdir( file_xp , &k_dirent );
     78
     79        if( error )
    5280        {
    53                 this->info.errno = (err < 0) ? -err : err;
     81        printk("\n[ERROR] in %s : cannot access directory %d\n",
     82               __FUNCTION__ , file_id );
     83                this->errno = error;
    5484                return -1;
    5585        }
    5686   
     87    // copy dirent to user space
     88    hal_copy_to_uspace( dirent , &k_dirent , sizeof(vfs_dirent_t) );
     89
    5790        return 0;
    58 }
     91
     92}  // end sys_readdir()
  • trunk/kernel/syscalls/sys_rmdir.c

    r1 r23  
    11/*
    2  * sys_rmdir: remove a directory
     2 * sys_rmdir.c - Remove a directory from file system.
     3 *
     4 * Author    Alain Greiner (2016,2017)
    35 *
    46 * Copyright (c) 2015 UPMC Sorbonne Universites
    57 *
    6  * This file is part of ALMOS-kernel.
     8 * This file is part of ALMOS-MKH.
    79 *
    8  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    911 * under the terms of the GNU General Public License as published by
    1012 * the Free Software Foundation; version 2.0 of the License.
    1113 *
    12  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1315 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1416 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1618 *
    1719 * You should have received a copy of the GNU General Public License
    18  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    1921 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2022 */
    2123
    22 #include <cpu.h>
     24#include <hal_types.h>
     25#include <hal_uspace.h>
     26#include <printk.h>
     27#include <errno.h>
    2328#include <vfs.h>
    24 #include <sys-vfs.h>
     29#include <vmm.h>
    2530#include <thread.h>
    26 #include <task.h>
     31#include <process.h>
    2732
     33////////////////////////////////
     34int sys_rmdir( char * pathname )
     35{
     36    error_t     error;
     37    paddr_t     paddr;
     38    uint32_t    length;
     39    char        kbuf[CONFIG_VFS_MAX_PATH_LENGTH];
     40       
     41        thread_t  * this    = CURRENT_THREAD;
     42        process_t * process = this->process;
    2843
    29 int sys_rmdir (char *pathname)
    30 {
    31         register struct thread_s *this;
    32         register struct task_s *task;
    33         struct ku_obj ku_path;
    34         error_t err = 0;
    35        
    36         this = current_thread;
    37         task = current_task;
     44    // check pathname in user space
     45    error = vmm_v2p_translate( false , pathname , &paddr );
    3846
    39         if(!pathname)
     47        if( error )
    4048        {
    41                 this->info.errno = EINVAL;
     49        printk("\n[ERROR] in %s : user buffer unmapped  for thread %x in process %x\n",
     50               __FUNCTION__ , this->trdid , process->pid );
     51                this->errno = EINVAL;
     52                return -1;
     53        }       
     54
     55    // get pathname length
     56    length = hal_strlen_from_uspace( pathname );
     57
     58    if( length >= CONFIG_VFS_MAX_PATH_LENGTH )
     59    {
     60        printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ );
     61                this->errno = ENFILE;
     62        return -1;
     63    }
     64 
     65        // get pathname copy in kernel space
     66    hal_copy_from_uspace( kbuf, pathname, length );
     67
     68    // get cluster and local pointer on reference process
     69    xptr_t      ref_xp  = process->ref_xp;
     70    process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
     71    cxy_t       ref_cxy = GET_CXY( ref_xp );
     72
     73    // get extended pointer on cwd inode
     74    xptr_t cwd_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->vfs_cwd_xp ) );
     75   
     76    // get the cwd lock in read mode from reference process
     77        remote_rwlock_rd_lock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
     78
     79    // call the relevant VFS function
     80        error = vfs_rmdir( cwd_xp,
     81                       kbuf );
     82
     83    // release the cwd lock
     84        remote_rwlock_rd_unlock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
     85
     86    if( error )
     87        {
     88        printk("\n[ERROR] in %s : cannot remove directory %s\n",
     89               __FUNCTION__ , kbuf );
     90                this->errno = error;
    4291                return -1;
    4392        }
     93   
     94        return 0;
    4495
    45         KU_BUFF(ku_path, pathname);
    46         rwlock_wrlock(&task->cwd_lock);
    47 
    48         if((err = vfs_rmdir(&current_task->vfs_cwd, &ku_path)))
    49         {
    50                 current_thread->info.errno = (err < 0) ? -err : err;
    51                 rwlock_unlock(&task->cwd_lock);
    52                 return -1;
    53         }
    54        
    55         rwlock_unlock(&task->cwd_lock);
    56         return 0;
    57 }
     96}  // end sys_rmdir()
  • trunk/kernel/syscalls/sys_sem.c

    r1 r23  
    22 * sys_sem.c - Acces a POSIX unamed semaphore.
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * Authors     Alain Greiner (2016,2017)
    65 *
    7  * This file is part of ALMOS-kernel.
     6 * Copyright (c) UPMC Sorbonne Universites
    87 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     8 * This file is part of ALMOS-MKH.
     9 *
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1718 *
    1819 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2021 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2122 */
    2223
    2324#include <hal_types.h>
    24 #include <hal_uspace.
     25#include <hal_uspace.h>
     26#include <errno.h>
     27#include <thread.h>
     28#include <printk.h>
     29#include <vmm.h>
    2530#include <remote_sem.h>
     31#include <syscalls.h>
    2632
    2733//////////////////////////////////
     
    3137{
    3238        uint32_t             data;   
    33         error_t              error;
     39        paddr_t              paddr;
     40    error_t              error;
    3441
    35     thread_t           * this      = CURRENT_THREAD;
    36         process_t          * process   = CURRENT_PROCESS;
     42    thread_t           * this = CURRENT_THREAD;
    3743
    3844    // check vaddr in user vspace
    39         error = vmm_check_address( process , vaddr , sizeof(unsigned long) );
    40         if( error ) 
     45        error = vmm_v2p_translate( false , vaddr , &paddr );
     46        if( error )
    4147    {
     48        printk("\n[ERROR] in %s : illegal semaphore virtual address = %x\n",
     49               __FUNCTION__ , (intptr_t)vaddr );
    4250        this->errno = error;
    4351        return -1;
     
    4553
    4654    // check value in user vspace
    47     error = vmm_check_address( process , value , sizeof(int*) );
    48         if( error ) 
     55        error = vmm_v2p_translate( false , value , &paddr );
     56        if( error )
    4957    {
     58        printk("\n[ERROR] in %s : illegal argument virtual address = %x\n",
     59               __FUNCTION__ , (intptr_t)value );
    5060        this->errno = error;
    5161        return -1;   
     
    6272
    6373            // call init function
    64             error = remote_sem_init( (intptr_t)vaddr , data );
     74            error = remote_sem_create( (intptr_t)vaddr , data );
    6575
    6676            if ( error )
    6777            {
     78                printk("\n[ERROR] in %s : cannot create semaphore = %x\n",
     79                       __FUNCTION__ , (intptr_t)value );
    6880                this->errno = error;
    6981                return -1;
     
    7991            if( sem_xp == XPTR_NULL )     // user error
    8092            {
     93                printk("\n[ERROR] in %s : semaphore %x not registered\n",
     94                       __FUNCTION__ , (intptr_t)value );
    8195                this->errno = EINVAL;
    8296                return -1;
     
    100114            if( sem_xp == XPTR_NULL )     // user error
    101115            {
     116                printk("\n[ERROR] in %s : semaphore %x not registered\n",
     117                       __FUNCTION__ , (intptr_t)value );
    102118                this->errno = EINVAL;
    103119                return -1;
     
    118134            if( sem_xp == XPTR_NULL )     // user error
    119135            {
     136                printk("\n[ERROR] in %s : semaphore %x not registered\n",
     137                       __FUNCTION__ , (intptr_t)value );
    120138                this->errno = EINVAL;
    121139                return -1;
     
    136154            if( sem_xp == XPTR_NULL )     // user error
    137155            {
     156                printk("\n[ERROR] in %s : semaphore %x not registered\n",
     157                       __FUNCTION__ , (intptr_t)value );
    138158                this->errno = EINVAL;
    139159                return -1;
     
    149169            default:  // undefined operation                       
    150170        {
    151                     this->errno = EINVAL;
    152             return -1;
     171            printk("\n[PANIC] in %s : illegal operation type\n", __FUNCTION__ );
     172            hal_core_sleep();
    153173        }
    154174        }
  • trunk/kernel/syscalls/sys_signal.c

    r1 r23  
    11/*
    2  * sys_sem.c: interface to access signal service
     2 * sys_signal.c - associate a specific signal handler to a given signal.
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012,2013,2014,2015 UPMC Sorbonne Universites
     4 * Authors   Ghassan Almaless (2008,2009,2010,2011,2012)
     5 *           Alain Greiner (2016,2017)
     6 *
     7 * Copyright (c) UPMC Sorbonne Universites
    68 *
    79 * This file is part of ALMOS-kernel.
     
    2123 */
    2224
    23 #include <types.h>
     25#include <hal_types.h>
    2426#include <errno.h>
    2527#include <thread.h>
    26 #include <task.h>
    27 #include <pid.h>
     28#include <printk.h>
    2829#include <signal.h>
    2930
     31//////////////////////////////////
     32int sys_signal( uint32_t   sig_id,
     33                void     * handler )
     34
     35        thread_t  * this = CURRENT_THREAD;
    3036
    31 int sys_signal(uint_t sig, sa_handler_t *handler)
    32 
    33         register struct thread_s *this;
    34         int retval;
    35 
    36         this = current_thread;
    37 
    38         if((sig == 0) || (sig >= SIG_NR) || (sig == SIGKILL) || (sig == SIGSTOP))
     37        if((sig_id == 0) || (sig_id >= SIG_NR) || (sig_id == SIGKILL) || (sig_id == SIGSTOP))
    3938        {
    40                 this->info.errno = EINVAL;
    41                 return SIG_ERROR;
     39        printk("\n[ERROR] in %s : illega signal index = %d\n", __FUNCTION__ , sig_id );
     40                this->errno = EINVAL;
     41                return -1;
    4242        }
    4343
    44         retval = (int) this->task->sig_mgr.sigactions[sig];
    45         this->task->sig_mgr.sigactions[sig] = handler;
     44        // register handler in signal manager for the calling process
     45        this->process->sig_mgr.sigactions[sig_id] = handler;
    4646
    47         sig_dmsg(1, "%s: handler @%x has been registred for signal %d\n",
    48                __FUNCTION__,
    49                handler,
    50                sig);
     47        signal_dmsg("\n[INFO] %s : handler @%x has been registred for signal %d\n",
     48                    __FUNCTION__ , handler , sig_id );
    5149
    52         return retval;
    53 }
    54 
    55 
    56 int sys_sigreturn_setup(void *sigreturn_func)
    57 {
    58         struct thread_s *this;
    59 
    60         this = current_thread;
    61         this->info.attr.sigreturn_func = sigreturn_func;
    62         cpu_context_set_sigreturn(&this->pws, sigreturn_func);
    6350        return 0;
    6451}
    6552
    66 
    67 int sys_kill(pid_t pid, uint_t sig)
    68 {
    69         cid_t   location;
    70         error_t err;
    71 
    72         if((sig == 0) || (sig >= SIG_NR))
    73         {
    74                 err = EINVAL;
    75         }
    76         else
    77         {
    78                 if ( PID_GET_CLUSTER(pid) == current_cid )
    79                         location = current_cid;
    80                 else
    81                         location = task_whereis(pid);
    82 
    83                 err = signal_rise(pid, location, sig);
    84 
    85                 /* No error, return 0 */
    86                 if (!err)
    87                         return 0;
    88         }
    89 
    90         /* Error. Set errno and return */
    91         current_thread->info.errno = err;
    92         return -1;
    93 }
  • trunk/kernel/syscalls/sys_stat.c

    r1 r23  
    11/*
    2  * kern/sys_stat.c - stats a file or directory
     2 * sys_stat.c - Return statistics on a file or directory.
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * Author    Alain Greiner  (2016,2017)
    65 *
    7  * This file is part of ALMOS-kernel.
     6 * Copyright (c) UPMC Sorbonne Universites
    87 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     8 * This file is part of ALMOS-MKH.
     9 *
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1718 *
    1819 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2021 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2122 */
    2223
     24#include <hal_types.h>
     25#include <hal_uspace.h>
     26#include <hal_special.h>
    2327#include <errno.h>
    2428#include <thread.h>
     29#include <printk.h>
    2530#include <vfs.h>
    26 #include <sys-vfs.h>
    27 #include <task.h>
    28 #include <spinlock.h>
    29 #include <cpu-trace.h>
     31#include <vmm.h>
     32#include <process.h>
    3033
     34//////////////////////////////////////////
     35int sys_stat( uint32_t            file_id,
     36              struct vfs_stat_s * stat )
     37{
     38    error_t           error;
     39    paddr_t           paddr;
     40    struct vfs_stat_s k_stat;
     41    xptr_t            file_xp;
     42       
     43        thread_t  * this    = CURRENT_THREAD;
     44        process_t * process = this->process;
    3145
    32 int sys_stat(char *pathname, struct vfs_stat_s *buff, int fd)
    33 {
    34         CPU_HW_TRACE(sys_stat);
    35         struct thread_s *this;
    36         register error_t err = 0;
    37         struct vfs_file_s *file;
    38         struct ku_obj ku_path;
    39         struct task_s *task;
     46    // check stat structure in user space
     47    error = vmm_v2p_translate( false , stat , &paddr );
    4048
    41         file = NULL;
    42         this = current_thread;
    43         task = current_task;
     49        if( error )
     50        {
     51        printk("\n[ERROR] in %s : stat structure unmapped  for thread %x in process %x\n",
     52               __FUNCTION__ , this->trdid , process->pid );
     53                this->errno = EINVAL;
     54                return -1;
     55        }       
    4456
    45         if((buff == NULL) || ((pathname == NULL) && (fd == -1)))
     57    // get extended pointer on remote file descriptor
     58    file_xp = process_fd_get_xptr( process , file_id );
     59
     60    if( file_xp == XPTR_NULL )
     61    {
     62        printk("\n[ERROR] in %s : undefined file descriptor for thread %x in process %x\n",
     63               __FUNCTION__ , this->trdid , process->pid );
     64        this->errno = EBADFD;
     65        return -1;
     66    }
     67
     68    // call the relevant VFS function
     69    error = vfs_stat( file_xp,
     70                      &k_stat );
     71    if( error )
    4672        {
    47                 this->info.errno = EINVAL;
    48                 CPU_HW_TRACE(sys_stat);
     73        printk("\n[ERROR] in %s : cannot access file %d for thread %x in process %x\n",
     74               __FUNCTION__ , file_id , this->trdid , process->pid );
     75                this->errno = error;
    4976                return -1;
    5077        }
     78   
     79    // copy stat to user space
     80    hal_copy_to_uspace( stat , &k_stat , sizeof(struct vfs_stat_s) );
    5181
    52         if(NOT_IN_USPACE((uint_t)buff))
    53         {
    54                 this->info.errno = EPERM;
    55                 CPU_HW_TRACE(sys_stat);
    56                 return -1;
    57         }
     82    hal_wbflush();
    5883
    59         if(pathname == NULL)
    60         {
    61                 if((fd >= CONFIG_TASK_FILE_MAX_NR) || (task_fd_lookup(task, fd, &file)))
    62                 {
    63                         CPU_HW_TRACE(sys_stat);
    64                         return EBADFD;
    65                 }
    66  
    67                 err = vfs_stat(&task->vfs_cwd, NULL, buff, file);
    68         }
    69         else
    70         {
    71                 KU_BUFF(ku_path, pathname);
    72                 rwlock_rdlock(&task->cwd_lock);
    73                 err = vfs_stat(&task->vfs_cwd, &ku_path, buff, NULL);
    74                 rwlock_unlock(&task->cwd_lock);
    75         }
    76  
    77         this->info.errno = err;
    78         CPU_HW_TRACE(sys_stat);
    7984        return 0;
    80 }
     85
     86}  // end sys_stat()
     87
  • trunk/kernel/syscalls/sys_thread_create.c

    r14 r23  
    22 * sys_thread_create.c - creates a new user thread
    33 *
    4  * Author  Ghassan Almaless (2008,2009,2010,2011,2012)
    5  *         Mohamed lamine Karaoui (2015)
    6  *         Alain Greiner (2016)
     4 * Author     Alain Greiner (2016,2017)
    75 *
    86 * Copyright (c) UPMC Sorbonne Universites
     
    2624#include <kernel_config.h>
    2725#include <hal_types.h>
     26#include <hal_uspace.h>
    2827#include <printk.h>
    2928#include <errno.h>
     
    3837#include <spinlock.h>
    3938#include <dqdt.h>
     39#include <rpc.h>
    4040
    4141
     
    4646                        pthread_attr_t * user_attr,     // [in] argument
    4747                        void           * start_func,    // [in] argument
    48                         void           * start_args )   // [in] argument
     48                        void           * start_arg )    // [in] argument
    4949{
    50         pthread_attr_t   attr;             // copy of pthread attributes in kernel space
     50        pthread_attr_t   k_attr;           // copy of pthread attributes in kernel space
    5151        thread_t       * parent;           // pointer on thread executing the pthread_create
    52     xptr_t           xp_parent;        // extended pointer on created thread
    53     thread_t       * child;            // pointer on created child thread
    54     xptr_t           xp_child;         // extended pointer on created thread
     52    xptr_t           parent_xp;        // extended pointer on created thread
     53    thread_t       * child_ptr;        // pointer on created child thread
     54    xptr_t           child_xp;         // extended pointer on created thread
    5555    trdid_t          trdid;            // created thread identifier
    5656    process_t      * process;          // pointer on local process descriptor
     57    paddr_t          paddr;            // unused, required by vmm_v2p_translate()
    5758    error_t          error;
    5859
     
    6465    // get parent thead pointer, extended pointer, and process pointer
    6566        parent     = CURRENT_THREAD;
    66     xp_parent  = XPTR( local_cxy , parent );   
     67    parent_xp  = XPTR( local_cxy , parent );   
    6768        process    = parent->process;
    6869
    69     // check user_attr & start_func arguments
    70         if( user_attr == NULL )
     70    // check user_attr in user space
     71    error = vmm_v2p_translate( false , user_attr , &paddr );
     72
     73        if( error )
    7174        {
    72                 printk("\n[ERROR] in %s : user_attr is NULL\n", __FUNCTION__ );
    73                 return EINVAL;
    74         }
    75         if( start_func== NULL )
    76         {
    77                 printk("\n[ERROR] in %s : start_func is NULL\n", __FUNCTION__ );
    78                 return EINVAL;
     75                printk("\n[ERROR] in %s : user_attr unmapped\n", __FUNCTION__ );
     76                parent->errno = EINVAL;
     77        return -1;
    7978        }
    8079
    81     // copy user_attr structure to kernel space
    82         hal_copy_from_uspace( &attr , user_attr , sizeof(pthread_attr_t) );
     80    // check start_func in user space
     81    error = vmm_v2p_translate( false , start_func , &paddr );
     82
     83        if( error )
     84        {
     85                printk("\n[ERROR] in %s : start_func unmapped\n", __FUNCTION__ );
     86                parent->errno = EINVAL;
     87        return -1;
     88        }
     89
     90    // check start_arg in user space
     91    if( start_arg != NULL ) error = vmm_v2p_translate( false , start_arg , &paddr );
     92
     93        if( error )
     94        {
     95                printk("\n[ERROR] in %s : start_arg unmapped\n", __FUNCTION__ );
     96                parent->errno = EINVAL;
     97        return -1;
     98        }
     99
     100    // copy user_attr structure from user space to kernel space
     101        hal_copy_from_uspace( &k_attr , user_attr , sizeof(pthread_attr_t) );
    83102
    84103    // check/set "cxy" attribute
    85         if( attr.flags & PT_FLAG_CLUSTER_DEFINED )
     104        if( k_attr.attributes & PT_ATTR_CLUSTER_DEFINED )
    86105    {
    87         if( cluster_is_undefined( attr.cxy ) )
     106        if( cluster_is_undefined( k_attr.cxy ) )
    88107        {
    89                     printk("\n[ERROR] in %s : illegal target cluster = %x\n",
    90                    __FUNCTION__ , attr.cxy );
    91                     return = EINVAL;
     108                    printk("\n[ERROR] in %s : illegal target cluster attribute = %x\n",
     109                   __FUNCTION__ , k_attr.cxy );
     110                    parent->errno = EINVAL;
     111            return -1;
    92112        }
    93113    }
    94114    else
    95115    {
    96         attr.cxy = dqdt_get_cluster_for_process();
     116        k_attr.cxy = dqdt_get_cluster_for_process();
    97117    }
    98118
    99     // set "pid", "start_func" & "start_args" attributes
    100     attr.pid        = process->pid;
    101     attr.start_func = start_func;
    102     attr.start_args = start_args;
    103 
    104119    // create the thread, using a RPC if required
    105     // this returns "error", "child", and "xp_child"
    106     if( attr.cxy == local_cxy )                 // target cluster is local
     120    // this returns "error", "child", and "child_xp"
     121 
     122    if( k_attr.cxy == local_cxy )                         // target cluster is local
    107123    {
    108         // allocate a stack from local VMM
    109         vseg_t * vseg = vmm_create_vseg( process,
    110                                          0,
    111                                          0,
    112                                          VSEG_TYPE_STACK,
    113                                          local_cxy );
    114         if( vseg == NULL )
    115         {
    116                     printk("\n[ERROR] in %s for : cannot create stack vseg\n", __FUNCTION__ );
    117                     return = EINVAL;
    118         }
    119124
    120125        // create thread in local cluster
    121         error = thread_user_create( &child,
    122                                     &attr,
    123                                     vseg->min,
    124                                     vseg->max - vseg->min );
     126        error = thread_user_create( process->pid,
     127                                    start_func,
     128                                    start_arg,
     129                                    &k_attr,
     130                                    &child_ptr );
    125131
    126         xp_child = XPTR( local_cxy , thread );
     132        child_xp = XPTR( local_cxy , child_ptr );
    127133    }
    128134    else                                                 // target cluster is remote
    129135    {
    130         rpc_thread_user_create( attr.cxy , &attr , &error , &xp_child );
    131         child = (thread_t *)GET_PTR( xp_child );
     136        rpc_thread_user_create_client( k_attr.cxy,
     137                                       process->pid,
     138                                       start_func,
     139                                       start_arg,
     140                                       &k_attr,
     141                                       &child_xp,
     142                                       &error );
     143
     144        child_ptr = (thread_t *)GET_PTR( child_xp );
    132145    }
    133146
     
    140153
    141154    // returns trdid to user space
    142     trdid = hal_remote_lw( XPTR( attr.cxy , &child->trdid ) );   
     155    trdid = hal_remote_lw( XPTR( k_attr.cxy , &child_ptr->trdid ) );   
    143156        hal_copy_to_uspace( new_thread , &trdid , sizeof(pthread_t) );
    144157   
    145158    // register new-thread in parent-thread children list if required
    146     if( attr.flags & PT_FLAG_DETACH == 0 ) thread_child_parent_link( xp_parent , xp_child );
     159    if( (k_attr.attributes & PT_ATTR_DETACH) == 0 )
     160        thread_child_parent_link( parent_xp , child_xp );
    147161
    148162        tm_end = hal_time_stamp();
     
    150164        thread_dmsg("\n[INFO] %s created thread %x for process %x in cluster %x\n"
    151165                "  start_cycle = %d / end_cycle = %d\n",
    152                    trdid , process->pid , attr.cxy , tm_start , tm_end );
     166                   trdid , process->pid , k_attr.cxy , tm_start , tm_end );
    153167        return 0;
    154168
  • trunk/kernel/syscalls/sys_thread_detach.c

    r1 r23  
    11/*
    2  * kern/sys_thread_detach.c - detach a joinable thread
     2 * sys_thread_detach.c - detach a joinable thread
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
     4 * Authors   Alain Greiner (2016,2017)
     5 *
    56 * Copyright (c) 2011,2012 UPMC Sorbonne Universites
    67 *
    7  * This file is part of ALMOS-kernel.
     8 * This file is part of ALMOS-MKH.
    89 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1718 *
    1819 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2021 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2122 */
    2223
    23 #include <list.h>
     24#include <hal_types.h>
     25#include <hal_remote.h>
     26#include <hal_special.h>
    2427#include <thread.h>
    25 #include <kmem.h>
    26 #include <kmagics.h>
    2728#include <errno.h>
    28 #include <task.h>
    29 #include <spinlock.h>
     29#include <printk.h>
    3030
    31 int sys_thread_detach (pthread_t tid)
     31//////////////////////////////////////
     32int sys_thread_detach( trdid_t trdid )
    3233{
    33         register struct task_s *task;
    34         struct thread_s *target_th;
    35         uint_t state;
    36         error_t err;
     34    xptr_t       target_xp;
     35        thread_t   * target_ptr;
     36    cxy_t        target_cxy;
     37    ltid_t       target_ltid;
     38    uint32_t     flags;
    3739
    38         task = current_task;
     40        thread_t   * this    = CURRENT_THREAD;
     41    process_t  * process = this->process;
    3942
    40         if(tid > task->max_order)
     43    // get target thread ltid and cxy
     44    target_ltid = LTID_FROM_TRDID( trdid );
     45    target_cxy  = CXY_FROM_TRDID( trdid );
     46
     47    // check trdid argument
     48        if( (target_ltid >= CONFIG_THREAD_MAX_PER_CLUSTER) || cluster_is_undefined( target_cxy ) ) 
    4149        {
    42                 err = EINVAL;
    43                 goto fail_arg;
    44         }
    45  
    46         spinlock_lock(&task->th_lock);
    47 
    48         target_th = task->th_tbl[tid];
    49    
    50         if((target_th == NULL)                 ||
    51            (target_th->signature != THREAD_ID) ||
    52            (target_th->info.attr.key != tid))
    53         {
    54                 err = ESRCH;
    55                 goto fail_srch;
    56         }
    57  
    58         if(!(thread_isJoinable(target_th)))
    59         {
    60                 err = EINVAL;
    61                 goto fail_not_joinable;
    62         }
    63  
    64         err = 0;
    65 
    66         spinlock_lock(&target_th->lock);
    67 
    68         thread_clear_joinable(target_th);
    69 
    70         if((target_th->info.join == NULL) &&
    71            !(state = wait_queue_isEmpty(&target_th->info.wait_queue)))
    72         {
    73                 wakeup_one(&target_th->info.wait_queue, WAIT_ANY);
     50        printk("\n[ERROR] in %s : illegal trdid argument\n", __FUNCTION__ );
     51                this->errno = EINVAL;
     52                return -1;
    7453        }
    7554
    76         spinlock_unlock(&target_th->lock);
    77  
    78 fail_not_joinable:
    79 fail_srch:
    80         spinlock_unlock(&task->lock);
     55    // get extended pointer on target thread
     56        target_xp  = thread_get_xptr( process->pid , trdid );
    8157
    82 fail_arg:
    83         current_thread->info.errno = err;
    84         return err;
    85 }
     58    if( target_xp == XPTR_NULL )
     59    {
     60        printk("\n[ERROR] in %s : target thread not found\n", __FUNCTION__ );
     61        this->errno = ESRCH;
     62        return -1;
     63    }
     64
     65    // get local pointer on target thread
     66    target_ptr = (thread_t *)GET_PTR( target_xp );
     67
     68    // get target thread flags
     69    flags = hal_remote_lw( XPTR( target_cxy , &target_ptr->flags ) );
     70
     71    // check target thread joinable
     72    if( flags & THREAD_FLAG_DETACHED )
     73    {
     74        printk("\n[ERROR] in %s : target thread not joinable\n", __FUNCTION__ );
     75        this->errno = EINVAL;
     76        return -1;
     77    }
     78
     79    // atomically set the thread DETACHED flag
     80    hal_remote_atomic_or( XPTR( target_cxy , &target_ptr->flags ) , THREAD_FLAG_DETACHED );
     81
     82        return 0;
     83
     84}  // end sys_thread_detach()
  • trunk/kernel/syscalls/sys_thread_exit.c

    r16 r23  
    11/*
    2  * kern/sys_thread_exit.c - terminates the execution of current thread
     2 * sys_thread_exit.c - terminates the execution of current thread
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * Authors       Ghassan Almaless (2008,2009,2010,2011,2012)
     5 *               Alain Greiner (2016,2017)
    66 *
    7  * This file is part of ALMOS-kernel.
     7 * Copyright (c) UPMC Sorbonne Universites
    88 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     9 * This file is part of ALMOS-MKH.
     10 *
     11 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1012 * under the terms of the GNU General Public License as published by
    1113 * the Free Software Foundation; version 2.0 of the License.
    1214 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     15 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1416 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1517 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1719 *
    1820 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     21 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2022 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2123 */
    2224
    23 #include <list.h>
     25#include <hal_types.h>
     26#include <hal_irqmask.h>
    2427#include <thread.h>
     28#include <core.h>
    2529#include <scheduler.h>
    26 #include <wait_queue.h>
    27 #include <cluster.h>
    28 #include <dqdt.h>
    29 #include <process.h>
     30#include <printk.h>
    3031
    31 ///////////////////////////////////////
    32 int sys_thread_exit ( void * exit_val )
     32
     33////////////////////////////////////////
     34int sys_thread_exit( void * exit_value )
    3335{
    3436        thread_t  * this = CURRENT_THREAD;
    3537    core_t    * core = this->core;
    36         bool_t      isEmpty;
    37         bool_t      isReleased;
    3838    uint32_t    irq_state;
    3939
    40         // update DQDT TODO must be done by thread destroy
    41         if(this->process->pid != 1) dqdt_local_update_threads( -1 );
     40    // register the exit_value in thread descriptor
     41    this->exit_value = exit_value;
    4242
    43         spinlock_lock( &this->lock );
     43    // we enter the join loop to wait the join
     44    // only if thread is joinable
     45    if( (this->flags & THREAD_FLAG_DETACHED) == 0 )
     46    {
     47            while( 1 )
     48            {
     49            // take the lock protecting the flags
     50                remote_spinlock_lock( XPTR( local_cxy, &this->flags_lock ) );
    4451
    45         if(!(thread_isJoinable(this)))
    46         {
    47                 goto exit_dead;
     52            // check the JOIN flag
     53            if( this->flags & THREAD_FLAG_JOIN )       // parent made a join
     54            {
     55                // unblock the parent thread
     56                thread_unblock( this->parent , THREAD_BLOCKED_JOIN );
     57
     58                // release the lock protecting the flags
     59                    remote_spinlock_unlock( XPTR( local_cxy, &this->flags_lock ) );
     60
     61                // exit while
     62                break;
     63            }
     64            else                                       // no join done by parent thread
     65            {
     66                // set the EXIT flag
     67                this->flags |= THREAD_FLAG_EXIT;
     68
     69                // block this thread
     70                thread_block( this , THREAD_BLOCKED_EXIT );
     71
     72                // release the lock protecting the flags
     73                    remote_spinlock_unlock( XPTR( local_cxy, &this->flags_lock ) );
     74
     75                // deschedule
     76                sched_yield();
     77            }     
     78        }
    4879        }
    49 
    50         // Check if there's a thread waiting the end of calling thread
    51         isEmpty = wait_queue_isEmpty(&this->info.wait_queue);
    52 
    53         if(isEmpty)
    54         {
    55                 this->info.exit_value = exit_val;
    56                 wait_on(&this->info.wait_queue, WAIT_ANY);
    57                 spinlock_unlock_nosched(&this->lock);
    58                 sched_sleep(this);
    59         }
    60         else
    61         {
    62                 this->info.join->info.exit_value = exit_val;
    63                 wakeup_one(&this->info.wait_queue, WAIT_ANY);
    64                 spinlock_unlock_nosched(&this->lock);
    65         }
    66 
    67 exit_dead:
    68 
    69         isReleased = false;
    7080
    7181        // Release FPU if required
    7282        hal_disable_irq( &irq_state );
    73         if(core->fpu_owner == this)
    74         {
    75                 core->fpu_owner = NULL;
    76                 isReleased = true;
    77         }
     83        if( core->fpu_owner == this )  core->fpu_owner = NULL;
    7884        hal_restore_irq( irq_state );
    7985
    80         if(isReleased)
    81         {
    82                 thread_dmsg(1, "INFO: Thread %x has released FPU on CPU %d\n",
    83                        this,
    84                        current_cpu->gid);
    85         }
     86        // suicide
     87    thread_kill( this );
     88        return 0;       
    8689
    87         sched_exit(this);
    88 
    89         PANIC ("Thread %x, CPU %d must never return", this, current_cpu->gid);
    90         return -1;              /* Fake return ! */
    91 }
     90}  // end sys_thread_exit()
  • trunk/kernel/syscalls/sys_thread_join.c

    r1 r23  
    11/*
    2  * kern/sys_thread_join.c - passive wait on the end of a given thread
     2 * sys_thread_join.c - passive wait on the end of a given thread.
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
     4 * Authors    Alain Greiner (2016,2017)
     5 *
    56 * Copyright (c) 2011,2012 UPMC Sorbonne Universites
    67 *
    7  * This file is part of ALMOS-kernel.
     8 * This file is part of ALMOS-MKH.
    89 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1718 *
    1819 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2021 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2122 */
    2223
    23 #include <list.h>
     24#include <hal_types.h>
     25#include <hal_remote.h>
     26#include <hal_special.h>
    2427#include <thread.h>
     28#include <vmm.h>
    2529#include <scheduler.h>
    26 #include <kmem.h>
    2730#include <errno.h>
    28 #include <task.h>
    29 #include <spinlock.h>
     31#include <printk.h>
     32#include <remote_spinlock.h>
    3033
    31 int sys_thread_join (pthread_t tid, void **thread_return)
     34///////////////////////////////////////
     35int sys_thread_join ( trdid_t    trdid,
     36                      void    ** exit_value )
    3237{
    33         register struct task_s *task;
    34         register struct thread_s *this;
    35         register struct thread_s *target_th;
    36         register uint_t state = 0;
    37         void *retval;
    38         int err;
     38    xptr_t        target_xp;
     39    thread_t    * target_ptr;
     40    cxy_t         target_cxy;
     41    ltid_t        target_ltid;
     42    uint32_t      flags;        // target thread flags
     43    intptr_t      value;        // value returned by target thread
     44    paddr_t       paddr;        // required for vmm_v2p_translate()
    3945
    40         this   = current_thread;
    41         task   = this->task;
    42         retval = 0;
     46        thread_t  * this    = CURRENT_THREAD;
     47    process_t * process = this->process;
    4348
    44         if((tid > task->max_order) ||
    45            ((thread_return != NULL) &&
    46             (NOT_IN_USPACE((uint_t)thread_return + sizeof(void*)))))
     49    // get target thread ltid and cxy
     50    target_ltid = LTID_FROM_TRDID( trdid );
     51    target_cxy  = CXY_FROM_TRDID( trdid );
     52
     53    // check trdid argument
     54        if( (target_ltid >= CONFIG_THREAD_MAX_PER_CLUSTER) || cluster_is_undefined( target_cxy ) ) 
    4755        {
    48                 err = EINVAL;
    49                 goto fail_arg;
     56        printk("\n[ERROR] in %s : illegal trdid argument\n", __FUNCTION__ );
     57                this->errno = EINVAL;
     58                return -1;
    5059        }
    5160
    52         /* try to write to userland address */
    53         if(thread_return)
     61    // check exit_value argument
     62        if( (exit_value != NULL) && (vmm_v2p_translate( false , exit_value , &paddr ) != 0 ) )
    5463        {
    55                 if((err = cpu_copy_to_uspace(thread_return, &retval, sizeof(void *))))
    56                         goto fail_uspace_ret;
     64        printk("\n[ERROR] in %s : illegal exit_value argument\n", __FUNCTION__ );
     65                this->errno = EINVAL;
     66                return -1;
    5767        }
    5868
    59         spinlock_lock(&task->th_lock);
    60         target_th = task->th_tbl[tid];
     69    // check target thread != this thread
     70    if( this->trdid == trdid )
     71    {
     72        printk("\n[ERROR] in %s : this thread == target thread\n", __FUNCTION__ );
     73        this->errno = EDEADLK;
     74        return -1;
     75    }
    6176
    62         if((target_th == NULL)                 ||
    63            (target_th->signature != THREAD_ID) ||
    64            (target_th->info.attr.key != tid))
    65         {
    66                 err = ESRCH;
    67                 goto fail_srch;
    68         }
     77    // get extended pointer on target thread
     78        target_xp  = thread_get_xptr( process->pid , trdid );
    6979
    70         if(target_th == this)
    71         {
    72                 err = EDEADLK;
    73                 goto fail_deadlock;
    74         }
     80    if( target_xp == XPTR_NULL )
     81    {
     82        printk("\n[ERROR] in %s : target thread not found\n", __FUNCTION__ );
     83        this->errno = ESRCH;
     84        return -1;
     85    }
    7586
    76         if(!(thread_isJoinable(target_th)))
    77         {
    78                 err = EINVAL;
    79                 goto fail_joinable;
    80         }
    81    
    82         spinlock_lock(&target_th->lock);
    83    
    84         if(target_th->info.join != NULL)
    85         {
    86                 spinlock_unlock(&target_th->lock);
    87                 err = EINVAL;
    88                 goto fail_joined;
    89         }
     87    // get cluster and local pointer on target thread
     88    target_ptr = (thread_t *)GET_PTR( target_xp );
    9089
    91         // Get the exit code of the target thread
    92         if ((state=wait_queue_isEmpty(&target_th->info.wait_queue)))
    93         {
    94                 target_th->info.join = this;
    95                 wait_on(&target_th->info.wait_queue, WAIT_ANY);
    96                 spinlock_unlock(&target_th->lock);
    97                 spinlock_unlock_nosched(&task->th_lock);
    98                 sched_sleep(this);
    99                 retval = this->info.exit_value;
    100         }
    101         else
    102         {
    103                 retval = target_th->info.exit_value;
    104                 wakeup_one(&target_th->info.wait_queue, WAIT_ANY);
    105                 spinlock_unlock(&target_th->lock);
    106                 spinlock_unlock(&task->th_lock);
    107         }
     90    // check target thread joinable
     91    flags = hal_remote_lw( XPTR( target_cxy , &target_ptr->flags ) );
     92    if( flags & THREAD_FLAG_DETACHED )
     93    {
     94        printk("\n[ERROR] in %s : target thread not joinable\n", __FUNCTION__ );
     95        this->errno = EINVAL;
     96        return -1;
     97    }
    10898
    109         /* Probably will not fail */
    110         if(thread_return)
    111         {
    112                 if((err = cpu_copy_to_uspace(thread_return, &retval, sizeof(void *))))
    113                         goto fail_uspace;
    114         }
     99    // check kernel stack overflow
     100    if( target_ptr->signature != THREAD_SIGNATURE )
     101    {
     102        printk("\n[PANIC] in %s : kernel stack overflow\n", __FUNCTION__ );
     103        hal_core_sleep();
     104    }
    115105
    116         return 0;
     106    // wait target thread exit
     107    while( 1 )
     108    {
     109        // take the target thread lock protecting flags     
     110        remote_spinlock_lock( XPTR( target_cxy , &target_ptr->flags_lock ) );
    117111
    118 fail_joined:
    119 fail_joinable:
    120 fail_deadlock:
    121 fail_srch:
    122         spinlock_unlock(&task->th_lock);
     112        // get the remote thread flags
     113        flags = hal_remote_lw( XPTR( target_cxy , &target_ptr->flags ) );
    123114
    124 fail_uspace:
    125 fail_uspace_ret:
    126 fail_arg:
    127         this->info.errno = err;
    128         return err;
    129 }
     115        // check the EXIT flag
     116        if( flags & THREAD_FLAG_EXIT )   // target made an exit
     117        {
     118            // unblock the target thread
     119            thread_unblock( target_xp , THREAD_BLOCKED_EXIT );
     120
     121            // release the target thread lock protecting flags     
     122            remote_spinlock_unlock( XPTR( target_cxy , &target_ptr->flags_lock ) );
     123
     124            // exit while
     125            break;
     126        }
     127        else                             // no exit done by target thread
     128        {
     129            // set the JOIN flag in target thread
     130            hal_remote_atomic_or( XPTR( target_xp , &target_ptr->flags ) ,
     131                                  THREAD_BLOCKED_JOIN );
     132
     133            // block this thread
     134            thread_block( this , THREAD_BLOCKED_JOIN );
     135
     136            // release the target thread lock protecting flags
     137                remote_spinlock_unlock( XPTR( target_cxy , &target_ptr->flags_lock ) );
     138
     139            // deschedule
     140            sched_yield();
     141        }
     142    }
     143
     144    // return exit_value from target thread descriptor
     145    value = (intptr_t)hal_remote_lpt( XPTR( target_cxy , &target_ptr->exit_value ) );
     146    *exit_value = (void *)value;
     147    return 0;
     148
     149}  // end sys_thread_join()
  • trunk/kernel/syscalls/sys_thread_sleep.c

    r1 r23  
    11/*
    2  * kern/sys_thread_sleep.c - puts the current thread in sleep state
     2 * sys_thread_sleep.c - put the calling thread in sleep state
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * Author    Alain Greiner (2016,2017)
    65 *
    7  * This file is part of ALMOS-kernel.
     6 * Copyright (c) UPMC Sorbonne Universites
    87 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     8 * This file is part of ALMOS-MKH.
     9 *
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1718 *
    1819 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2021 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2122 */
    2223
     24#include <hal_special.h>
    2325#include <scheduler.h>
    2426#include <thread.h>
    25 #include <task.h>
     27#include <printk.h>
    2628
     29//////////////////////
    2730int sys_thread_sleep()
    2831{
    29         struct thread_s *this;
     32    thread_t * this = CURRENT_THREAD;
    3033
    31         this = current_thread;
     34    thread_dmsg("\n[INFO] %s : thread %x in process %x goes to sleep at cycle %d\n",
     35                __FUNCTION__ , this->trdid , this->process->pid , hal_time_stamp() );
    3236
    33         if(this->info.isTraced == true)
    34         {
    35                 printk(INFO, "%s: cpu %d, pid %d, tid %d, asked to go sleep [%d]\n",
    36                        __FUNCTION__,
    37                        cpu_get_id(),
    38                        this->task->pid,
    39                        this->info.order,
    40                        cpu_time_stamp());
    41         }
     37    thread_block( CURRENT_THREAD , THREAD_BLOCKED_GLOBAL );
     38    sched_yield();
    4239
    43         thread_set_cap_wakeup(this);
    44         sched_sleep(this);
    45  
    46         if(this->info.isTraced == true)
    47         {
    48                 printk(INFO, "%s: cpu %d, pid %d, tid %d, resuming [%d]\n",
    49                        __FUNCTION__,
    50                        cpu_get_id(),
    51                        this->task->pid,
    52                        this->info.order,
    53                        cpu_time_stamp());
    54         }
     40    thread_dmsg("\n[INFO] %s : thread %x in process %x resume at cycle\n",
     41                __FUNCTION__ , this->trdid , this->process->pid , hal_time_stamp() );
    5542
    5643        return 0;
    57 }
     44}  // end sys_thread_sleep()
  • trunk/kernel/syscalls/sys_thread_wakeup.c

    r1 r23  
    11/*
    2  * kern/sys_thread_wakeup.c - wakeup all indicated threads
     2 * sys_thread_wakeup.c - wakeup all indicated threads
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * Author    Alain Greiner (2016,2017)
    65 *
    7  * This file is part of ALMOS-kernel.
     6 * Copyright (c) UPMC Sorbonne Universites
    87 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     8 * This file is part of ALMOS-MKH.
     9 *
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1718 *
    1819 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2021 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2122 */
    2223
     24#include <hal_types.h>
     25#include <thread.h>
     26#include <printk.h>
     27#include <process.h>
    2328#include <errno.h>
    24 #include <kmagics.h>
    25 #include <cpu.h>
    26 #include <kdmsg.h>
    27 #include <cluster.h>
    28 #include <task.h>
    29 #include <scheduler.h>
    30 #include <thread.h>
    3129
    32 /*
    33  * FIXME: define spinlock_rdlock() so all locking on task->th_lock
    34  * becoms rdlock but on join/detach/destroy
    35  */
    36 int sys_thread_wakeup(pthread_t tid, pthread_t *tid_tbl, uint_t count)
     30//////////////////////////////////////
     31int sys_thread_wakeup( trdid_t trdid )
    3732{
    38         struct task_s *task;
    39         struct thread_s *this;
    40         struct thread_s *target;
    41         pthread_t tbl[100];
    42         void *listner;
    43         uint_t event;
    44         sint_t i;
    45         error_t err;
     33        thread_t  * this    = CURRENT_THREAD;
     34    process_t * process = this->process;
    4635
    47         this = current_thread;
    48         task = this->task;
    49         i = -1;
     36    // get target thread ltid and cxy
     37    ltid_t   target_ltid = LTID_FROM_TRDID( trdid );
     38    cxy_t    target_cxy  = CXY_FROM_TRDID( trdid );
    5039
    51         if(tid_tbl != NULL)
     40    // check trdid argument
     41        if( (target_ltid >= CONFIG_THREAD_MAX_PER_CLUSTER) || cluster_is_undefined( target_cxy ) ) 
    5242        {
    53                 if((NOT_IN_USPACE((uint_t)tid_tbl + (count*sizeof(pthread_t)))) ||
    54                    (count == 0) || (count > 100))
    55                 {
    56                         err = -1;
    57                         goto fail_tid_tbl;
    58                 }
    59 
    60                 if((err = cpu_copy_from_uspace(&tbl[0], tid_tbl, sizeof(pthread_t*) * count)))
    61                         goto fail_usapce;
    62 
    63                 if(tbl[0] != tid)
    64                 {
    65                         err = -2;
    66                         goto fail_first_tid;
    67                 }
    68         }
    69         else
    70         {
    71                 count = 1;
    72                 tbl[0] = tid;
     43        printk("\n[ERROR] in %s : illegal trdid argument\n", __FUNCTION__ );
     44                this->errno = EINVAL;
     45                return -1;
    7346        }
    7447
    75         for(i = 0; i < count; i++)
    76         {
    77                 tid = tbl[i];
     48    // get extended pointer on target thread
     49    xptr_t thread_xp = thread_get_xptr( process->pid , trdid );
    7850
    79                 if(tid > task->max_order)
    80                 {
    81                         err = -3;
    82                         goto fail_tid;
    83                 }
     51    if( thread_xp == XPTR_NULL )
     52    {
     53        printk("\n[ERROR] in %s : cannot find thread %x in process %x/n",
     54               __FUNCTION__ , trdid , CURRENT_THREAD->process->pid );
     55        CURRENT_THREAD->errno = EINVAL;
     56        return -1;
     57    }
    8458
    85                 target = task->th_tbl[tid];
    86    
    87                 if((target == NULL) || (target->signature != THREAD_ID))
    88                 {
    89                         err = -4;
    90                         goto fail_target;
    91                 }
     59    // unblock target thread
     60    thread_unblock( thread_xp , THREAD_BLOCKED_GLOBAL );
    9261
    93                 listner = sched_get_listner(target, SCHED_OP_UWAKEUP);
    94                 event = sched_event_make(target,SCHED_OP_UWAKEUP);
    95    
    96                 if(this->info.isTraced == true)
    97                 {
    98                         printk(INFO,"%s: tid %d --> tid %d [%d][%d]\n",
    99                                __FUNCTION__,
    100                                this->info.order,
    101                                tid,
    102                                cpu_time_stamp(),
    103                                i);
    104                 }
    105 
    106                 sched_event_send(listner,event);
    107                 cpu_wbflush();
    108         }
    109 
    110         return 0;
    111 
    112 fail_target:
    113 fail_tid:
    114 fail_first_tid:
    115 fail_usapce:
    116 fail_tid_tbl:
    117 
    118         printk(INFO, "%s: cpu %d, pid %d, tid %x, i %d, count %d, ttid %x, request has failed with err %d [%d]\n",
    119                __FUNCTION__,
    120                cpu_get_id(),
    121                task->pid,
    122                this,
    123                i,
    124                count,
    125                tid,
    126                err,
    127                cpu_time_stamp());
    128  
    129         this->info.errno = EINVAL;
    130         return -1;
    131 }
     62    return 0;
     63}  // end sys_thread_wakeup()
  • trunk/kernel/syscalls/sys_thread_yield.c

    r1 r23  
    11/*
    2  * kern/sys_thread_yield.c - calls the scheduler to yield current CPU
     2 * sys_thread_yield.c - calls the scheduler to yield
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
     4 * Authors       Ghassan Almaless (2008,2009,2010,2011,2012)
     5 *               Alain Greiner (2016,2017)
     6 *
    57 * Copyright (c) 2011,2012 UPMC Sorbonne Universites
    68 *
    7  * This file is part of ALMOS-kernel.
     9 * This file is part of ALMOS-MKH.
    810 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     11 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1012 * under the terms of the GNU General Public License as published by
    1113 * the Free Software Foundation; version 2.0 of the License.
    1214 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     15 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1416 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1517 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1719 *
    1820 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     21 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2022 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2123 */
    2224
    23 #include <thread.h>
    2425#include <scheduler.h>
    2526
    2627int sys_thread_yield()
    2728{
    28         return sched_yield(current_thread);
     29        sched_yield();
     30        return 0;
    2931}
  • trunk/kernel/syscalls/sys_trace.c

    r15 r23  
    11/*
    2  * kern/sys_ps.c - show kernel active processes and threads
     2 * sys_trace.c - show kernel active processes and threads
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012,2013,2014,2015 UPMC Sorbonne Universites
     4 * Author    Alain Greiner (c) (2016,2017)
    65 *
    7  * This file is part of ALMOS-kernel.
     6 * Copyright (c) UPMC Sorbonne Universites
    87 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     8 * This file is part of ALMOS-MKH.
     9 *
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1718 *
    1819 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2021 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2122 */
    2223
    23 #include <types.h>
    24 #include <task.h>
    25 #include <pid.h>
     24#include <hal_types.h>
     25#include <hal_special.h>
     26#include <printk.h>
    2627#include <thread.h>
    27 #include <vmm.h>
    2828#include <errno.h>
    29 #include <utils.h>
    30 #include <rpc.h>
    31 #include <cluster.h>
     29#include <syscalls.h>
    3230
    33 extern error_t ps_func(void *param);
     31//////////////////////////////////
     32int sys_trace( uint32_t operation,
     33               pid_t    pid,
     34               uint32_t trdid )
     35{
     36    // get extended pointer on target thread
     37    xptr_t thread_xp = thread_get_xptr( pid , trdid );
    3438
    35 /* TODO: add remote support. */
    36 static error_t sys_ps_check_thread(pid_t pid, uint_t tid, struct thread_s **th_ptr)
    37 {
    38         struct task_s *task;
    39         struct thread_s *thread;
    40         cid_t  location;
     39    if( thread_xp == XPTR_NULL )
     40    {
     41        printk("\n[ERROR] in %s : undefined thread for PID = %x / TRDID = %x\n",
     42               __FUNCTION__ , pid , trdid );
     43        CURRENT_THREAD->errno = EINVAL;
     44        return -1;
     45    }
    4146
    42         if(pid == PID_MIN_LOCAL)
    43                 return EINVAL;
     47    if( operation == TRACE_OFF )
     48    {
     49        // desactivate thread trace TODO
    4450
    45         location = task_whereis(pid);
     51            printk("\n[INFO] %s : trace OFF  for thread %x in process %x\n",
     52               __FUNCTION__ , trdid , pid );
     53    }
     54    else if( operation == TRACE_ON )
     55    {
     56        // activate thread trace TODO
     57                   
     58            printk("\n[INFO] %s : trace ON for thread %x in process %x\n",
     59               __FUNCTION__ , trdid , pid );
     60    }
     61    else
     62    {
     63        printk("\n[ERROR] in %s : undefined operation\n", __FUNCTION__ );
     64        CURRENT_THREAD->errno = EINVAL;
     65        return -1;
     66    }
    4667
    47         tasks_manager_lock();
    48         if ( location == current_cid )
    49         {
    50                 task = task_lookup(pid)->task;
     68    hal_wbflush();
    5169
    52                 if((task == NULL) || (tid > task->max_order))
    53                         return EINVAL;
     70    return 0;
    5471
    55                 thread = task->th_tbl[tid];
    56 
    57                 if((thread == NULL)                 ||
    58                    (thread->signature != THREAD_ID) ||
    59                    (thread->info.attr.key != tid))
    60                 {
    61                         return ESRCH;
    62                 }
    63 
    64                 *th_ptr = thread;
    65                 return 0;
    66         }
    67         else
    68         {
    69                 printk(WARNING, "%s: cluster %u can't execute this function on remote task (pid %u on cluster %u)\n",   \
    70                                 __FUNCTION__, current_cid, pid, location);
    71                 return ENOSYS;
    72         }
    73         tasks_manager_unlock();
    74 }
    75 
    76 /*TODO: use RPC_ARG_NULL instead of sending a useless variable.
    77  * It's not urgent, it's a minor change.
    78  */
    79 RPC_DECLARE(__ps_func,                                  \
    80                 RPC_RET( RPC_RET_PTR(error_t, err) ),   \
    81                 RPC_ARG( RPC_ARG_PTR(error_t, foo) )    \
    82            )
    83 {
    84         *err = ps_func(NULL);
    85 }
    86 
    87 int sys_ps(uint_t cmd, pid_t pid, uint_t tid)
    88 {
    89         cid_t next;
    90         error_t err;
    91         struct thread_s *thread;
    92         struct kernel_iter_s *kernel_iter;
    93 
    94         err = 0;
    95 
    96         switch(cmd)
    97         {
    98         case TASK_PS_TRACE_OFF:
    99                 err = sys_ps_check_thread(pid, tid, &thread);
    100                 if(err) goto fail_trace_off;
    101                 thread->info.isTraced = false;
    102                 cpu_wbflush();
    103                 printk(INFO,"INFO: pid %d, tid %x, tracing is turned [OFF]\n", pid, tid);
    104                 break;
    105 
    106         case TASK_PS_TRACE_ON:
    107                 err = sys_ps_check_thread(pid, tid, &thread);
    108                 if(err) goto fail_trace_on;
    109                 thread->info.isTraced = true;
    110                 cpu_wbflush();
    111                 printk(INFO,"INFO: pid %d, tid %x, tracing is turned [ON]\n", pid, tid);
    112                 break;
    113 
    114         case TASK_PS_SHOW:
    115                 kernel_foreach_backward(kernel_iter, next)
    116                 {
    117                         RCPC( next, RPC_PRIO_PS, __ps_func,
    118                               RPC_RECV( RPC_RECV_OBJ(err) ),
    119                               RPC_SEND( RPC_SEND_OBJ(err) )
    120                            );
    121                 }
    122                 break;
    123         }
    124 
    125 fail_trace_on:
    126 fail_trace_off:
    127         current_thread->info.errno = err;
    128         return err;
    129 }
     72}  // end sys_trace()
  • trunk/kernel/syscalls/sys_undefined.c

    r15 r23  
    11/*
    2  * kern/sys_dma_memcpy.c - exported DMA access to user process
     2 * sys_undefined.c - function executed for an undefined syscall.
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * Author    Alain Greiner (2016,2017)
    65 *
    7  * This file is part of ALMOS-kernel.
     6 * Copyright (c) UPMC Sorbonne Universites
    87 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     8 * This file is part of ALMOS-MKH.
     9 *
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1718 *
    1819 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2021 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2122 */
    2223
    2324#include <errno.h>
    24 #include <types.h>
    25 #include <event.h>
    26 #include <chdev.h>
    27 #include <driver.h>
    28 #include <kmem.h>
    29 #include <kdmsg.h>
    30 #include <dma.h>
    31 #include <kcm.h>
    3225#include <thread.h>
    33 #include <cluster.h>
    34 #include <kcm.h>
     26#include <process.h>
     27#include <printk.h>
    3528
     29///////////////////
     30int sys_undefined()
     31{
     32    thread_t  * this    = CURRENT_THREAD;
     33    process_t * process = this->process;
    3634
    37 KMEM_OBJATTR_INIT(dma_kmem_request_init)
    38 {
    39         attr->type = KMEM_DMA_REQUEST;
    40         attr->name = "KCM Dev-Request";
    41         attr->size = sizeof(dev_request_t);
    42         attr->aligne = 0;
    43         attr->min  = CONFIG_DMA_RQ_KCM_MIN;
    44         attr->max  = CONFIG_DMA_RQ_KCM_MAX;
    45         attr->ctor = NULL;
    46         attr->dtor = NULL;
    47  
    48         return 0;
     35    printk("\n[ERROR] in %s : undefined syscall calle by thread %x in process %x\n",
     36           __FUNCTION__ , this->trdid , process->pid );
     37    this->errno = EINVAL;
     38    return -1;
    4939}
    50 
    51 static EVENT_HANDLER(dma_async_request_event)
    52 {
    53         kmem_req_t req;
    54         error_t err;
    55  
    56         if((err=event_get_error(event)) != 0)
    57                 printk(ERROR, "ERROR: dma_async_request_event: DMA transfare is not well completed, remaining %d\n", err);
    58 
    59         req.type = KMEM_DMA_REQUEST;
    60         req.ptr  = event_get_argument(event);
    61 
    62         assert(req.ptr != NULL && "Corrupted argument, expected the address of request");
    63 
    64         kmem_free(&req);
    65         return 0;
    66 }
    67 
    68 static inline error_t dma_do_async_request(void *dst, void *src, size_t size)
    69 {
    70         kmem_req_t req;
    71         dev_request_t *rq;
    72  
    73         req.type  = KMEM_DMA_REQUEST;
    74         req.size  = sizeof(*rq);
    75         req.flags = AF_KERNEL;
    76 
    77         if((rq = kmem_alloc(&req)) == NULL)
    78                 return ENOMEM;
    79 
    80         memset(rq, 0, sizeof(*rq));
    81 
    82         rq->src   = src;
    83         rq->dst   = dst;
    84         rq->count = size;
    85         rq->flags = DEV_RQ_NOBLOCK;
    86 
    87         event_set_priority(&rq->event, E_FUNC);
    88         event_set_handler(&rq->event, &dma_async_request_event);
    89         event_set_argument(&rq->event, rq);
    90  
    91         return __sys_dma->op.dev.write(__sys_dma, rq);
    92 }
    93 
    94 static inline error_t dma_do_sync_request(void *dst, void *src, size_t size)
    95 {
    96         dev_request_t rq;
    97  
    98         rq.src   = src;
    99         rq.dst   = dst;
    100         rq.count = size;
    101         rq.flags = 0;
    102  
    103         return __sys_dma->op.dev.write(__sys_dma, &rq);
    104 }
    105 
    106 
    107 error_t dma_memcpy(void *dst, void *src, size_t size, uint_t isAsync)
    108 {
    109         if(isAsync == DMA_ASYNC)
    110                 return dma_do_async_request(dst, src, size);
    111         else
    112                 return dma_do_sync_request(dst, src, size);
    113 }
    114 
    115 
    116 int sys_dma_memcpy(void *src, void *dst, size_t size)
    117 {
    118         return dma_do_sync_request(dst, src, size);
    119 }
  • trunk/kernel/syscalls/sys_unlink.c

    r1 r23  
    11/*
    2  * kern/sys_unlink.c - file unlink
     2 * sys_unlink.c - file unlink
    33 *
    44 * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
     
    2121 */
    2222
     23#include <hal_types.h>
     24#include <hal_uspace.h>
    2325#include <vfs.h>
    24 #include <sys-vfs.h>
    25 #include <task.h>
     26#include <process.h>
    2627#include <thread.h>
     28#include <printk.h>
    2729
    28 int sys_unlink (char *pathname)
     30//////////////////////////////////
     31int sys_unlink ( char * pathname )
    2932{
    30         error_t err = 0;
    31         struct ku_obj ku_path;
     33        error_t   error;
     34    uint32_t  length;
     35    char      kbuf[CONFIG_VFS_MAX_PATH_LENGTH];
    3236
    33         KU_BUFF(ku_path, pathname);
    34         if((err = vfs_unlink(&current_task->vfs_cwd, &ku_path)))
     37        thread_t     * this     = CURRENT_THREAD;
     38        process_t    * process  = this->process;
     39
     40    // get pathname length
     41    length = hal_strlen_from_uspace( pathname );
     42
     43    if( length >= CONFIG_VFS_MAX_PATH_LENGTH )
     44    {
     45        printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ );
     46                this->errno = ENFILE;
     47        return -1;
     48    }
     49 
     50        // get pathname copy in kernel space
     51    hal_copy_from_uspace( kbuf, pathname, length );
     52
     53    // get cluster and local pointer on reference process
     54    xptr_t      ref_xp  = process->ref_xp;
     55    process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
     56    cxy_t       ref_cxy = GET_CXY( ref_xp );
     57
     58    // get the cwd lock in read mode from reference process
     59        remote_rwlock_rd_lock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
     60
     61    // get extended pointer on cwd inode
     62    xptr_t cwd_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->vfs_cwd_xp ) );
     63
     64    // call relevant VFS function
     65    error  = vfs_unlink( cwd_xp , kbuf );
     66
     67    // release the cwd lock in reference process
     68        remote_rwlock_rd_unlock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
     69
     70        if( error )
    3571        {
    36                 current_thread->info.errno = (err < 0) ? -err : err;
    37                 return -1;
     72        printk("\n[ERROR] in %s : cannot unlink file/dir %s\n",
     73               __FUNCTION__ , pathname );
     74                this->errno = ENFILE;
     75            return -1;
    3876        }
    39  
     77
    4078        return 0;
    41 }
     79
     80} // end sys_unlink()
  • trunk/kernel/syscalls/sys_utls.c

    r1 r23  
    22 * kern/sys_utls.c - User Thread Local Storage
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * Author    Ghassan Almaless (2008,2009,2010,2011,2012)
     5 *           Alain Greiner (2016,2017)
    66 *
    7  * This file is part of ALMOS-kernel.
     7 * Copyright (c) UPMC Sorbonne Universites
    88 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     9 * This file is part of ALMOS-MKH.
     10 *
     11 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1012 * under the terms of the GNU General Public License as published by
    1113 * the Free Software Foundation; version 2.0 of the License.
    1214 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     15 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1416 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1517 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1719 *
    1820 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     21 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2022 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2123 */
    2224
    23 #include <types.h>
     25#include <hal_types.h>
    2426#include <errno.h>
    2527#include <thread.h>
    26 #include <kmem.h>
    27 #include <kmagics.h>
    28 #include <semaphore.h>
     28#include <printk.h>
     29#include <syscalls.h>
    2930
    30 #define UTLS_SET       1
    31 #define UTLS_GET       2
    32 #define UTLS_GET_ERRNO 3
    33 
    34 int sys_utls(uint_t operation, uint_t value)
     31/////////////////////////////////
     32int sys_utls( uint32_t operation,
     33              uint32_t value )
    3534{
    36         struct thread_s *this = current_thread;
     35    thread_t * this = CURRENT_THREAD;
    3736 
    3837        switch(operation)
    3938        {
    40         case UTLS_SET:
    41                 this->info.usr_tls = value;
     39            case UTLS_SET:
     40                this->utls = value;
    4241                return 0;
    4342
    44         case UTLS_GET:
    45                 return this->info.usr_tls;
     43            case UTLS_GET:
     44                return this->utls;
    4645
    47         case UTLS_GET_ERRNO:
    48                 return this->info.errno;
     46            case UTLS_GET_ERRNO:
     47                return this->errno;
    4948
    50         default:
    51                 this->info.errno = EINVAL;
     49            default:
     50        printk("\n[ERROR] in %s : illegal utls operation\n", __FUNCTION__ );
     51                this->errno = EINVAL;
    5252                return -1;
    5353        }
    54 }
     54
     55}  // end sys_utls()
  • trunk/kernel/syscalls/sys_write.c

    r1 r23  
    11/*
    2  * kern/sys_write.c - write bytes to a file
     2 * sys_write.c - write bytes to a file
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * Author        Alain Greiner (2016,2017)
    65 *
    7  * This file is part of ALMOS-kernel.
     6 * Copyright (c) UPMC Sorbonne Universites
    87 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     8 * This file is part of ALMOS-MKH.
     9 *
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1718 *
    1819 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2021 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2122 */
    2223
     24#include <kernel_config.h>
     25#include <hal_types.h>
     26#include <hal_uspace.h>
     27#include <hal_special.h>
    2328#include <errno.h>
    24 #include <thread.h>
    2529#include <vfs.h>
    2630#include <thread.h>
    27 #include <sys-vfs.h>
    28 #include <task.h>
     31#include <printk.h>
     32#include <process.h>
    2933
    30 int sys_write (uint_t fd, void *buf, size_t count)
     34/* TODO: user page(s) need to be locked  [AG] */
     35
     36//////////////////////////////////
     37int sys_write( uint32_t   file_id,
     38               void     * buf,
     39               uint32_t   count )
    3140{
    32         ssize_t err = 0;
    33         struct thread_s *this;
    34         struct task_s *task;
    35         struct vfs_file_s *file;
    36         struct ku_obj kub;
     41    error_t      error;
     42    paddr_t      paddr;
     43    char         kbuf[CONFIG_VFS_KBUF_SIZE];
     44        xptr_t       file_xp;                       // remote file extended pointer
     45    uint32_t     nbytes;                        // number of bytes in one iteration
    3746
    38         file = NULL;
    39         this = current_thread;
    40         task = current_task;
     47        thread_t   * this = CURRENT_THREAD;
     48        process_t  * process = this->process;
    4149 
    42         if((fd >= CONFIG_TASK_FILE_MAX_NR) || (task_fd_lookup(task, fd, &file)))
     50    // check file_id argument
     51        if( file_id >= CONFIG_PROCESS_FILE_MAX_NR )
    4352        {
    44                 this->info.errno = EBADFD;
     53        printk("\n[ERROR] in %s : illegal file descriptor index\n", __FUNCTION__ );
     54        this->errno = EBADFD;
    4555                return -1;
    4656        }
    4757
    48         KU_SLICE_BUFF(kub, buf, count);
    49         if((err = vfs_write(file, &kub)) < 0)
     58    // check user buffer in user space
     59    error = vmm_v2p_translate( false , buf , &paddr );
     60
     61    if ( error )
     62    {
     63        printk("\n[ERROR] in %s : user buffer unmapped = %x\n",
     64               __FUNCTION__ , (intptr_t)buf );
     65                this->errno = EINVAL;
     66                return -1;
     67    }
     68
     69    // get extended pointer on remote file descriptor
     70    file_xp = process_fd_get_xptr( process , file_id );
     71
     72    if( file_xp == XPTR_NULL )
     73    {
     74        printk("\n[ERROR] in %s : undefined file descriptor index = %d\n",
     75               __FUNCTION__ , file_id );
     76                this->errno = EBADFD;
     77                return -1;
     78    }
     79
     80    // get file descriptor cluster and local pointer
     81    vfs_file_t * file_ptr = (vfs_file_t *)GET_PTR( file_xp );
     82    cxy_t        file_cxy = GET_CXY( file_xp );
     83
     84    // check file writable
     85    uint32_t attr = hal_remote_lw( XPTR( file_cxy , &file_ptr->attr ) );
     86    if( (attr & FD_ATTR_WRITE_ENABLE) == 0 )
    5087        {
    51                 this->info.errno = (err < 0) ? -err : err;
     88        printk("\n[ERROR] in %s : file %d not writable\n",
     89               __FUNCTION__ , file_id );
     90                this->errno = EBADFD;
    5291                return -1;
    5392        }
    5493   
    55         return err;
    56 }
     94    // transfer at most CONFIG_VFS_KBUF_SIZE bytes per iteration
     95    while( count )
     96    {
     97        if( count <= CONFIG_VFS_KBUF_SIZE )
     98        {
     99            nbytes = count;
     100            count  = 0;
     101        }
     102        else
     103        {
     104            nbytes = CONFIG_VFS_KBUF_SIZE;
     105            count  = count - CONFIG_VFS_KBUF_SIZE;
     106        }
     107
     108        // copy user buffer to kernel buffer
     109        hal_copy_to_uspace( buf , kbuf , nbytes );
     110
     111        // transfer nbytes from kernel buffer
     112        error = vfs_move( false,               // write => (to_buffer = false)
     113                          file_xp,
     114                          kbuf ,
     115                          nbytes );
     116
     117        if( error )
     118        {
     119            printk("\n[ERROR] in %s cannot read data from file %d\n",
     120                   __FUNCTION__ , file_id );
     121            this->errno = error;
     122            return -1;
     123        }
     124    }
     125
     126    hal_wbflush();
     127
     128        return 0;
     129
     130}  // end sys_write()
  • trunk/kernel/syscalls/syscalls.h

    r16 r23  
    22 * syscalls.h - kernel services definition
    33 *
    4  * Author  Ghassan Almaless (2007,2008,2009,2010,2011,2012)
    5  *         Alain Greiner    (2016)
     4 * Author     Alain Greiner (2016,2017)
    65 *
    76 * Copyright (c) UPMC Sorbonne Universites
     
    2625#define _SYSCALLS_H_
    2726
     27#include <hal_types.h>
     28#include <time.h>
     29
     30/*****   Forward declarations  *****/
     31
     32struct thread_s;                  // defined in thread.h
     33struct pthread_attr_s;            // defined in thread.h
     34struct vfs_stat_s;                // defined in vfs.h
     35struct vfs_dirent_s;              // defined in vfs.h
     36struct mmap_attr_s;               // defined in vmm.h
     37
    2838/******************************************************************************************
    2939 * This enum defines the mnemonics for the syscall indexes.
     
    3242enum
    3343{
    34         SYS_EXIT,          /* 0  */
    35         SYS_MMAP,          /* 1  */
    36         SYS_CREATE,        /* 2  */
    37         SYS_JOIN,          /* 3  */
    38         SYS_DETACH,        /* 4  */
    39         SYS_YIELD,         /* 5  */
    40         SYS_SEMAPHORE,     /* 6  */
    41         SYS_COND_VAR,      /* 7  */
    42         SYS_BARRIER,       /* 8  */
    43         SYS_RWLOCK,        /* 9  */
    44         SYS_SLEEP,         /* 10 */
    45         SYS_WAKEUP,        /* 11 */
    46         SYS_OPEN,          /* 12 */
    47         SYS_CREAT,         /* 13 */
    48         SYS_READ,          /* 14 */
    49         SYS_WRITE,         /* 15 */
    50         SYS_LSEEK,         /* 16 */
    51         SYS_CLOSE,         /* 17 */
    52         SYS_UNLINK,        /* 18 */   
    53         SYS_PIPE,          /* 19 */
    54         SYS_CHDIR,         /* 20 */
    55         SYS_MKDIR,         /* 21 */
    56         SYS_MKFIFO,        /* 22 */   
    57         SYS_OPENDIR,       /* 23 */
    58         SYS_READDIR,       /* 24 */
    59         SYS_CLOSEDIR,      /* 25 */
    60         SYS_GETCWD,        /* 26 */
    61         SYS_CLOCK,         /* 27 */
    62         SYS_ALARM,         /* 28 */   
    63         SYS_DMA_MEMCPY,    /* 29 */
    64         SYS_UTLS,          /* 30 */ 
    65         SYS_SIGRETURN,     /* 31 */
    66         SYS_SIGNAL,        /* 32 */
    67         SYS_SET_SIGRETURN, /* 33 */
    68         SYS_KILL,          /* 34 */
    69         SYS_GETPID,        /* 35 */
    70         SYS_FORK,          /* 36 */
    71         SYS_EXEC,          /* 37 */
    72         SYS_GETATTR,       /* 38 */     
    73         SYS_PS,            /* 39 */
    74         SYS_MADVISE,       /* 40 */   
    75         SYS_PAGEINFO,      /* 41 */
    76         SYS_STAT,          /* 42 */
    77         SYS_MIGRATE,       /* 43 */
    78         SYS_SBRK,          /* 44 */
    79         SYS_RMDIR,         /* 45 */
    80         SYS_FTIME,         /* 46 */
    81         SYS_CHMOD,         /* 47 */
    82         SYS_FSYNC,         /* 48 */
    83         SYS_GET_TOD,       /* 49 */
    84         SYS_TIMES,         /* 50 */
    85         SYSCALLS_NR,
     44        SYS_THREAD_EXIT    = 0,
     45        SYS_MMAP           = 1,
     46        SYS_THREAD_CREATE  = 2,
     47        SYS_THREAD_JOIN    = 3,
     48        SYS_THREAD_DETACH  = 4,
     49        SYS_THREAD_YIELD   = 5,
     50        SYS_SEM            = 6,
     51        SYS_CONDVAR        = 7,
     52        SYS_BARRIER        = 8,
     53        SYS_MUTEX          = 9,
     54
     55        SYS_SLEEP          = 10,
     56        SYS_WAKEUP         = 11,
     57        SYS_OPEN           = 12,
     58        SYS_CREAT          = 13,
     59        SYS_READ           = 14,
     60        SYS_WRITE          = 15,
     61        SYS_LSEEK          = 16,
     62        SYS_CLOSE          = 17,
     63        SYS_UNLINK         = 18,   
     64        SYS_PIPE           = 19,
     65
     66        SYS_CHDIR          = 20,
     67        SYS_MKDIR          = 21,
     68        SYS_MKFIFO         = 22,   
     69        SYS_OPENDIR        = 23,
     70        SYS_READDIR        = 24,
     71        SYS_CLOSEDIR       = 25,
     72        SYS_GETCWD         = 26,
     73        SYS_CLOCK          = 27,
     74        SYS_ALARM          = 28,   
     75        SYS_RMDIR          = 29,
     76
     77        SYS_UTLS           = 30, 
     78        SYS_CHMOD          = 31,
     79        SYS_SIGNAL         = 32,
     80        SYS_TIMEOFDAY      = 33,
     81        SYS_KILL           = 34,
     82        SYS_GETPID         = 35,
     83        SYS_FORK           = 36,
     84        SYS_EXEC           = 37,
     85        SYS_STAT           = 38,     
     86        SYS_TRACE          = 39,
     87       
     88        SYSCALLS_NR        = 40,
    8689};
    8790
     91
    8892/********************************************************************************************/
    89 /********************   Process related system calls  ***************************************/
     93/********************    system calls    ****************************************************/
    9094/********************************************************************************************/
    9195
    92 
    93 /*********************************************************************************************
    94  * [0] This function TODO
    95  ********************************************************************************************/
    96 int sys_thread_exit( void * );
    97 
    98 /*********************************************************************************************
    99  * [1] This function TODO
    100  ********************************************************************************************/
    101 int sys_mmap();
    102 
    103 /*********************************************************************************************
    104  * [2] This function TODO
    105  ********************************************************************************************/
    106 int sys_thread_create();
    107 
    108 /*********************************************************************************************
    109  * [3] This function TODO
    110  ********************************************************************************************/
    111 int sys_thread_join();
    112 
    113 /*********************************************************************************************
    114  * [4] This function TODO
    115  ********************************************************************************************/
    116 int sys_thread_detach();
    117 
    118 /*********************************************************************************************
    119  * [5] This function TODO
     96/*********************************************************************************************
     97 * [0] This function terminates the execution of the calling user thread value,
     98 * and makes the exit_value pointer available to any successful pthread_join() with the
     99 * terminating thread.
     100 *********************************************************************************************
     101 * @ exit_vallue  : [out] pointer to to the parrent thread if attached.
     102 * @ return 0 if success / return -1 if failure.
     103 ********************************************************************************************/
     104int sys_thread_exit( void * exit_value );
     105
     106/*********************************************************************************************
     107 * [1] This function map physical memory (or a file) in the calling thread virtual space.
     108 * The <attr> argument is a pointer on a structure containing arguments, defined in vmm.h.
     109 * TODO not implemented yet...
     110 *********************************************************************************************
     111 * @ attr       : pointer on attributes structure.
     112 * @ return 0 if success / return -1 if failure.
     113 ********************************************************************************************/
     114int sys_mmap( struct mmap_attr_s * attr );
     115
     116/*********************************************************************************************
     117 * [2] This function creates a new user thread. The <user_attr> argument is a pointer
     118 * on astructure containing the thread attributes, defined in thread.h file.
     119 *********************************************************************************************
     120 * @ new_thread  : [out] local pointer on created thread descriptor.
     121 * @ user_attr   : [in]  pointer on thread attributes structure.
     122 * @ start_func  : [in]  pointer on start function.
     123 * @ start_args  : [in]  pointer on start function arguments.
     124 * @ return 0 if success / return -1 if failure.
     125 ********************************************************************************************/
     126int sys_thread_create( struct thread_s        * new_thread,
     127                       struct pthread_attr_s  * user_attr,
     128                       void                   * start_func,
     129                       void                   * start_args );
     130
     131/*********************************************************************************************
     132 * [3] This blocking function suspend execution of the calling thread until completion
     133 * of another target thread identified by the <trdid> argument.
     134 * If the <exit_value> argument is not NULL, the value passed to pthread_exit() by the
     135 * target thread is stored in the location referenced by exit_value.
     136 *********************************************************************************************
     137 * @ trdid     : [in]  target thread identifier.
     138 * @ thread    : [out] buffer for exit_value returned by target thread.
     139 * @ return 0 if success / return -1 if failure.
     140 ********************************************************************************************/
     141int sys_thread_join( trdid_t    trdid,
     142                     void    ** exit_value );
     143
     144/*********************************************************************************************
     145 * [4] This function detach a joinable thread.
     146 *********************************************************************************************
     147 * @ trdid   : thread identifier.
     148 * @ return 0 if success / return -1 if failure.
     149 ********************************************************************************************/
     150int sys_thread_detach( trdid_t  trdid );
     151
     152/*********************************************************************************************
     153 * [5] This function calls the scheduler for the core running the calling thread.
     154 *********************************************************************************************
     155 * @ return always 0.
    120156 ********************************************************************************************/
    121157int sys_thread_yield();
    122158
    123159/*********************************************************************************************
    124  * [6] This function TODO
    125  ********************************************************************************************/
    126 int sys_sem();
    127 
    128 /*********************************************************************************************
    129  * [7] This function TODO
    130  ********************************************************************************************/
    131 int sys_cond_var();
    132 
    133 /*********************************************************************************************
    134  * [8] This function TODO
    135  ********************************************************************************************/
    136 int sys_barrier();
    137 
    138 /*********************************************************************************************
    139  * [9] This function TODO
    140  ********************************************************************************************/
    141 int sys_rwlock();
    142 
    143 /*********************************************************************************************
    144  * [10] This function TODO
     160 * [6] This function implement all operations on a POSIX unnamed semaphore,
     161 * that can be shared by threads running in different clusters.
     162 * The kernel structure representing a remote semaphore is in the remote_sem.h file,
     163 * and the code implementing the operations is in the remore_sem.c file.
     164 *********************************************************************************************
     165 * @ vaddr     : semaphore virtual address in user space == identifier.
     166 * @ operation : SEM_INIT / SEM_DESTROY / SEM_GETVALUE / SEM_POST / SEM_WAIT.
     167 * @ value     : pointer on in/out argument in user space.
     168 * @ return 0 if success / return -1 if failure.
     169 ********************************************************************************************/
     170int sys_sem( void       * vaddr,
     171             uint32_t     operation,
     172             uint32_t   * value );
     173
     174typedef enum
     175{
     176        SEM_INIT,
     177        SEM_DESTROY,
     178        SEM_GETVALUE,
     179        SEM_WAIT,
     180        SEM_POST,
     181}
     182sem_operation_t;
     183
     184/*********************************************************************************************
     185 * [7] This function implement all operations on a POSIX condition variable.
     186 * The kernel structure representing a cond_var is defined in the remote_cv.h file,
     187 * The code implementing the operations is defined in the remote_cv.c file.
     188 *********************************************************************************************
     189 * @ vaddr     : condvar virtual address in user space == identifier.
     190 * @ operation : operation type (see below).
     191 * @ attr      : mutex virtual address in user space == identifier.
     192 * @ return 0 if success / return -1 if failure.
     193 ********************************************************************************************/
     194int sys_condvar( void     * condvar,
     195                 uint32_t   operation,
     196                 void     * mutex );
     197
     198typedef enum
     199{
     200        CONDVAR_INIT,
     201        CONDVAR_DESTROY,
     202    CONDVAR_WAIT,
     203    CONDVAR_SIGNAL,
     204    CONDVAR_BROADCAST,
     205}
     206condvar_operation_t;
     207
     208/*********************************************************************************************
     209 * [8] This function implement all operations on a POSIX barrier.
     210 * The kernel structure representing a barrier is defined in the remote_barrier.h file.
     211 * The code implementting the operations is defined in the remote_barrier.c file.
     212 *********************************************************************************************
     213 * @ vaddr     : barrier virtual address in user space == identifier.
     214 * @ operation : BARRIER_INIT / BARRIER_DESTROY / BARRIER_WAIT.
     215 * @ count     : number of expected threads (only used by BARRIER_INIT operation).
     216 * @ return 0 if success / return -1 if failure.
     217 ********************************************************************************************/
     218int sys_barrier( void     * vaddr,
     219                 uint32_t   operation,
     220                 uint32_t   count );
     221
     222typedef enum
     223{
     224        BARRIER_INIT,
     225        BARRIER_DESTROY,
     226        BARRIER_WAIT,
     227}
     228barrier_operation_t;
     229
     230/*********************************************************************************************
     231 * [9] This function implement all operations on a POSIX mutex.
     232 * The kernel structure representing a barrier is defined in the remote_barrier.h file.
     233 * The code implementting the operations is defined in the remote_barrier.c file.
     234 *********************************************************************************************
     235 * @ vaddr     : mutex virtual address in user space == identifier.
     236 * @ operation : MUTEX_INIT / MUTEX_DESTROY / MUTEX_LOCK / MUTEX_UNLOCK
     237 * @ attr      : mutex attributes (non supported yet => must be 0).
     238 * @ return 0 if success / return -1 if failure.
     239 ********************************************************************************************/
     240int sys_mutex( void     * vaddr,
     241               uint32_t   operation,
     242               uint32_t   count );
     243
     244typedef enum
     245{
     246        MUTEX_INIT,
     247        MUTEX_DESTROY,
     248        MUTEX_LOCK,
     249        MUTEX_UNLOCK,
     250}
     251mutex_operation_t;
     252
     253/*********************************************************************************************
     254 * [10] This function block the calling thread on the THREAD_BLOCKED_GLOBAL condition,
     255 * and deschedule.
     256 *********************************************************************************************
     257 * @ return 0 if success / returns -1 if failure.
    145258 ********************************************************************************************/
    146259int sys_thread_sleep();
    147260
    148261/*********************************************************************************************
    149  * [11] This function TODO
     262 * [11] This function unblock the thread identified by its <trdid> from the
     263 * THREAD_BLOCKED_GLOBAL condition.
     264 *********************************************************************************************
     265 * @ trdid  : target thread identifier.
     266 * @ return 0 if success / return -1 if failure.
    150267 ********************************************************************************************/
    151268int sys_thread_wakeup();
    152269
    153270/*********************************************************************************************
    154  * [12] This function TODO
    155  ********************************************************************************************/
    156 int sys_open();
    157 
    158 /*********************************************************************************************
    159  * [13] This function TODO
    160  ********************************************************************************************/
    161 int sys_creat();
    162 
    163 /*********************************************************************************************
    164  * [14] This function TODO
    165  ********************************************************************************************/
    166 int sys_read();
    167 
    168 /*********************************************************************************************
    169  * [15] This function TODO
    170  ********************************************************************************************/
    171 int sys_write();
    172 
    173 /*********************************************************************************************
    174  * [16] This function TODO
    175  ********************************************************************************************/
    176 int sys_lseek();
    177 
    178 /*********************************************************************************************
    179  * [17] This function TODO
    180  ********************************************************************************************/
    181 int sys_close();
    182 
    183 /*********************************************************************************************
    184  * [18] This function TODO
    185  ********************************************************************************************/
    186 int sys_unlink();
    187 
    188 /*********************************************************************************************
    189  * [19] This function TODO
    190  ********************************************************************************************/
    191 int sys_pipe();
    192 
    193 /*********************************************************************************************
    194  * [20] This function TODO
    195  ********************************************************************************************/
    196 int sys_chdir();
    197 
    198 /*********************************************************************************************
    199  * [21] This function TODO
    200  ********************************************************************************************/
    201 int sys_mkdir();
    202 
    203 /*********************************************************************************************
    204  * [22] This function TODO
    205  ********************************************************************************************/
    206 int sys_mkfifo();
    207 
    208 /*********************************************************************************************
    209  * [23] This function TODO
    210  ********************************************************************************************/
    211 int sys_opendir();
    212 
    213 /*********************************************************************************************
    214  * [24] This function TODO
    215  ********************************************************************************************/
    216 int sys_readdir();
    217 
    218 /*********************************************************************************************
    219  * [25] This function TODO
    220  ********************************************************************************************/
    221 int sys_closedir();
    222 
    223 /*********************************************************************************************
    224  * [26] This function TODO
    225  ********************************************************************************************/
    226 int sys_getcwd();
    227 
    228 /*********************************************************************************************
    229  * [27] This function TODO
    230  ********************************************************************************************/
    231 int sys_clock();
    232 
    233 /*********************************************************************************************
    234  * [28] This function TODO
    235  ********************************************************************************************/
    236 int sys_alarm();
    237 
    238 /*********************************************************************************************
    239  * [29] This function TODO
    240  ********************************************************************************************/
    241 int sys_dma_memcpy();
    242 
    243 /*********************************************************************************************
    244  * [30] This function TODO
    245  ********************************************************************************************/
    246 int sys_utls();
    247 
    248 /*********************************************************************************************
    249  * [31] This function TODO
    250  ********************************************************************************************/
    251 int sys_notAvailable();
    252 
    253 /*********************************************************************************************
    254  * [32] This function TODO
    255  ********************************************************************************************/
    256 int sys_signal();
    257 
    258 /*********************************************************************************************
    259  * [33] This function TODO
    260  ********************************************************************************************/
    261 int sys_sigreturn_setup();
     271 * [12] This function open or create a file.
     272 *********************************************************************************************
     273 * @ pathname   : pathname (can be relative or absolute).
     274 * @ flags      : bit vector attributes (see below).
     275 * @ mode       : access rights.
     276 * @ return file descriptor index in fd_array if success / return -1 if failure.
     277 ********************************************************************************************/
     278int sys_open( char    * pathname,
     279              uint32_t  flags,
     280              uint32_t  mode );
     281
     282typedef enum
     283{
     284    O_RDONLY   = 0x0010000,    /*! open file in read-only mode                              */
     285    O_WRONLY   = 0x0020000,    /*! open file in write-only mode                             */
     286    O_RDWR     = 0x0030000,    /*! open file in read/write mode                             */
     287    O_NONBLOCK = 0x0040000,    /*! do not block if data non available                       */
     288    O_APPEND   = 0x0080000,    /*! append on each write                                     */
     289    O_CREAT    = 0x0100000,    /*! create file if it does not exist                         */
     290    O_TRUNC    = 0x0200000,    /*! file length is forced to 0                               */
     291    O_EXCL     = 0x0400000,    /*! error if VFS_O_CREAT and file exist                      */
     292    O_SYNC         = 0x0800000,    /*! synchronize File System on each write                    */
     293    O_CLOEXEC  = 0x1000000,    /*! set the close-on-exec flag in file descriptor            */
     294    O_DIR      = 0x2000000,    /*! new file descriptor is for a directory                   */
     295}
     296open_attributes_t;
     297
     298/*********************************************************************************************
     299 * [13] This function creates a new file as specified by the arguments.
     300 * This function is obsolete, you should use open() with 0_CREATE.
     301 *********************************************************************************************
     302 * @ pathname   : pathname (can be relative or absolute).
     303 * @ mode       : access rights.
     304 ********************************************************************************************/
     305int sys_creat( char     * pathname,
     306               uint32_t   mode );
     307
     308/*********************************************************************************************
     309 * [14] This function read bytes from an open file identified by its file descriptor.
     310 * This file can be a regular file or character oriented device.
     311 *********************************************************************************************
     312 * @ file_id  : open file index in fd_array.
     313 * @ buf      : buffer virtual address in user space.
     314 * @ count    : number of bytes.
     315 * @ return number of bytes actually read if success / returns -1 if failure.
     316 ********************************************************************************************/
     317int sys_read( uint32_t   file_id,
     318              void     * buf,
     319              uint32_t   count );
     320
     321/*********************************************************************************************
     322 * [15] This function writes bytes to an open file identified by its file descriptor.
     323 * This file can be a regular file or character oriented device.
     324 *********************************************************************************************
     325 * @ file_id  : open file index in fd_array.
     326 * @ buf      : buffer virtual address in user space.
     327 * @ count    : number of bytes.
     328 * @ return number of bytes actually written if success / returns -1 if failure.
     329 ********************************************************************************************/
     330int sys_write( uint32_t   file_id,
     331               void     * buf,
     332               uint32_t   count );
     333
     334/*********************************************************************************************
     335 * [16] This function epositions the offset of the file descriptor identified by <file_id>,
     336 * according to the operation type defined by the <whence> and <offset> arguments.
     337 *********************************************************************************************
     338 * @ file_id  : open file index in fd_array.
     339 * @ offset   : buffer virtual address in user space.
     340 * @ whence   : operation type (see below).
     341 * @ return 0 if success / returns -1 if failure.
     342 ********************************************************************************************/
     343int sys_lseek( xptr_t    file_id,
     344               uint32_t  offset,
     345               uint32_t  whence );
     346
     347typedef enum
     348{
     349    SEEK_SET  = 0,     /*! new_offset <= offset                                             */
     350    SEEK_CUR  = 1,     /*! new_offset <= current_offset + offset                            */
     351    SEEK_END  = 2,     /*! new_iffset <= current_size + offset                              */
     352}
     353lseek_operation_t;
     354
     355/*********************************************************************************************
     356 * [17] This function release the memory allocated for the file descriptor identified by
     357 * the <file_id> argument, and remove the fd array_entry in all copies of the process
     358 * descriptor.
     359 *********************************************************************************************
     360  file_id   : file descriptor index in fd_array.
     361 * @ return 0 if success / returns -1 if failure.
     362 ********************************************************************************************/
     363int sys_close( uint32_t file_id );
     364
     365/*********************************************************************************************
     366 * [18] This function removes a directory entry identified by the <pathname> from its
     367 * directory, and decrement the link count of the file referenced by the link.
     368 * If the link count reduces to zero, and no process has the file open, then all resources
     369 * associated with the file are reclaimed.  If one or more process have the file open when
     370 * the last link is removed, the link is removed, but the removal of the file is delayed
     371 * until all references to it have been closed.
     372 *********************************************************************************************
     373 * @ pathname   : pathname (can be relative or absolute).
     374 * @ return 0 if success / returns -1 if failure.
     375 ********************************************************************************************/
     376int sys_unlink( char * pathname );
     377
     378/*********************************************************************************************
     379 * [19] This function creates in the calling thread cluster an unnamed pipe, and two
     380 * (read and write) file descriptors.
     381 *********************************************************************************************
     382 * @ file_id[0] : [out] read only file descriptor index.
     383 * @ file_id[1] : [out] write only file descriptor index.
     384 * @ return 0 if success / return -1 if failure.
     385 ********************************************************************************************/
     386int sys_pipe( uint32_t file_id[2] );
     387
     388/*********************************************************************************************
     389 * [20] This function change the current working directory in reference process descriptor.
     390 *********************************************************************************************
     391 * @ pathname   : pathname (can be relative or absolute).
     392 * @ return 0 if success / returns -1 if failure.
     393 ********************************************************************************************/
     394int sys_chdir( char * pathname );
     395
     396/*********************************************************************************************
     397 * [21] This function creates a new directory in file system.
     398 *********************************************************************************************
     399 * @ pathname   : pathname (can be relative or absolute).
     400 * @ mode       : access rights (as defined in chmod).
     401 * @ return 0 if success / returns -1 if failure.
     402 ********************************************************************************************/
     403int sys_mkdir( char      pathname,
     404               uint32_t  mode );
     405
     406/*********************************************************************************************
     407 * [22] This function creates a named FIFO file in the calling thread cluster.
     408 * The associated read and write file descriptors mut be be  explicitely created
     409 * using the sy_open() function.
     410 *********************************************************************************************
     411 * @ pathname   : pathname (can be relative or absolute).
     412 * @ mode       : access rights (as defined in chmod).
     413 * @ return 0 if success / returns -1 if failure.
     414 ********************************************************************************************/
     415int sys_mkfifo( char     * pathname,
     416                uint32_t   mode );
     417
     418/*********************************************************************************************
     419 * [23] This function open a directory, that must exist in the file system.
     420 *********************************************************************************************
     421 * @ pathname   : pathname (can be relative or absolute).
     422 * @ return file descriptor index in fd_array if success / return -1 if failure.
     423 ********************************************************************************************/
     424int sys_opendir( char * pathname );
     425
     426/*********************************************************************************************
     427 * [24] This function returns in the structure pointed by the <dirent> argument various
     428 * information about an entry of the directory identified by the <file_id> argument.
     429 *********************************************************************************************
     430 * @ file_id   : file descriptor index of the searched directory.
     431 * @ dirent    : pointer on a dirent structure in user space.
     432 * @ return 0 if success / returns -1 if failure.
     433 ********************************************************************************************/
     434int sys_readdir( uint32_t              file_id,
     435                 struct vfs_dirent_s * dirent );
     436
     437/*********************************************************************************************
     438 * [25] This function close the file descriptor previouly open by the opendir() function.
     439 *********************************************************************************************
     440 * @ file_id   : file descriptor index of the searched directory.
     441 * @ return 0 if success / returns -1 if failure.
     442 ********************************************************************************************/
     443int sys_closedir( uint32_t file_id );
     444
     445/*********************************************************************************************
     446 * [26] This function returns the pathname of the current working directory.
     447 *********************************************************************************************
     448 * buf     : buffer addres in user space.
     449 * nbytes  : user buffer size in bytes.
     450 * @ return 0 if success / returns -1 if failure.
     451 ********************************************************************************************/
     452int sys_getcwd( char     * buf,
     453                uint32_t   nbytes );
     454
     455/*********************************************************************************************
     456 * [27] This function returns in a 64 bits user buffer the calling core cycles count.
     457 * It uses both the hardware register and the core descriptor cycles count tos take
     458 * into account a possible harware register overflow  in 32 bits architectures.
     459 *********************************************************************************************
     460 * cyles    : [out] address of buffer in user space.
     461 ********************************************************************************************/
     462int sys_clock( uint64_t * cycles );
     463
     464/*********************************************************************************************
     465 * [28] This function forces the calling thread to sleep, for a fixed number of cycles.
     466 *********************************************************************************************
     467 * cycles   : number of cycles.
     468 ********************************************************************************************/
     469int sys_alarm( uint32_t cycles );
     470
     471/*********************************************************************************************
     472 * [29] This undefined function does nothing.
     473 *********************************************************************************************
     474 * @ pathname   : pathname (can be relative or absolute).
     475 * @ return 0 if success / returns -1 if failure.
     476 ********************************************************************************************/
     477int sys_rmdir( char * pathname );
     478
     479/*********************************************************************************************
     480 * [30] This function implement the operations related to User Thread Local Storage.
     481 * It is actually implemented as an uint32_t variable in the thread descriptor.
     482 *********************************************************************************************
     483 * @ operation  : UTLS operation type as defined below.
     484 * @ value      : argument value for the UTLS_SET operation.
     485 * @ return value for the UTLS_GET and UTLS_GET_ERRNO / return -1 if failure.
     486 ********************************************************************************************/
     487int sys_utls( uint32_t operation,
     488              uint32_t value );
     489
     490typedef enum
     491{
     492    UTLS_SET       = 1,
     493    UTLS_GET       = 2,
     494    UTLS_GET_ERRNO = 3,
     495}
     496utls_operation_t;
     497
     498/*********************************************************************************************
     499 * [31] This function change the acces rights for the file/dir identified by the
     500 * pathname argument.
     501 *********************************************************************************************
     502 * @ pathname   : pathname (can be relative or absolute).
     503 * @ rights     : acces rights.
     504 * @ return 0 if success / returns -1 if failure.
     505 ********************************************************************************************/
     506int sys_chmod( char     * pathname,
     507               uint32_t   rights );
     508
     509/*********************************************************************************************
     510 * [32] This function associate a specific signal handler to a given signal type.
     511 * Tee handlers for the SIGKILL and SIGSTOP signals cannot be redefined.
     512 *********************************************************************************************
     513 * @ sig_id    : index defining signal type (from 1 to 31).
     514 * @ handler   : pointer on fonction implementing the specific handler.
     515 * @ return 0 if success / returns -1 if failure.
     516 ********************************************************************************************/
     517int sys_signal( uint32_t   sig_id,
     518                void     * handler );
     519
     520/*********************************************************************************************
     521 * [33] This function returns in the structure <tv>, defined in the time.h file,
     522 * the current time (in seconds & micro-seconds).
     523 * It is computed from the calling core descriptor.
     524 * The timezone is not supported.
     525 *********************************************************************************************
     526 * @ tv      : pointer on the timeval structure.
     527 * @ tz      : pointer on the timezone structure : must be NULL.       
     528 * @ return 0 if success / returns -1 if failure.
     529 ********************************************************************************************/
     530int sys_gettimeofday( struct timeval  * tv,
     531                      struct timezone * tz );
    262532
    263533/*********************************************************************************************
    264534 * [34] This function implements the "kill" system call.
    265  * It register the signal identified by the <sig> argument in all thread descriptors
    266  * of process identified by the <pid> argument.
     535 * It register the signal defined by the <sig_id> argument in all thread descriptors
     536 * of a target process identified by the <pid> argument. This is done in all clusters
     537 * containing threads for the target process.
     538 * It can be executed by any thread running in any cluster, as this function uses
     539 * remote access to traverse the list of process copies in the owner cluster,
     540 * and the RPC_SIGNAL_RISE to signal the remote threads.
    267541 *********************************************************************************************
    268542 * @ pid      : target process identifier.
    269  * @ sig      : signal index.
     543 * @ sig_id   : index defining the signal type (from 1 to 31).
     544 * @ return 0 if success / returns -1 if failure.
    270545 ********************************************************************************************/
    271546int sys_kill( pid_t    pid,
    272               uint32_t sig );
    273 
    274 /*********************************************************************************************
    275  * [35] This function TODO
     547              uint32_t sig_id );
     548
     549/*********************************************************************************************
     550 * [35] This function implements the "getpid" system call.
     551 *********************************************************************************************
     552 * @ returns the PID for the calling thread.
    276553 ********************************************************************************************/
    277554int sys_getpid();
     
    281558 * The calling process descriptor (parent process), and the associated thread descriptor are
    282559 * replicated in the same cluster as the calling thread, but the new process (child process)
    283  * is registered in another target cluster, that will become the process owner.
     560 * is registered in another target cluster, that is the new process owner.
    284561 * The child process and the associated main thread will be migrated to the target cluster
    285562 * later, when the child process makes an "exec" or any other system call.
     
    295572 * [37] This function implement the "exec" system call.
    296573 * It is executed in the client cluster, but the new process descriptor and main thread
    297  * must be created in a server cluster, that is generally another cluster, using a RPC.
    298  * - If the server_cluster is the client cluster, call directly make_exec() in local
    299  *   mode, to change the process image and launch a new thread in local cluster.
    300  *   finally, the old thread is deleted.
    301  * - If the target_cluster is remote, call rpc_process_exec_client() to execute the
    302  *   make_exec() in remote mode on the remote cluster, to create a new process
    303  *   descriptor and a new thread on remote cluster. Finally, both the local
    304  *   process descriptor and the local thread descriptor are deleted.
     574 * must be created in a server cluster, that is generally another cluster.
     575 * - if the server_cluster is the client cluster, call directly the process_make_exec()
     576 *   function to create a new process, and launch a new thread in local cluster.
     577 * - if the target_cluster is remote, call rpc_process_exec_client() to execute the
     578 *   process_make_exec() on the remote cluster.
    305579 * In both case this function build an exec_info_t structure containing all informations
    306  * required to build the new process descriptor and the associated thread, including
    307  * the mode (local/remote).
     580 * required to build the new process descriptor and the associated thread.
     581 * Finally, the calling process and thread are deleted.
    308582 *********************************************************************************************
    309583 * @ filename : string pointer on .elf filename (virtual pointer in user space)
    310584 * @ argv     : array of strings on process arguments (virtual pointers in user space)
    311585 * @ envp     : array of strings on Renvironment variables (virtual pointers in user space)
    312  * @ returns O if success / returns non-zero if error.
     586 * @ returns O if success / returns -1 if failure.
    313587 ********************************************************************************************/
    314588int sys_exec( char  * filename,
     
    317591
    318592/*********************************************************************************************
    319  * [38] This function TODO
    320  ********************************************************************************************/
    321 int sys_thread_getattr();
    322 
    323 /*********************************************************************************************
    324  * [39] This function implements the ps system call.
    325  ********************************************************************************************/
    326 int sys_ps( uint32_t cmd,
    327             pid_t    pid,
    328             uint32_t tid );
    329 
    330 /*********************************************************************************************
    331  * [40] This function TODO
    332  ********************************************************************************************/
    333 int sys_madvise();
    334 
    335 /*********************************************************************************************
    336  * [41] This function TODO
    337  ********************************************************************************************/
    338 int sys_mcntl();
    339 
    340 /*********************************************************************************************
    341  * [42] This function TODO
    342  ********************************************************************************************/
    343 int sys_stat();
    344 
    345 /*********************************************************************************************
    346  * [43] This function TODO
    347  ********************************************************************************************/
    348 int sys_thread_migrate();
    349 
    350 /*********************************************************************************************
    351  * [44] This function TODO
    352  ********************************************************************************************/
    353 int sys_sbrk();
    354 
    355 /*********************************************************************************************
    356  * [45] This function TODO
    357  ********************************************************************************************/
    358 int sys_rmdir();
    359 
    360 /*********************************************************************************************
    361  * [46] This function TODO
    362  ********************************************************************************************/
    363 int sys_ftime();
    364 
    365 /*********************************************************************************************
    366  * [47] This function TODO
    367  ********************************************************************************************/
    368 int sys_chmod();
    369 
    370 /*********************************************************************************************
    371  * [48] This function TODO
    372  ********************************************************************************************/
    373 int sys_fsync();
    374 
    375 /*********************************************************************************************
    376  * [49] This function TODO
    377  ********************************************************************************************/
    378 int sys_gettimeofday();
    379 
    380 /*********************************************************************************************
    381  * [50] This function TODO
    382  ********************************************************************************************/
    383 int sys_times();
     593 * [38] This function  returns in the <stat> structure, defined in the vfs.h file,
     594 * various informations on the file/directory identified by the <file_id> argument.
     595 *********************************************************************************************
     596 * @ file_id   : file descriptor index in fd_array.
     597 * @ stat      : pointer on the stat structure.
     598 * @ returns O if success / returns -1 if failure.
     599 ********************************************************************************************/
     600int sys_stat( uint32_t            file_id,
     601              struct vfs_stat_s * stat );
     602
     603/*********************************************************************************************
     604 * [39] This function is used to activate / desactivate Rthe trace for a thread
     605 * identified by the <trdid> and <pid> arguments.
     606 * It can be called by any other thread.
     607 *********************************************************************************************
     608 * @ operation  : operation type as defined below.
     609 * @ pid        : process identifier.
     610 * @ trdid      : thread identifier.
     611 * @ returns O if success / returns -1 if failure.
     612 ********************************************************************************************/
     613int sys_trace( uint32_t operation,
     614               pid_t    pid,
     615               uint32_t trdid );
     616
     617typedef enum
     618{
     619    TRACE_ON       = 0,
     620    TRACE_OFF      = 1,
     621}
     622trace_operation_t;
    384623
    385624
  • trunk/kernel/vfs/fatfs.c

    r15 r23  
    22 * fatfs.c - FATFS file system API implementation.
    33 *
    4  * Author    Mohamed Lamine Karaoui (2015)
    5  *           Alain Greiner (2016)
     4 * Author    Mohamed Lamine Karaoui (2014,2015)
     5 *           Alain Greiner (2016,2017)
    66 *
    77 * Copyright (c) UPMC Sorbonne Universites
     
    3232#include <rpc.h>
    3333#include <mapper.h>
     34#include <cluster.h>
    3435#include <dev_ioc.h>
    3536#include <fatfs.h>
    3637
    37 
    3838//////////////////////////////////////////////////////////////////////////////////////////
     39//          Extern  variables         
     40//////////////////////////////////////////////////////////////////////////////////////////
     41
     42extern vfs_ctx_t        fs_context[FS_TYPES_NR];   // allocated in vfs.c file
     43
     44extern remote_barrier_t global_barrier;            // allocated dans kernel_init.c
     45 
    3946//////////////////////////////////////////////////////////////////////////////////////////
    4047// FATFS specific functions : these functions cannot be called by the VFS
    4148//////////////////////////////////////////////////////////////////////////////////////////
    42 //////////////////////////////////////////////////////////////////////////////////////////
    4349
    4450//////////////////////////////////////////////////////////
     
    4652                                        uint32_t      cluster )
    4753{
    48     return (ctx->cluster_begin_lba + ((cluster - 2) * ctx->sectors_per_cluster));
     54    return (ctx->cluster_begin_lba + ((cluster - 2) << 3));
    4955}
    5056
     
    95101
    96102}  // end fatfs_get_cluster()
     103
     104///////////////////////////////////////////////////////////////////////////////////////
     105// This static function return an integer record value (one, two, or four bytes)
     106// from a memory buffer, taking into account endianness.
     107///////////////////////////////////////////////////////////////////////////////////////
     108// @ offset        : first byte of record in buffer.
     109// @ size          : record length in bytes (1/2/4).
     110// @ buffer        : pointer on buffer base.
     111// @ little endian : the most significant byte has the highest address when true.
     112// @ return the integer value in a 32 bits word.
     113///////////////////////////////////////////////////////////////////////////////////////
     114static uint32_t get_record_from_buffer( uint32_t    offset,
     115                                        uint32_t    size,
     116                                        uint8_t   * buffer,
     117                                        uint32_t    little_endian )
     118{
     119    uint32_t n;
     120    uint32_t res  = 0;
     121
     122    if ( little_endian)
     123    {
     124        for( n = size ; n > 0 ; n-- ) res = (res<<8) | buffer[offset+n-1];
     125    }
     126    else
     127    {
     128        for( n = 0 ; n < size ; n++ ) res = (res<<8) | buffer[offset+n];
     129    }
     130    return res;
     131
     132}  // end get_record_from_buffer()
     133
    97134
    98135
     
    162199
    163200///////////////////////////////////////////////////////////////////////////////////////
     201//          The following functions are called by the VFS.
    164202///////////////////////////////////////////////////////////////////////////////////////
    165 // Generic API : the following functions are called by the VFS,
    166 //               and must be defined by all isupported file systems.
    167 ///////////////////////////////////////////////////////////////////////////////////////
    168 ///////////////////////////////////////////////////////////////////////////////////////
    169 
    170 ////////////////////////////////////////////////////////////
    171 error_t fatfs_inode_create( struct vfs_inode_s * vfs_inode )
    172 {
    173     printk("\n[PANIC] %s not fully implemented yet\n", __FUNCTION__ );
    174     hal_core_sleep();
    175 
     203
     204
     205///////////////////
     206xptr_t fatfs_init()
     207{
     208    kmem_req_t    req;
     209    fatfs_ctx_t * fatfs_ctx;       // local pointer on FATFS context
     210    vfs_ctx_t   * vfs_ctx;         // local pointer on VFS context
     211    xptr_t        root_inode_xp;   // extended pointer on root inode
     212    error_t       error;
     213
     214    // get local pointer on VFS context for FATFS
     215    vfs_ctx = &fs_context[FS_TYPE_FATFS];
     216
     217    // get number of kernel instances and extended pointer on global barrier
     218    cluster_t * cluster     = LOCAL_CLUSTER;
     219    uint32_t    nb_clusters = cluster->x_size * cluster->y_size;
     220    xptr_t      barrier_xp  = XPTR( cluster->io_cxy , &global_barrier );
     221
     222    ///// step 1 : all clusters allocate memory for FATFS context
     223
     224    // allocate memory for FATFS context extension
     225        req.type    = KMEM_FATFS_CTX;
     226        req.size    = sizeof(fatfs_ctx_t);
     227    req.flags   = AF_KERNEL | AF_ZERO;
     228        fatfs_ctx   = (fatfs_ctx_t *)kmem_alloc( &req );
     229
     230    if( fatfs_ctx == NULL )
     231    {
     232        printk("\n[PANIC] in %s : no memory for FATFS context\n", __FUNCTION__ );
     233        hal_core_sleep();
     234    }
     235   
     236    ///// step 2 : only cluster_0 access device and creates root inode
     237
     238    if( local_cxy == 0 )
     239    {
     240        // create VFS root inode
     241        error = vfs_inode_create( XPTR_NULL,        // no parent dentry
     242                                  FS_TYPE_FATFS,
     243                                  INODE_TYPE_DIR,
     244                                  0,                // attr
     245                                  0,                // rights
     246                                  0,                // uid
     247                                  0,                // gid
     248                                  &root_inode_xp );
     249
     250        assert( (error == 0 ) , __FUNCTION__ , "cannot create VFS root inode" );
     251
     252        // initialize VFS context / access device to initialize FATFS context
     253        error = fatfs_ctx_init( vfs_ctx,
     254                                fatfs_ctx,
     255                                root_inode_xp );
     256
     257        // create FATFS root inode
     258        error = fatfs_inode_create( GET_PTR( root_inode_xp ) ,
     259                                    fatfs_ctx->root_dir_cluster );
     260
     261        if( error )
     262        {
     263            printk("\n[PANIC] in %s : cannot create FATFS root inode\n", __FUNCTION__ );
     264            hal_core_sleep();
     265        }
     266
     267    }
     268
     269    //////////////// synchronize all clusters
     270    remote_barrier( barrier_xp , nb_clusters );
     271
     272    ///// step 3 : all others clusters initialize both context and extension
     273
     274    if( local_cxy != 0 )
     275    {
     276        // copy VFS context from remote cluster_0 to local cluster
     277        hal_remote_memcpy( XPTR( local_cxy , vfs_ctx ),
     278                           XPTR( 0 , vfs_ctx ),
     279                           sizeof(vfs_ctx_t) );
     280
     281        // copy FATFS context from remote cluster_0 to local cluster
     282        hal_remote_memcpy( XPTR( local_cxy , fatfs_ctx ),
     283                           XPTR( 0 , vfs_ctx->extend ) ,
     284                           sizeof(fatfs_ctx_t) );
     285
     286        // update extend field in local copy of VFS context
     287        vfs_ctx->extend = fatfs_ctx;
     288    }
     289
     290    return root_inode_xp;
     291
     292}  // end fatfs_init()
     293
     294//////////////////////////////////////////////
     295error_t fatfs_ctx_init( vfs_ctx_t   * vfs_ctx,
     296                        fatfs_ctx_t * fatfs_ctx,
     297                        xptr_t        root_inode_xp )
     298{
     299    error_t  error;
     300    uint8_t  buffer[512];    // buffer for boot record
     301
     302    // make a synchronous access to IOC device to read the boot record from device
     303    error = dev_ioc_sync_read( buffer , 0 , 1 );
     304    assert( (error == 0) , __FUNCTION__ , "cannot access FAT boot record" );
     305
     306    // check sector size from boot record
     307    uint32_t sector_size = get_record_from_buffer( BPB_BYTSPERSEC , buffer , 1 );
     308    assert( (sector_size == 512) , __FUNCTION__ , "sector size must be 512 bytes" );
     309
     310    // check cluster size from boot record
     311    uint32_t nb_sectors = get_record_from_buffer( BPB_SECPERCLUS , buffer , 1 );
     312    assert( (nb_sectors == 8) , __FUNCTION__ , "cluster size must be 8 sectors" );
     313
     314    // check number of FAT copies from boot record
     315    uint32_t nb_fats = get_record_from_buffer( BPB_NUMFATS , buffer , 1 );
     316    assert( (nb_fats == 1) , __FUNCTION__ , "number of FAT copies must be 1" );
     317
     318    // get & check number of sectors in FAT from boot record
     319    uint32_t fat_sectors = get_record_from_buffer( BPB_FAT32_FATSZ32 , buffer , 1 );
     320    assert( ((fat_sectors & 0xF) == 0) , __FUNCTION__ , "FAT not multiple of 16 sectors");
     321
     322    // get and check root cluster from boot record
     323    uint32_t root_cluster = get_record_from_buffer( BPB_FAT32_ROOTCLUS , buffer , 1 );
     324    assert( (root_cluster == 2) , __FUNCTION__ , "Root cluster index must be  2");
     325
     326    // get FAT lba from boot record
     327    uint32_t fat_lba = get_record_from_buffer( BPB_RSVDSECCNT , buffer , 1 );
     328   
     329    // allocate a mapper for the FAT itself
     330    mapper_t * fat_mapper = mapper_create();
     331    assert( (fat_mapper != NULL) , __FUNCTION__ , "no memory for FAT mapper" );
     332
     333    // initialize the FATFS context
     334    fatfs_ctx->fat_begin_lba         = fat_lba;
     335    fatfs_ctx->fat_sectors_count     = fat_sectors;
     336    fatfs_ctx->bytes_per_sector      = sector_size;
     337    fatfs_ctx->bytes_per_cluster     = sector_size * nb_sectors;
     338    fatfs_ctx->cluster_begin_lba     = fat_lba + fat_sectors;
     339    fatfs_ctx->root_dir_cluster      = 2;
     340    fatfs_ctx->last_allocated_sector = 0;    // TODO ???
     341    fatfs_ctx->last_allocated_index  = 0;    // TODO ???
     342    fatfs_ctx->fat_mapper_xp         = XPTR( local_cxy , fat_mapper );
     343
     344    // initialize the VFS context
     345    vfs_ctx->type    = FS_TYPE_FATFS;
     346    vfs_ctx->attr    = 0;                    // not READ_ONLY / not SYNC
     347    vfs_ctx->count   = fat_sectors << 10;    // total number of sectors in data region
     348    vfs_ctx->blksize = 512;                  // number of bytes per sector
     349    vfs_ctx->root_xp = root_inode_xp;
     350    vfs_ctx->extend  = fatfs_ctx;
     351
     352    spinlock_init( &vfs_ctx->lock );
     353
     354    bitmap_init( vfs_ctx->bitmap , CONFIG_VFS_MAX_INODES );
     355
     356    return 0;
     357
     358}  // end fatfs_ctx_init()
     359 
     360
     361
     362////////////////////////////////////////////////////
     363void fatfs_ctx_destroy( struct vfs_ctx_s * vfs_ctx )
     364{
     365    kmem_req_t    req;
     366    fatfs_ctx_t * fatfs_ctx;
     367
     368    // get pointer on FATFS context extension
     369    fatfs_ctx = (fatfs_ctx_t *)vfs_ctx->extend;
     370
     371    req.type = KMEM_FATFS_INODE;
     372    req.ptr  = fatfs_ctx;
     373    kmem_free( &req );
     374}
     375
     376
     377////////////////////////////////////////////////////
     378error_t fatfs_inode_create( vfs_inode_t * vfs_inode,
     379                            uint32_t      first_cluster )
     380{
    176381    kmem_req_t      req;
    177382    fatfs_inode_t * fatfs_inode;
    178383
    179     // allocate memory for fatfs inode
     384    // allocate memory for FATFS inode extension
    180385        req.type    = KMEM_FATFS_INODE;
    181386        req.size    = sizeof(fatfs_inode_t);
     
    185390    if( fatfs_inode == NULL ) return ENOMEM;
    186391
    187     // initialise ramfs_inode
    188     fatfs_inode->first_cluster = 0;   // TODO ???
    189     fatfs_inode->ctx           = (fatfs_ctx_t *)vfs_inode->ctx->extend;
     392    // link FATFS inode to VFS inode
     393    vfs_inode->extend = fatfs_inode;
     394
     395    // initialise FATFS inode
     396    fatfs_inode->first_cluster = first_cluster;
    190397 
    191     // link fatfs_inode to vfs_inode
    192     vfs_inode->extend = fatfs_inode;
    193 
    194398    return 0;
    195 
    196 }
    197 
    198 //////////////////////////////////////////////////////
    199 void fatfs_inode_destroy( struct vfs_inode_s * inode )
    200 {
    201     printk("\n[PANIC] %s not fully implemented yet\n", __FUNCTION__ );
    202     hal_core_sleep();
    203 }
    204 
    205 //////////////////////////////////////////////////
    206 error_t fatfs_ctx_create( struct vfs_ctx_s * ctx )
    207 {
    208     printk("\n[PANIC] %s not fully implemented yet\n", __FUNCTION__ );
    209     hal_core_sleep();
    210 
    211     return 0;
    212 }
    213 
    214 ////////////////////////////////////////////////
    215 void fatfs_ctx_destroy( struct vfs_ctx_s * ctx )
    216 {
    217     printk("\n[PANIC] %s not fully implemented yet\n", __FUNCTION__ );
    218     hal_core_sleep();
    219 }
     399}
     400
     401///////////////////////////////////////////////////
     402void fatfs_inode_destroy( vfs_inode_t * vfs_inode )
     403{
     404    kmem_req_t      req;
     405    fatfs_inode_t * fatfs_inode;
     406
     407    // get pointer on FATFS inode
     408    fatfs_inode = (fatfs_inode_t *)vfs_inode->extend;
     409
     410    req.type = KMEM_FATFS_INODE;
     411    req.ptr  = fatfs_inode;
     412    kmem_free( &req );
     413
     414        vfs_inode->extend = NULL;
     415}
     416
    220417
    221418////////////////////////////////////////////////
     
    223420                                  bool_t   is_read )
    224421{
    225     // get source buffer base address
    226     char * buffer = (char *)ppm_page2base( page );
     422    // get memory buffer base address
     423    uint8_t * buffer = (uint8_t *)ppm_page2base( page );
    227424 
    228425    // get pointer on source mapper and page index from page descriptor
    229     mapper_t * src_mapper  = page->mapper;
     426    mapper_t * mapper      = page->mapper;
    230427    uint32_t   page_index  = page->index;
    231428
    232     if( src_mapper == NULL)
    233     {
    234         printk("\n[PANIC] in %s : no mapper for this page\n", __FUNCTION__ );
    235         hal_core_sleep();
    236     }
    237 
    238429    // get VFS inode pointer from mapper
    239     vfs_inode_t * vfs_inode = src_mapper->inode;
     430    vfs_inode_t * vfs_inode = mapper->inode;
    240431
    241432    // get FATFS inode pointer for VFS inode
     
    246437
    247438    // get FATFS context pointer from FATFS inode
    248     fatfs_ctx_t * fatfs_ctx = fatfs_inode->ctx;
     439    fatfs_ctx_t * fatfs_ctx = (fatfs_ctx_t *)vfs_inode->ctx->extend;
    249440
    250441    // get number of sectors
  • trunk/kernel/vfs/fatfs.h

    r15 r23  
    22 * fatfs.h - FATFS file system API definition.
    33 *
    4  * Author    Mohamed Lamine Karaoui (2015)
    5  *           Alain Greiner (2016)
     4 * Author    Mohamed Lamine Karaoui (2014,2015)
     5 *           Alain Greiner (2016,2017)
    66 *
    77 * Copyright (c) UPMC Sorbonne Universites
     
    2828#include <hal_types.h>
    2929#include <rwlock.h>
     30#include <vfs.h>
     31
     32
     33///////////////////////////////////////////////////////////////////////////////////////////
     34// The FATFS File System implements a FAT32 read/write file system.
     35///////////////////////////////////////////////////////////////////////////////////////////
     36
     37/*************** Partition Boot Sector Format **********************************/
     38//                                     offset |  length
     39#define BS_JMPBOOT                          0 ,  3
     40#define BS_OEMNAME                          3 ,  8
     41#define BPB_BYTSPERSEC                     11 ,  2
     42#define BPB_SECPERCLUS                     13 ,  1
     43#define BPB_RSVDSECCNT                     14 ,  2
     44#define BPB_NUMFATS                        16 ,  1
     45#define BPB_ROOTENTCNT                     17 ,  2
     46#define BPB_TOTSEC16                       19 ,  2
     47#define BPB_MEDIA                          21 ,  1
     48#define BPB_FATSZ16                        22 ,  2
     49#define BPB_SECPERTRK                      24 ,  2
     50#define BPB_NUMHEADS                       26 ,  2
     51#define BPB_HIDDSEC                        28 ,  4
     52#define BPB_TOTSEC32                       32 ,  4
     53#define BPB_PARTITION_TABLE               446 , 64
     54
     55// FAT 32
     56#define BPB_FAT32_FATSZ32                  36 ,  4
     57#define BPB_FAT32_EXTFLAGS                 40 ,  2
     58#define BPB_FAT32_FSVER                    42 ,  2
     59#define BPB_FAT32_ROOTCLUS                 44 ,  4
     60#define BPB_FAT32_FSINFO                   48 ,  2
     61#define BPB_FAT32_BKBOOTSEC                50 ,  2
     62#define BS_FAT32_DRVNUM                    64 ,  1
     63#define BS_FAT32_BOOTSIG                   66 ,  1
     64#define BS_FAT32_VOLID                     67 ,  4
     65#define BS_FAT32_VOLLAB                    71 , 11
     66#define BS_FAT32_FILSYSTYPE                82 ,  8
     67
     68// Partitions
     69#define FIRST_PARTITION_ACTIVE            446 ,  8
     70#define FIRST_PARTITION_BEGIN_LBA         454 ,  4
     71#define FIRST_PARTITION_SIZE              458 ,  4
     72#define SECOND_PARTITION_ACTIVE           462 ,  8
     73#define SECOND_PARTITION_BEGIN_LBA        470 ,  4
     74#define SECOND_PARTITION_SIZE             474 ,  4
     75#define THIRD_PARTITION_ACTIVE            478 ,  8
     76#define THIRD_PARTITION_BEGIN_LBA         486 ,  4
     77#define THIRD_PARTITION_SIZE              490 ,  4
     78#define FOURTH_PARTITION_ACTIVE           494 ,  8
     79#define FOURTH_PARTITION_BEGIN_LBA        502 ,  4
     80#define FOURTH_PARTITION_SIZE             506 ,  4   
     81/*******************************************************************************/
     82
     83#define MBR_SIGNATURE_POSITION            510 , 2
     84#define MBR_SIGNATURE_VALUE               0xAA55 
     85
     86/************** FAT_FS_INFO SECTOR  ********************************************/
     87#define FS_SIGNATURE_VALUE_1              0x52526141
     88#define FS_SIGNATURE_VALUE_2              0x72724161
     89#define FS_SIGNATURE_VALUE_3              0x000055AA 
     90#define FS_SIGNATURE_POSITION_1           0   , 4 
     91#define FS_SIGNATURE_POSITION_2           484 , 4
     92#define FS_SIGNATURE_POSITION_3           508 , 4 
     93#define FS_FREE_CLUSTERS                  488 , 4
     94#define FS_FREE_CLUSTER_HINT              492 , 4
     95/*******************************************************************************/
     96
     97#define DIR_ENTRY_SIZE          32
     98                   
     99#define NAME_MAX_SIZE           31
     100
     101/******* Directory Entry Structure (32 bytes) **********************************/
     102//                            offset | length
     103#define DIR_NAME                   0 , 11   // dir_entry name
     104#define DIR_ATTR                  11 ,  1   // attributes
     105#define DIR_NTRES                 12 ,  1   // reserved for the OS       
     106#define DIR_CRT_TIMES_TENTH       13 ,  1
     107#define DIR_FST_CLUS_HI           20 ,  2   // cluster index 16 MSB bits
     108#define DIR_WRT_TIME              22 ,  2   // time of last write
     109#define DIR_WRT_DATE              24 ,  2   // date of last write
     110#define DIR_FST_CLUS_LO           26 ,  2   // cluster index 16 LSB bit
     111#define DIR_FILE_SIZE             28 ,  4   // dir_entry size (up to 4 Gbytes)
     112/*******************************************************************************/
     113
     114/******* LFN Directory Entry Structure  (32 bytes) *****************************/
     115//                            offset | length
     116#define LDIR_ORD                   0 ,  1   // Sequence number (from 0x01 to 0x0f)   
     117#define LDIR_NAME_1                1 , 10   // name broken into 3 parts
     118#define LDIR_ATTR                 11 ,  1   // attributes (must be 0x0F)
     119#define LDIR_TYPE                 12 ,  1   // directory type (must be 0x00)
     120#define LDIR_CHKSUM               13 ,  1   // checksum of name in short dir 
     121#define LDIR_NAME_2               14 , 12
     122#define LDIR_RSVD                 26 ,  2   // artifact of previous fat (must be 0)
     123#define LDIR_NAME_3               28 ,  4   
     124/*******************************************************************************/
     125
     126/***********************  DIR_ATTR values  (attributes) ************************/
     127#define ATTR_READ_ONLY            0x01
     128#define ATTR_HIDDEN               0x02
     129#define ATTR_SYSTEM               0x04
     130#define ATTR_VOLUME_ID            0x08
     131#define ATTR_DIRECTORY            0x10
     132#define ATTR_ARCHIVE              0x20
     133#define ATTR_LONG_NAME_MASK       0x0f      // READ_ONLY|HIDDEN|SYSTEM|VOLUME_ID
     134/*******************************************************************************/
     135
     136/********************* DIR_ORD special values **********************************/
     137#define FREE_ENTRY                0xE5     // this entry is free in the directory
     138#define NO_MORE_ENTRY             0x00     // no more entry in the directory
     139/*******************************************************************************/
     140
     141/******************** CLuster Index Special Values *****************************/
     142#define FREE_CLUSTER              0x00000000
     143#define RESERVED_CLUSTER          0x00000001
     144#define BAD_CLUSTER               0x0FFFFFF7
     145#define END_OF_CHAIN_CLUSTER_MIN  0x0ffffff8
     146#define END_OF_CHAIN_CLUSTER_MAX  0x0fffffff
     147/*******************************************************************************/
    30148
    31149/****  Forward declarations  ****/
    32150
    33151struct mapper_s;
    34 struct device_s;
     152struct page_s;
     153struct vfs_ctx_s;
    35154struct vfs_inode_s;
    36 struct vfs_ctx_s;
    37 struct page_s;
    38 
    39 /*****************************************************************************************
    40  * This structure defines a FATFS specific context extension.
     155
     156/*****************************************************************************************
     157 * This structure defines a FATFS specific context (extension to VFS context).
    41158 ****************************************************************************************/
    42159
    43160typedef struct fatfs_ctx_s
    44161{
    45     rwlock_t          lock;                  /*! TODO protect what ???                  */
    46     uint32_t          fat_begin_lba;         /*! first lba of FAT region                */
     162    uint32_t          fat_begin_lba;         /*! lba of FAT region                      */
    47163    uint32_t          fat_sectors_count;     /*! number of sectors in FAT region        */
    48164    uint32_t          bytes_per_sector;      /*!                                        */
    49165    uint32_t          bytes_per_cluster;     /*!                                        */
    50     uint32_t          cluster_begin_lba;     /*! first lba of data region on device     */
    51     uint32_t          sectors_per_cluster;   /*!                                        */
    52     uint32_t          rootdir_first_cluster; /*                                         */
    53     uint32_t          last_allocated_sector; /*!                                        */
    54     uint32_t          last_allocated_index;  /*! TODO last allocated cluster ???        */
    55     xptr_t            fat_mapper_xp;         /*! FAT mapper (in IO cluster)             */ 
     166    uint32_t          cluster_begin_lba;     /*! lba of data region                     */
     167    uint32_t          sectors_per_cluster;   /*! cluster index for root directory       */
     168    uint32_t          root_dir_cluster;      /*!                                        */
     169    uint32_t          last_allocated_sector; /*! TODO ???                               */
     170    uint32_t          last_allocated_index;  /*! TODO ???                               */
     171    xptr_t            fat_mapper_xp;         /*! FAT mapper (in IO cluster)             */
    56172}
    57173fatfs_ctx_t;
    58174
    59175/*****************************************************************************************
    60  * This structure defines the FAT specific inode extension (versus the VFS inode).
     176 * This structure defines the FATFS specific inode (extension to VFS inode).
    61177 ****************************************************************************************/
    62178
    63179typedef struct fatfs_inode_s
    64180{
    65     struct fatfs_ctx_s * ctx;                /*! local pointer on the FATFS context     */
    66         uint32_t             first_cluster;      /*! first cluster for this file/dir        */
     181        uint32_t          first_cluster;         /*! first cluster for this file/dir        */
    67182}
    68183fatfs_inode_t;
     
    70185
    71186
     187
     188//////////////////////////////////////////////////////////////////////////////////////////
     189// These functions are specific to the FATFS, and cannot be called by the VFS.
     190//////////////////////////////////////////////////////////////////////////////////////////
     191
    72192/*****************************************************************************************
    73193 * This function returns the LBA of the first sector of a FAT cluster.
     
    76196 * @ ctx          :     pointer on FATFS context.
    77197 * @ cluster  : cluster index in FATFS.
    78  * # return the lba value.
     198 * @ return the lba value.
    79199 ****************************************************************************************/
    80200inline uint32_t fatfs_lba_from_cluster( fatfs_ctx_t * ctx,
     
    105225                           uint32_t        * cluster );
    106226
     227
     228
     229
     230//////////////////////////////////////////////////////////////////////////////////////////
     231// These functions are called by the VFS, and must be implemented by all File Systems.
     232//////////////////////////////////////////////////////////////////////////////////////////
     233
     234/******************************************************************************************
     235 * This function initializes the FATFS file system as the root FS.
     236 * It is executed cooperatively during kernel init by all CP0s in all clusters.
     237 * The initilisation is made in three phases, separated by synchronisation barrier:     
     238 * - phase 1 : all CP0s in all clusters allocate memory for the local copy of
     239 *   the FATFS context.
     240 * - phase 2 : cluster_0 only creates the root inode descriptor, access the external
     241 *   device to get information stored on the boot record, and initialises both
     242 *   the VFS context, and the FATFS context.
     243 * - phase 3 : all other clusters initialize their local VFS context and FATFS context
     244 *   from values contained in cluster_0, using hal_remote_memcpy().
     245 ******************************************************************************************
     246 * @ return an extended pointer on the created root inode / return XPTR_NULL if failure.
     247 *****************************************************************************************/
     248xptr_t fatfs_init();
     249
     250/******************************************************************************************
     251 * This function mount the FATFS on the root FS.
     252 * TODO not implemented [AG]
     253 ******************************************************************************************
     254 * @ parent_inode_xp : extended pointer on the parent inode.
     255 *****************************************************************************************/
     256error_t fatfs_mount( xptr_t parent_inode_xp );
     257
     258
     259/*****************************************************************************************
     260 * This function  initializes both the VFS context and the FATFS context.
     261 * Both the VFS context and the FATFS context must have been previously allocated.
     262 * It access the device to read the boot record, and is supposed to be called only
     263 * in cluster_0 (in other clusters these contexts are replicated from values
     264 * contained in cluster_0).
     265 *****************************************************************************************
     266 * @ vfs_ctx        : local pointer on VFS context for FATFS.
     267 * @ fatfs_ctx      : local pointer on specific FATFS context.
     268 * @ root_inode_xp  : extended pointer on VFS root inode.
     269 ****************************************************************************************/
     270error_t fatfs_ctx_init( struct vfs_ctx_s   * vfs_ctx,
     271                        struct fatfs_ctx_s * fatfs_ctx,
     272                        xptr_t               root_inode_xp );
     273
     274/*****************************************************************************************
     275 * This function releases memory dynamically allocated for the FATFS context extension.
     276 *****************************************************************************************
     277 * @ vfs_ctx   : local pointer on VFS context.
     278 ****************************************************************************************/
     279void fatfs_ctx_destroy( struct vfs_ctx_s * vfs_ctx );
     280
     281
     282
    107283/*****************************************************************************************
    108284 * This function allocates memory for a FATFS inode, initializes it,
    109285 * and link it to the VFS inode.
    110286 *****************************************************************************************
     287 * @ inode         : local pointer on the VFS inode.
     288 * @ first_cluster : first cluster index in the FAT32.
     289 * @ return 0 if success / return ENOMEM if error.
     290 ****************************************************************************************/
     291error_t fatfs_inode_create( struct vfs_inode_s * inode,
     292                            uint32_t             first_cluster);
     293
     294/*****************************************************************************************
     295 * This function releases memory allocated for a FATFS inode.
     296 *****************************************************************************************
    111297 * @ inode   : local pointer on vfs_inode.
    112  * @ return 0 if success / return ENOMEM if error.
    113  ****************************************************************************************/
    114 error_t fatfs_inode_create( struct vfs_inode_s * inode );
    115 
    116 /*****************************************************************************************
    117  * This function releases memory allocated for a FATFS inode.
    118  *****************************************************************************************
    119  * @ inode   : local pointer on vfs_inode.
    120298 ****************************************************************************************/
    121299void fatfs_inode_destroy( struct vfs_inode_s * inode );
    122300
    123 /*****************************************************************************************
    124  * This function allocates memory for a FATFS context, initialises it,
    125  * and link it to the local VFS context.
    126  *****************************************************************************************
    127  * @ inode   : local pointer on VFS context.
    128  * @ return 0 if success / return ENOMEM if error.
    129  ****************************************************************************************/
    130 error_t fatfs_ctx_create( struct vfs_ctx_s * ctx );
    131 
    132 /*****************************************************************************************
    133  * This function releases memory allocated for a FATFS context.
    134  *****************************************************************************************
    135  * @ ctx   : local pointer on VFS context.
    136  ****************************************************************************************/
    137 void fatfs_ctx_destroy( struct vfs_ctx_s * ctx );
    138 
    139 /*****************************************************************************************
    140  * This function moves a page from the mapper to the FATFS file system.
     301
     302
     303/*****************************************************************************************
     304 * This function moves a page from the mapper to the FATFS file system on device.
    141305 * It must be called by a thread running in cluster containing the mapper.
    142  * The pointer on the mapper and the page index in file are supposed to be registered
     306 * The pointer on the mapper and the page index in file are registered
    143307 * in the page descriptor.
    144308 *****************************************************************************************
     
    151315 * This function moves a page from the FATFS file system on device to the mapper.
    152316 * It must be called by a thread running in cluster containing the mapper.
    153  * The pointer on the mapper and the page index in file are supposed to be registered
     317 * The pointer on the mapper and the page index in file are registered
    154318 * in the page descriptor.
    155319 *****************************************************************************************
     
    160324
    161325
     326
     327
    162328#endif  /* _FATFS_H_ */
  • trunk/kernel/vfs/ramfs.c

    r15 r23  
    22 * ramfs.c  RAMFS file system API implementation.
    33 *
    4  * Authors   Mohamed Lamine Karaoui (2015)
    5  *           Alain Greiner (2016)
     4 * Authors   Mohamed Lamine Karaoui (2014,2015)
     5 *           Alain Greiner (2016,2017)
    66 *
    77 * Copyright (c) UPMC Sorbonne Universites
     
    3232
    3333
    34 ///////////////////////////////////////////////////////////////////////////////////////
    35 // RAMFS specific functions : these static functions cannot be called by the VFS
    36 ///////////////////////////////////////////////////////////////////////////////////////
    3734
    3835
    3936
    4037///////////////////////////////////////////////////////////////////////////////////////
    41 // Generic API : the following functions are called by the VFS,
    42 //               and must be defined by all supported file systems.
     38//             The following functions are called by the VFS.
    4339///////////////////////////////////////////////////////////////////////////////////////
    4440
    45 ////////////////////////////////////////////////////////////
    46 error_t ramfs_inode_create( struct vfs_inode_s * vfs_inode )
     41//////////////////////////////////////////////
     42error_t ramfs_mount( xptr_t   parent_inode_xp,
     43                     char   * ramfs_root_name )
    4744{
    48     printk("\n[PANIC] %s not fully implemented yet\n", __FUNCTION__ );
    49     hal_core_sleep();
     45    xptr_t        root_inode_xp;   // unused                     
     46 
     47    // create VFS dentry and VFS inode for RAMFS root directory
     48    return  vfs_add_child_in_parent( INODE_TYPE_DIR,
     49                                     FS_TYPE_RAMFS,
     50                                     parent_inode_xp,
     51                                     ramfs_root_name,
     52                                     &root_inode_xp );
     53}
    5054
    51     kmem_req_t      req;
    52     ramfs_inode_t * ramfs_inode;
    5355
    54     // allocate memory for ramfs inode
    55         req.type    = KMEM_RAMFS_INODE;
    56         req.size    = sizeof(ramfs_inode_t);
    57     req.flags   = AF_KERNEL | AF_ZERO;
    58         ramfs_inode = (ramfs_inode_t *)kmem_alloc( &req );
     56////////////////////////////////////////////
     57error_t ramfs_ctx_init( vfs_ctx_t * vfs_ctx,
     58                        xptr_t      root_inode_xp )
    5959
    60     if( ramfs_inode == NULL ) return ENOMEM;
     60{
     61    vfs_ctx->type    = FS_TYPE_RAMFS;
     62    vfs_ctx->attr    = 0;                // not READ_ONLY / not SYNC
     63    vfs_ctx->count   = 0;                // unused for RAMFS
     64    vfs_ctx->blksize = 512;              // unused for RAMFS
     65    vfs_ctx->root_xp = root_inode_xp;
     66    vfs_ctx->extend  = NULL;             // unused for DEVFS
    6167
    62     // initialise ramfs_inode TODO
     68    spinlock_init( &vfs_ctx->lock );
    6369
    64     // link vfs_inode to ramfs_inode
    65     vfs_inode->extend = ramfs_inode;
     70    bitmap_init( vfs_ctx->bitmap , CONFIG_VFS_MAX_INODES );
    6671
    6772    return 0;
    6873}
    6974
    70 //////////////////////////////////////////////////////
    71 void ramfs_inode_destroy( struct vfs_inode_s * inode )
    72 {
    73     assert( false , __FUNCTION__ , "not fully implemented yet" );
    74 }
    75 
    76 /////////////////////////////////////////////////
    77 error_t ramfs_write_page( struct page_s  * page )
    78 {
    79     printk("\n[PANIC] %s not fully implemented yet\n", __FUNCTION__ );
    80     hal_core_sleep();
    81 
    82     return 0;
    83 }
    84 
    85 ////////////////////////////////////////////////
    86 error_t ramfs_read_page( struct page_s  * page )
    87 {
    88     printk("\n[PANIC] %s not fully implemented yet\n", __FUNCTION__ );
    89     hal_core_sleep();
    90 
    91     return 0;
    92 }
    93    
  • trunk/kernel/vfs/ramfs.h

    r15 r23  
    22 * ramfs.h  RAMFS file system API definition.
    33 *
    4  * Authors   Mohamed Lamine Karaoui (2015)
    5  *           Alain Greiner (2016)
     4 * Authors   Mohamed Lamine Karaoui (2014,2015)
     5 *           Alain Greiner (2016,2017)
    66 *
    77 * Copyright (c) UPMC Sorbonne Universites
     
    2626#define _RAMFS_H_
    2727
     28///////////////////////////////////////////////////////////////////////////////////////////
     29// The RAMFS File System Rdoes not uses any external device to store data.
     30// It stores the dynamically created files and directories in the VFS mappers.
     31// The ramfs_read_page() and ramfs_write_page() functions should never be used.
     32// The RAMFS cannot be used as the root FS.
     33// There is no RAMFS context extension, and no RAMFS inode extension.
     34///////////////////////////////////////////////////////////////////////////////////////////
     35
     36
    2837/****  Forward declarations  ****/
    2938
    30 struct vfs_inode_s;
    31 struct page_s;
     39
     40//////////////////////////////////////////////////////////////////////////////////////////
     41// These functions are called by the VFS, and must be implemented by all FS.
     42//////////////////////////////////////////////////////////////////////////////////////////
     43
     44/******************************************************************************************
     45 * This function does not exist, as the RAMFS cannot be the root FS.
     46 *****************************************************************************************/
     47xptr_t ramfs_init();
     48
     49/******************************************************************************************
     50 * This function mount a RAMFS on a given inode of the root FS.
     51 * It actually creates a new VFS dentry in the cluster containing the parent inode,
     52 * and create a new VFS inode in another cluster.
     53 ******************************************************************************************
     54 * @ parent_inode_xp : extended pointer on the parent inode.
     55 * @ ramfs_root_name : RAMFS root directory name.
     56 *****************************************************************************************/
     57error_t ramfs_mount( xptr_t   parent_inode_xp,
     58                     char   * ramfs_root_name );
    3259
    3360/*****************************************************************************************
    34  * This structure defines a RAMFS specific context extension.
     61 * This function initializes all fields of the VFS context.
     62 * No extra memory is allocated for a RAMFS context.
    3563 ****************************************************************************************/
    36 
    37 typedef struct ramfs_ctx_s
    38 {
    39     intptr_t          base;                                                                 
    40     rwlock_t          size;
    41 }
    42 ramfs_ctx_t;
     64error_t ramfs_ctx_init( struct vfs_ctx_s * vfs_ctx,
     65                        xptr_t             root_inode_xp );
    4366
    4467/*****************************************************************************************
    45  * This structure defines the RAMFS inode specific extension (versus the VFS inode).
     68 * This function does not exist for a RAMFS context, as there is no RAMFS context.
    4669 ****************************************************************************************/
    47 
    48 typedef struct ramfs_inode_s
    49 {
    50     struct vfs_inode_s * vfs_inode;   /*! local pointer on VFS inode                    */
    51 }
    52 ramfs_inode_t;
    53 
    54 
    55 
     70error_t ramfs_ctx_destroy();
    5671
    5772/*****************************************************************************************
    58  * This function allocates memory for a RAMFS inode, and link it to the VFS inode.
    59  *****************************************************************************************
    60  * @ inode   : local pointer on vfs_inode.
    61  * @ return 0 if success / return ENOMEM if error.
     73 * This function does not exist, as the RAMFS does not use a RAMFS inode extension.
    6274 ****************************************************************************************/
    6375error_t ramfs_inode_create( struct vfs_inode_s * inode );
    6476
    6577/*****************************************************************************************
    66  * This function releases memory allocated for a RAMFS inode.
    67  *****************************************************************************************
    68  * @ inode   : local pointer on vfs_inode.
     78 * This function does not exist, as the RAMFS does not use a RAMFS inode extension.
    6979 ****************************************************************************************/
    7080void ramfs_inode_destroy( struct vfs_inode_s * inode );
    7181
    7282/*****************************************************************************************
    73  * This function moves a page from the mapper to the RAMFS file system.
    74  * It must be called by a thread running in cluster containing the mapper.
    75  * The pointer on the mapper and the page index in file are supposed to be registered
    76  * in the page descriptor.
    77 ******************************************************************************************
    78  * @ page    : local pointer on source page descriptor.
    79  * @ return 0 if success / return EIO if error.
     83 * This function does nothing for the RAMFS File System.
    8084 ****************************************************************************************/
    81 error_t ramfs_write_page( struct page_s  * page );
     85error_t ramfs_write_page( struct page_s * page );
    8286
    8387/*****************************************************************************************
    84  * This function moves a page from the RAMFS file system to the mapper.
    85  * It must be called by a thread running in cluster containing the mapper.
    86  * The pointer on the mapper and the page index in file are supposed to be registered
    87  * in the page descriptor.
    88  *****************************************************************************************
    89  * @ page    : local pointer on destination page descriptor.
    90  * @ return 0 if success / return EIO if error.
     88 * This function does not exist for the RAMFS File System.
    9189 ****************************************************************************************/
    92 error_t ramfs_read_page( struct page_s  * page );
     90error_t ramfs_read_page( struct page_s * page );
    9391
    9492
    95    
    9693#endif  /* _RAMFS_H_ */
  • trunk/kernel/vfs/vfs.c

    r14 r23  
    3535#include <slist.h>
    3636#include <xhtab.h>
     37#include <rpc.h>
    3738#include <errno.h>
    3839#include <kmem.h>
     
    4041#include <thread.h>
    4142#include <process.h>
     43#include <vfs.h>
    4244#include <fatfs.h>
    4345#include <ramfs.h>
    44 #include <vfs.h>
     46#include <devfs.h>
     47#include <syscalls.h>
    4548
    4649
     
    4952//////////////////////////////////////////////////////////////////////////////////////////
    5053
    51 // array of supported FS contexts (indexed by the FS type)
     54// array of supported FS contexts
    5255vfs_ctx_t   fs_context[FS_TYPES_NR];
    5356
     
    5659//////////////////////////////////////////////////////////////////////////////////////////
    5760
    58 /////////////////////////////////////////////////
     61////////////////////////////////////////////
    5962error_t vfs_ctx_inum_alloc( vfs_ctx_t * ctx,
    6063                            uint32_t  * inum )
     
    6467
    6568    // get lid from local inum allocator
    66     uint32_t lid = bitmap_ffc( ctx->inum , CONFIG_VFS_MAX_INODES );
     69    uint32_t lid = bitmap_ffc( ctx->bitmap , CONFIG_VFS_MAX_INODES );
    6770
    6871    if( lid == -1 )   // no more free slot => error
     
    7780    {
    7881        // set slot allocated
    79         bitmap_set( ctx->inum , lid );
     82        bitmap_set( ctx->bitmap , lid );
    8083
    8184        // release lock
     
    9295                           uint32_t    inum )
    9396{
    94     bitmap_clear( ctx->inum , inum & 0xFFFF );
     97    bitmap_clear( ctx->bitmap , inum & 0xFFFF );
    9598}
    9699
     
    99102//////////////////////////////////////////////////////////////////////////////////////////
    100103
    101 ////////////////////////////////////////////////
    102 error_t vfs_inode_create( xptr_t      dentry_xp,
    103                           uint32_t    type,
    104                           uint32_t    attr,
    105                           uint32_t    mode,
    106                           uid_t       uid,
    107                           gid_t       gid,
    108                           xptr_t    * inode_xp )
     104//////////////////////////////////////////////////////
     105
     106error_t vfs_inode_create( xptr_t            dentry_xp,
     107                          vfs_fs_type_t     fs_type,
     108                          vfs_inode_type_t  inode_type,
     109                          uint32_t          attr,
     110                          uint32_t          rights,
     111                          uid_t             uid,
     112                          gid_t             gid,
     113                          xptr_t          * inode_xp )
    109114{
    110115    mapper_t         * mapper;     // associated mapper( to be allocated)
     
    115120    error_t            error;
    116121
    117     // check type and get pointer on context
    118     if     ( type == FS_TYPE_FATFS ) ctx = &fs_context[FS_TYPE_FATFS];
    119     else if( type == FS_TYPE_RAMFS ) ctx = &fs_context[FS_TYPE_RAMFS];
     122    // check fs type and get pointer on context
     123    if     ( fs_type == FS_TYPE_FATFS ) ctx = &fs_context[FS_TYPE_FATFS];
     124    else if( fs_type == FS_TYPE_RAMFS ) ctx = &fs_context[FS_TYPE_RAMFS];
     125    else if( fs_type == FS_TYPE_DEVFS ) ctx = &fs_context[FS_TYPE_DEVFS];
    120126    else
    121127    {
     
    144150    }
    145151
    146     // allocate memory for inode descriptor
     152    // allocate memory for VFS inode descriptor
    147153        req.type  = KMEM_VFS_INODE;
    148154        req.size  = sizeof(vfs_inode_t);
     
    160166    // initialize inode descriptor
    161167    inode->gc         = 0;
     168    inode->type       = inode_type;
    162169    inode->inum       = inum;
    163170    inode->attr       = attr;
    164     inode->mode       = mode;
     171    inode->rights     = rights;
    165172    inode->uid        = uid;
    166173    inode->gid        = gid;
     
    174181
    175182    // initialize dentries hash table, if new inode is a directory
    176     if( attr & INODE_ATTR_DIR ) xhtab_init( &inode->children , XHTAB_DENTRY_TYPE );
     183    if( inode_type == INODE_TYPE_DIR ) xhtab_init( &inode->children , XHTAB_DENTRY_TYPE );
    177184
    178185    // initialize inode locks
    179186    remote_rwlock_init( XPTR( local_cxy , &inode->data_lock ) );
    180187    remote_spinlock_init( XPTR( local_cxy , &inode->main_lock ) );
    181 
    182     // create FS specific inode
    183     if     ( ctx->type == FS_TYPE_FATFS )  fatfs_inode_create( inode );
    184     else if( ctx->type == FS_TYPE_RAMFS )  ramfs_inode_create( inode );
    185188
    186189    // return extended pointer on inode
     
    284287//////////////////////////////////////////////////////////////////////////////////////////
    285288
    286 //////////////////////////////////////////////
    287 error_t vfs_dentry_create( uint32_t      type,
    288                            char        * name,
    289                            vfs_inode_t * parent,
    290                            xptr_t      * dentry_xp )
     289///////////////////////////////////////////////////
     290error_t vfs_dentry_create( vfs_fs_type_t   fs_type,
     291                           char          * name,
     292                           vfs_inode_t   * parent,
     293                           xptr_t        * dentry_xp )
    291294{
    292295    vfs_ctx_t      * ctx;        // context descriptor
    293296    vfs_dentry_t   * dentry;     // dentry descriptor (to be allocated)
    294297        kmem_req_t       req;        // request to kernel memory allocator
    295     xptr_t           xhtab_xp;   // extended pointer on xhtab_t embedded in inode
    296     xptr_t           xlist_xp;   // extended pointer on xlist_entry_t in dentry
     298
     299printk("\n            @@@ dentry_create : 0 / name = %s\n", name );
    297300
    298301    // check type and get pointer on context
    299     if     ( type == FS_TYPE_FATFS ) ctx = &fs_context[FS_TYPE_FATFS];
    300     else if( type == FS_TYPE_RAMFS ) ctx = &fs_context[FS_TYPE_RAMFS];
     302    if     ( fs_type == FS_TYPE_FATFS ) ctx = &fs_context[FS_TYPE_FATFS];
     303    else if( fs_type == FS_TYPE_RAMFS ) ctx = &fs_context[FS_TYPE_RAMFS];
     304    else if( fs_type == FS_TYPE_DEVFS ) ctx = &fs_context[FS_TYPE_DEVFS];
    301305    else
    302306    {
     
    309313    uint32_t length = strlen( name );
    310314
    311     if( length > (CONFIG_VFS_MAX_NAME_LENGTH - 1) )
     315    if( length >= CONFIG_VFS_MAX_NAME_LENGTH )
    312316    {
    313317        printk("\n[ERROR] in %s : name too long\n", __FUNCTION__ );
    314318        return EINVAL;
    315319    }
     320
     321printk("\n            @@@ dentry_create : 1 / name = %s\n", name );
    316322
    317323    // allocate memory for dentry descriptor
     
    328334
    329335    // initialize dentry descriptor
     336
    330337    dentry->ctx     = ctx;
    331338    dentry->length  = length;
     
    333340    strcpy( dentry->name , name );
    334341
    335     // return extended pointer on dentry to caller
     342printk("\n            @@@ dentry_create : 2 / name = %s\n", name );
     343
     344    // register dentry in hash table rooted in parent inode
     345    xhtab_insert( XPTR( local_cxy , &parent->children ),
     346                  name,
     347                  XPTR( local_cxy , &dentry->xlist ) );
     348
     349printk("\n            @@@ dentry_create : 3 / name = %s\n", name );
     350
     351    // return extended pointer on dentry
    336352    *dentry_xp = XPTR( local_cxy , dentry );
    337353
    338     // register dentry in hash table rooted in parent inode
    339     xhtab_xp    = XPTR( local_cxy , &parent->children );
    340     xlist_xp    = XPTR( local_cxy , &dentry->xlist );
    341     xhtab_register( xhtab_xp  , name , xlist_xp );
    342    
    343354    return 0;
    344355
     
    365376//////////////////////////////////////////////////////////////////////////////////////////
    366377
    367 ////////////////////////////////////////
    368 void vfs_file_count_up( xptr_t file_xp )
    369 {
    370     // get file cluster and local pointer
    371     cxy_t        file_cxy = GET_CXY( file_xp );
    372     vfs_file_t * file_ptr = (vfs_file_t *)GET_PTR( file_xp );
    373 
    374     // atomically increment count
    375     hal_remote_atomic_add( XPTR( file_cxy , &file_ptr->refcount ) , 1 );
    376 }
    377 
    378 //////////////////////////////////////////
    379 void vfs_file_count_down( xptr_t file_xp )
    380 {
    381     // get file cluster and local pointer
    382     cxy_t        file_cxy = GET_CXY( file_xp );
    383     vfs_file_t * file_ptr = (vfs_file_t *)GET_PTR( file_xp );
    384 
    385     // atomically decrement count
    386     hal_remote_atomic_add( XPTR( file_cxy , &file_ptr->refcount ) , -1 );
    387 }
    388 
    389 ////////////////////////////////////////////////
    390 error_t vfs_file_create( xptr_t        inode_xp,
    391                          uint32_t      type,
     378/////////////////////////////////////////////
     379error_t vfs_file_create( vfs_inode_t * inode,
    392380                         uint32_t      attr,
    393                          xptr_t      * file_xp ) 
    394 {
    395     vfs_file_t  * file_ptr;
     381                         xptr_t      * file_xp )
     382{
     383    vfs_file_t  * file;
    396384        kmem_req_t    req;
    397 
    398     // get inode cluster and local pointer
    399     cxy_t         inode_cxy = GET_CXY( inode_xp );
    400     vfs_inode_t * inode_ptr = (vfs_inode_t *)GET_PTR( inode_xp );
    401 
    402     // check cluster identifier
    403     if( inode_cxy != local_cxy )
    404     {
    405         printk("\n[PANIC] in %s : local cluster is not the inode owner\n", __FUNCTION__ );
    406         hal_core_sleep();
    407     }
    408385
    409386    // allocate memory for new file descriptor
     
    411388        req.size  = sizeof(vfs_file_t);
    412389    req.flags = AF_KERNEL | AF_ZERO;
    413         file_ptr  = (vfs_file_t *)kmem_alloc( &req );
    414 
    415     if( file_ptr == NULL ) return ENOMEM;
    416 
    417     // get inode local pointer
     390        file      = (vfs_file_t *)kmem_alloc( &req );
     391
     392    if( file == NULL ) return ENOMEM;
     393
    418394    // initializes new file descriptor
    419     file_ptr->gc       = 0;
    420     file_ptr->type     = type;
    421     file_ptr->attr     = attr;
    422     file_ptr->offset   = 0;
    423     file_ptr->refcount = 0;
    424     file_ptr->inode    = inode_ptr;
    425     file_ptr->ctx      = inode_ptr->ctx;
    426     file_ptr->mapper   = inode_ptr->mapper;
    427 
    428     remote_rwlock_init( XPTR( local_cxy , &file_ptr->lock ) );
    429 
    430     *file_xp = XPTR( local_cxy , file_ptr );
    431     return 0;
    432 }
    433 
    434 ////////////////////////////////////////
    435 void vfs_file_destroy( xptr_t  file_xp )
    436 {
    437     // get file cluster and local pointer
    438     cxy_t        file_cxy = GET_CXY( file_xp );
    439     vfs_file_t * file_ptr = (vfs_file_t *)GET_PTR( file_xp );
    440 
    441     if( file_cxy != local_cxy )
    442     {
    443         printk("\n[PANIC] in %s : file descriptor not in local cluster\n", __FUNCTION__ );
    444         hal_core_sleep();
    445     }
    446 
    447     if( file_ptr->refcount )
     395    file->gc       = 0;
     396    file->type     = inode->type;
     397    file->attr     = attr;
     398    file->offset   = 0;
     399    file->refcount = 0;
     400    file->inode    = inode;
     401    file->ctx      = inode->ctx;
     402    file->mapper   = inode->mapper;
     403
     404    remote_rwlock_init( XPTR( local_cxy , &file->lock ) );
     405
     406    *file_xp = XPTR( local_cxy , file );
     407    return 0;
     408
     409}  // end vfs_file_create()
     410
     411///////////////////////////////////////////
     412void vfs_file_destroy( vfs_file_t *  file )
     413{
     414    if( file->refcount )
    448415    {
    449416        printk("\n[PANIC] in %s : file refcount non zero\n", __FUNCTION__ );
     
    452419
    453420        kmem_req_t req;
    454         req.ptr   = file_ptr;
     421        req.ptr   = file;
    455422        req.type  = KMEM_VFS_FILE;
    456423        kmem_free( &req );
    457 }
    458 
    459 //////////////////////////////////////////////////////////////////////////////////////////
    460 //           File related functions
     424
     425}  // end vfs_file_destroy()
     426
     427
     428////////////////////////////////////////
     429void vfs_file_count_up( xptr_t file_xp )
     430{
     431    // get file cluster and local pointer
     432    cxy_t        file_cxy = GET_CXY( file_xp );
     433    vfs_file_t * file_ptr = (vfs_file_t *)GET_PTR( file_xp );
     434
     435    // atomically increment count
     436    hal_remote_atomic_add( XPTR( file_cxy , &file_ptr->refcount ) , 1 );
     437}
     438
     439//////////////////////////////////////////
     440void vfs_file_count_down( xptr_t file_xp )
     441{
     442    // get file cluster and local pointer
     443    cxy_t        file_cxy = GET_CXY( file_xp );
     444    vfs_file_t * file_ptr = (vfs_file_t *)GET_PTR( file_xp );
     445
     446    // atomically decrement count
     447    hal_remote_atomic_add( XPTR( file_cxy , &file_ptr->refcount ) , -1 );
     448}
     449
     450//////////////////////////////////////////////////////////////////////////////////////////
     451//           File access related functions
    461452//////////////////////////////////////////////////////////////////////////////////////////
    462453
     
    465456                          char     * path,
    466457                          uint32_t   flags,
    467                           xptr_t   * file_xp )
    468 {
    469     return 0;
    470 }
    471 
    472 ///////////////////////////////////
    473 uint32_t vfs_read( xptr_t   file_xp,
    474                    void   * buffer,
    475                    uint32_t size )
    476 {
    477     return 0;
    478 }
    479 
    480 ////////////////////////////////////
    481 uint32_t vfs_write( xptr_t   file_xp,
    482                     void   * buffer,
    483                     uint32_t size )
    484 {
    485     return 0;
    486 }
     458                  uint32_t   mode,
     459                          xptr_t   * new_file_xp,
     460                  uint32_t * new_file_id )
     461{
     462    error_t       error;
     463    xptr_t        inode_xp;     // extended pointer on target inode
     464    cxy_t         inode_cxy;    // inode cluster identifier       
     465    vfs_inode_t * inode_ptr;    // inode local pointer
     466    uint32_t      file_attr;    // file descriptor attributes
     467    uint32_t      lookup_mode;  // lookup working mode       
     468    xptr_t        file_xp;      // extended pointer on created file descriptor
     469    uint32_t      file_id;      // created file descriptor index in reference fd_array
     470
     471    // compute lookup working mode
     472    lookup_mode = VFS_LOOKUP_OPEN;
     473    if( (flags & O_DIR    )      )  lookup_mode |= VFS_LOOKUP_DIR;
     474    if( (flags & O_CREAT  )      )  lookup_mode |= VFS_LOOKUP_CREATE;
     475    if( (flags & O_EXCL   )      )  lookup_mode |= VFS_LOOKUP_EXCL;
     476 
     477    // compute attributes for the created file
     478    file_attr = 0;
     479    if( (flags & O_RDONLY ) == 0 )  file_attr |= FD_ATTR_READ_ENABLE;
     480    if( (flags & O_WRONLY ) == 0 )  file_attr |= FD_ATTR_WRITE_ENABLE;
     481    if( (flags & O_SYNC   )      )  file_attr |= FD_ATTR_SYNC;
     482    if( (flags & O_APPEND )      )  file_attr |= FD_ATTR_APPEND;
     483    if( (flags & O_CLOEXEC)      )  file_attr |= FD_ATTR_CLOSE_EXEC;
     484
     485    // get extended pointer on target inode
     486    error = vfs_lookup( cwd_xp , path , lookup_mode , &inode_xp );
     487
     488    if( error ) return error;
     489
     490    // get target inode cluster and local pointer
     491    inode_cxy = GET_CXY( inode_xp );
     492    inode_ptr = (vfs_inode_t *)GET_PTR( inode_xp );
     493   
     494    // create a new file descriptor in cluster containing inode
     495    if( inode_cxy == local_cxy )      // target cluster is local
     496    {
     497        error = vfs_file_create( inode_ptr , file_attr , &file_xp );
     498    }
     499    else                              // target cluster is remote
     500    {
     501        rpc_vfs_file_create_client( inode_cxy , inode_ptr , file_attr , &file_xp , &error );
     502    }
     503
     504    if( error )  return error;
     505
     506    // allocate and register a new file descriptor index in reference cluster fd_array
     507    error = process_fd_register( file_xp , &file_id );
     508
     509    if( error ) return error;
     510
     511    // success
     512    *new_file_xp = file_xp;
     513    *new_file_id = file_id;
     514    return 0;
     515
     516}  // end vfs_open()
     517
     518/////////////////////////////////////
     519error_t vfs_move( bool_t   to_buffer,
     520                  xptr_t   file_xp,
     521                  void   * buffer,
     522                  uint32_t size )
     523{
     524    assert( ( file_xp != XPTR_NULL ) , __FUNCTION__ , "file_xp == XPTR_NULL" );
     525
     526    cxy_t              file_cxy;     // remote file descriptor cluster
     527    vfs_file_t       * file_ptr;     // remote file descriptor local pointer
     528    vfs_inode_type_t   inode_type;
     529    uint32_t           file_offset;  // current offset in file
     530    mapper_t         * mapper;
     531    error_t            error;
     532
     533    // get cluster and local pointer on remote file descriptor
     534    file_cxy  = GET_CXY( file_xp );
     535    file_ptr  = (vfs_file_t *)GET_PTR( file_xp );
     536
     537    // get inode type from remote file descriptor
     538    inode_type = hal_remote_lw( XPTR( file_cxy , &file_ptr->type   ) );
     539   
     540    // action depends on inode type
     541    if( inode_type == INODE_TYPE_FILE )
     542    {
     543        // get mapper pointer and file offset from file descriptor
     544        file_offset = hal_remote_lw( XPTR( file_cxy , &file_ptr->offset ) );
     545        mapper = (mapper_t *)hal_remote_lpt( XPTR( file_cxy , &file_ptr->mapper ) );
     546
     547        // move data between mapper and buffer
     548        if( file_cxy == local_cxy )
     549        {
     550            error = mapper_move( mapper,
     551                                 to_buffer,
     552                                 file_offset,
     553                                 buffer,
     554                                 size );
     555        }
     556        else
     557        {
     558            rpc_mapper_move_client( file_cxy,
     559                                    mapper,
     560                                    to_buffer,
     561                                    file_offset,
     562                                    buffer,
     563                                    size,
     564                                    &error );
     565        }
     566
     567        return error;
     568    }
     569    else if (inode_type == INODE_TYPE_DIR )
     570    {
     571        printk("\n[ERROR] in %s : inode is a directory", __FUNCTION__ );
     572        return EINVAL;
     573    }
     574    else if (inode_type == INODE_TYPE_DEV )
     575    {
     576        // TODO
     577        return 0;
     578    }
     579    else
     580    {
     581        printk("\n[PANIC] in %s : illegal inode type\n", __FUNCTION__ );
     582        hal_core_sleep();
     583        return -1;
     584    }
     585}  // end vfs_access()
    487586
    488587//////////////////////////////////////
     
    492591                   uint32_t * new_offset )
    493592{
    494     return 0;
    495 }
    496 
    497 //////////////////////////////////////
    498 error_t vfs_close( xptr_t     file_xp,
    499                    uint32_t * refcount )
    500 {
    501     return 0;
    502 }
     593    printk("\n[PANIC] %s non implemented\n", __FUNCTION__ );
     594    hal_core_sleep();
     595    return 0;
     596
     597    assert( ( file_xp != XPTR_NULL ) , __FUNCTION__ , "file_xp == XPTR_NULL" );
     598
     599}  // vfs_lseek()
     600
     601///////////////////////////////////
     602error_t vfs_close( xptr_t   file_xp,
     603                   uint32_t file_id )
     604{
     605    assert( (file_xp != XPTR_NULL) , __FUNCTION__ , "file_xp == XPTR_NULL" );
     606
     607    assert( (file_id < CONFIG_PROCESS_FILE_MAX_NR) , __FUNCTION__ , "illegal file_id" );
     608
     609    thread_t  * this    = CURRENT_THREAD;
     610    process_t * process = this->process;
     611
     612    // get cluster and local pointer on remote file descriptor
     613    cxy_t        file_cxy = GET_CXY( file_xp );
     614    vfs_file_t * file_ptr = (vfs_file_t *)GET_PTR( file_xp );
     615
     616    // get local pointer on local cluster manager
     617    cluster_t * cluster = LOCAL_CLUSTER;
     618
     619    // get owner process cluster and lpid
     620    cxy_t   owner_cxy  = CXY_FROM_PID( process->pid );
     621    lpid_t  lpid       = LPID_FROM_PID( process->pid );
     622
     623    // get extended pointers on copies root and lock
     624    xptr_t root_xp = XPTR( owner_cxy , &cluster->pmgr.copies_root[lpid] );
     625    xptr_t lock_xp = XPTR( owner_cxy , &cluster->pmgr.copies_lock[lpid] );
     626
     627    // take the lock protecting the copies
     628    remote_spinlock_lock( lock_xp );
     629
     630    // 1) loop on the process descriptor copies to cancel all fd_array[file_id] entries
     631    xptr_t  iter_xp;
     632    XLIST_FOREACH( root_xp , iter_xp )
     633    {
     634        xptr_t      process_xp  = XLIST_ELEMENT( iter_xp , process_t , copies_list );
     635        cxy_t       process_cxy = GET_CXY( process_xp );
     636        process_t * process_ptr = (process_t *)GET_PTR( process_xp );
     637
     638        xptr_t lock_xp  = XPTR( process_cxy , &process_ptr->fd_array.lock );
     639        xptr_t entry_xp = XPTR( process_cxy , &process_ptr->fd_array.array[file_id] );
     640
     641        // lock is required for atomic write of a 64 bits word
     642        remote_rwlock_wr_lock( lock_xp );
     643        hal_remote_swd( entry_xp , XPTR_NULL );
     644        remote_rwlock_wr_unlock( lock_xp );
     645
     646        hal_wbflush();
     647    }   
     648
     649    // 2) release memory allocated to file descriptor in remote cluster
     650    if( file_cxy == local_cxy )             // file cluster is local
     651    {
     652        vfs_file_destroy( file_ptr );
     653    }
     654    else                                    // file cluster is local
     655    {
     656        rpc_vfs_file_destroy_client( file_cxy , file_ptr );
     657    }
     658
     659    return 0;
     660
     661}  // end vfs_close()
    503662
    504663////////////////////////////////////
     
    506665                    char   * path )
    507666{
     667    printk("\n[PANIC] %s non implemented\n", __FUNCTION__ );
     668    hal_core_sleep();
     669    return 0;
     670}  // vfs_unlink()
     671
     672///////////////////////////////////////
     673error_t vfs_stat( xptr_t       file_xp,
     674                  vfs_stat_t * k_stat )
     675{
     676    printk("\n[PANIC] %s non implemented\n", __FUNCTION__ );
     677    hal_core_sleep();
     678    return 0;
     679}
     680
     681////////////////////////////////////////////
     682error_t vfs_readdir( xptr_t         file_xp,
     683                     vfs_dirent_t * k_dirent )
     684{
     685    printk("\n[PANIC] %s non implemented\n", __FUNCTION__ );
     686    hal_core_sleep();
    508687    return 0;
    509688}
    510689
    511690//////////////////////////////////////
    512 error_t vfs_stat( xptr_t       file_xp,
    513                   vfs_stat_t * stat )
    514 {
    515     return 0;
    516 }
    517 
    518 //////////////////////////////////////////////////////////////////////////////////////////
    519 //           Directory related functions
    520 //////////////////////////////////////////////////////////////////////////////////////////
    521 
    522 
    523 
    524 
    525 
    526 //////////////////////////////////////////////////////////////////////////////////////////
     691error_t vfs_mkdir( xptr_t     file_xp,
     692                   char     * path,
     693                   uint32_t   mode )
     694{
     695    printk("\n[PANIC] %s non implemented\n", __FUNCTION__ );
     696    hal_core_sleep();
     697    return 0;
     698}
     699
     700////////////////////////////////////
     701error_t vfs_rmdir( xptr_t   file_xp,
     702                   char   * path )
     703{
     704    printk("\n[PANIC] %s non implemented\n", __FUNCTION__ );
     705    hal_core_sleep();
     706    return 0;
     707}
     708
     709///////////////////////////////////
     710error_t vfs_chdir( xptr_t   cwd_xp,
     711                   char   * path )
     712{
     713    error_t           error;
     714    xptr_t            inode_xp;     // extended pointer on target inode
     715    cxy_t             inode_cxy;    // target inode cluster identifier       
     716    vfs_inode_t     * inode_ptr;    // target inode local pointer
     717    uint32_t          mode;         // lookup working mode       
     718    vfs_inode_type_t  inode_type;   // target inode type
     719
     720    // set lookup working mode
     721    mode = 0;
     722
     723    // get extended pointer on target inode
     724    error = vfs_lookup( cwd_xp , path , mode , &inode_xp );
     725
     726    if( error ) return error;
     727
     728    // get inode cluster and local pointer
     729    inode_cxy = GET_CXY( inode_xp );
     730    inode_ptr = (vfs_inode_t *)GET_PTR( inode_xp );
     731
     732    // get inode type from remote file
     733    inode_type = hal_remote_lw( XPTR( inode_cxy , &inode_ptr->type ) );
     734
     735    if( inode_type != INODE_TYPE_DIR )
     736    {
     737        CURRENT_THREAD->errno = ENOTDIR;
     738        return -1;
     739    }
     740
     741    printk("\n[PANIC] %s non fully implemented\n", __FUNCTION__ );
     742    hal_core_sleep();
     743    return 0;
     744}
     745
     746///////////////////////////////////
     747error_t vfs_chmod( xptr_t   cwd_xp,
     748                   char   * path,
     749                   uint32_t rights )
     750{
     751    error_t           error;
     752    xptr_t            inode_xp;     // extended pointer on target inode
     753    cxy_t             inode_cxy;    // inode cluster identifier       
     754    vfs_inode_t     * inode_ptr;    // inode local pointer
     755    uint32_t          mode;         // lookup working mode
     756    vfs_inode_type_t  inode_type;   // target inode type
     757
     758    // set lookup working mode
     759    mode = 0;
     760 
     761    // get extended pointer on target inode
     762    error = vfs_lookup( cwd_xp , path , mode , &inode_xp );
     763
     764    if( error ) return error;
     765
     766    // get inode cluster and local pointer
     767    inode_cxy = GET_CXY( inode_xp );
     768    inode_ptr = (vfs_inode_t *)GET_PTR( inode_xp );
     769   
     770    // get inode type from remote inode
     771    inode_type = hal_remote_lw( XPTR( inode_cxy , &inode_ptr->type ) );
     772
     773   
     774    printk("\n[PANIC] %s non fully implemented\n", __FUNCTION__ );
     775    hal_core_sleep();
     776    return 0;
     777}
     778
     779///////////////////////////////////
     780error_t vfs_mkfifo( xptr_t   cwd_xp,
     781                    char   * path,
     782                    uint32_t rights )
     783{
     784    printk("\n[PANIC] in %s : not implemented yet\n", __FUNCTION__ );
     785    hal_core_sleep();
     786    return 0;
     787}
     788
     789
     790
     791/////////////////////////////////////////////////////////////////////////////////////////r
    527792//            Inode Tree functions
    528793//////////////////////////////////////////////////////////////////////////////////////////
    529794
    530795//////////////////////////////////////////////////////////////////////////////////////////
    531 // This static function is used by the vfs_lookup() function.
     796// This function is used by the vfs_lookup() function.
    532797// It takes an extended pointer on a remote inode (parent directory inode),
    533798// and check access_rights violation for the calling thread.
     
    641906}
    642907
    643 ////////////////////////////////////////
    644 error_t vfs_lookup( xptr_t       cwd_xp,
    645                     char       * pathname,
    646                     uint32_t     client_uid,
    647                     uint32_t     client_gid,
    648                                         xptr_t     * inode_xp,
    649                     xptr_t     * ctx_xp )
     908//////////////////////////////////////////////
     909error_t vfs_lookup( xptr_t             cwd_xp,
     910                    char             * pathname,
     911                    uint32_t           mode,
     912                                        xptr_t           * inode_xp )
    650913{
    651914    char          name[CONFIG_VFS_MAX_NAME_LENGTH];   // one name in path
    652915
    653     xptr_t        parent_xp;    // extended pointer on parent inode
    654     cxy_t         parent_cxy;   // cluster for parentc inode
    655     vfs_inode_t * parent_ptr;   // local pointer on parent inode 
    656     xptr_t        child_xp;     // extended pointer on child inode
    657     cxy_t         child_cxy;    // cluster for child inode
    658     vfs_inode_t * child_ptr;    // local pointer on child inode 
    659     char        * current;      // current pointer on path
    660     char        * next;         // next value for current pointer   
    661     bool_t        last;         // true when the name is the last in path
    662     bool_t        found;        // true when a child has been found
    663     thread_t    * this;         // pointer on calling thread descriptor
    664     process_t   * process;      // pointer on calling process descriptor
    665     vfs_ctx_t   * ctx;          // parent inode context
    666     uint32_t      type;         // file system type of parent inode
    667     error_t       error;
     916    xptr_t             parent_xp;    // extended pointer on parent inode
     917    cxy_t              parent_cxy;   // cluster for parent inode
     918    vfs_inode_t      * parent_ptr;   // local pointer on parent inode 
     919    xptr_t             child_xp;     // extended pointer on child inode
     920    cxy_t              child_cxy;    // cluster for child inode
     921    vfs_inode_t      * child_ptr;    // local pointer on child inode 
     922    vfs_inode_type_t   inode_type;   // child inode type
     923    vfs_fs_type_t      fs_type;      // File system type
     924    vfs_ctx_t        * ctx_ptr;      // local pointer on FS context
     925    char             * current;      // current pointer on path
     926    char             * next;         // next value for current pointer   
     927    bool_t             last;         // true when the name is the last in path
     928    bool_t             found;        // true when a child has been found
     929    thread_t         * this;         // pointer on calling thread descriptor
     930    process_t        * process;      // pointer on calling process descriptor
     931    error_t            error;
    668932
    669933    this    = CURRENT_THREAD;
     
    687951    do
    688952    {
    689         // get cluster and local pointer for parent inode
    690         parent_cxy = GET_CXY( parent_xp );
    691         parent_ptr = (vfs_inode_t *)GET_PTR( parent_xp );
    692        
    693         // get parent inode FS type
    694         ctx = (vfs_ctx_t *)(intptr_t)hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->ctx ) );
    695         type = ctx->type;
    696 
    697         // get one name from path
     953        // get one name from path and the last flag
    698954        vfs_get_name_from_path( current , name , &next , &last );
    699955
     
    708964            vfs_inode_remote_unlock( parent_xp );
    709965
    710             // insert a new dentry/inode in parent inode
    711             error = vfs_add_child_in_parent( type , parent_xp , name , &child_xp );
     966            // get cluster and local pointer on parent inode
     967            parent_cxy = GET_CXY( parent_xp );
     968            parent_ptr = (vfs_inode_t *)GET_PTR( parent_xp );
     969
     970            // get parent inode FS type
     971            ctx_ptr = (vfs_ctx_t *)hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->ctx ) );
     972            fs_type = ctx_ptr->type;
     973
     974            // get child inode type
     975            if( (last == false) || (mode & VFS_LOOKUP_DIR) ) inode_type = INODE_TYPE_DIR;
     976            else                                             inode_type = INODE_TYPE_FILE;
     977
     978            // insert a child dentry/inode in parent inode
     979            error = vfs_add_child_in_parent( inode_type,
     980                                             fs_type,
     981                                             parent_xp,
     982                                             name,
     983                                             &child_xp );
    712984
    713985            if( error )
     
    723995
    724996        // check access rights
    725         error = vfs_access_denied( child_xp,
    726                                    client_uid,
    727                                    client_gid );
    728         if( error )
    729         {
    730             printk("\n[ERROR] in %s : permission denied for %s\n", __FUNCTION__ , name );
    731             return EACCES;
    732         }
     997        // error = vfs_access_denied( child_xp,
     998        //                            client_uid,
     999        //                            client_gid );
     1000        // if( error )
     1001        // {
     1002        //     printk("\n[ERROR] in %s : permission denied for %s\n", __FUNCTION__ , name );
     1003        //     return EACCES;
     1004        // }
    7331005
    7341006        // take lock on child inode if not last
     
    7531025    // return searched pointers
    7541026    *inode_xp = child_xp;
    755     *ctx_xp   = (xptr_t)hal_remote_lwd( XPTR( child_cxy , &child_ptr->ctx ) );
    7561027
    7571028    return 0;
     
    7701041        uint32_t     count;       // number of characters written in buffer
    7711042        uint32_t     index;       // slot index in buffer
    772     xptr_t       inode_xp;  // extended pointer on   
     1043    xptr_t       inode_xp;    // extended pointer on   
    7731044
    7741045    // implementation note:
     
    8291100}  // end vfs_get_path()
    8301101
    831 ///////////////////////////////////////////////
    832 error_t vfs_add_child_in_parent( uint32_t type,
    833                                  xptr_t   parent_xp,
    834                                  char   * name,   
    835                                  xptr_t * child_xp )
    836 {
    837     xptr_t     dentry_xp;  // extended pointer on created dentry
    838     xptr_t     inode_xp;   // extended pointer on created inode
    839     error_t    error;
     1102///////////////////////////////////////////////////////////////
     1103error_t vfs_add_child_in_parent( vfs_inode_type_t   inode_type,
     1104                                 vfs_fs_type_t      fs_type,
     1105                                 xptr_t             parent_xp,
     1106                                 char             * name,
     1107                                 xptr_t           * child_xp )
     1108{
     1109    error_t         error;
     1110    xptr_t          dentry_xp;   // extended pointer on created dentry
     1111    xptr_t          inode_xp;    // extended pointer on created inode
     1112    cxy_t           parent_cxy;  // parent inode cluster identifier
     1113    vfs_inode_t   * parent_ptr;  // parent inode local pointer
     1114    vfs_ctx_t     * parent_ctx;  // parent inode context local pointer
    8401115
    8411116    // get parent inode cluster and local pointer
    842     cxy_t         parent_cxy = GET_CXY( parent_xp );
    843     vfs_inode_t * parent_ptr = (vfs_inode_t *)GET_PTR( parent_xp );
     1117    parent_cxy = GET_CXY( parent_xp );
     1118    parent_ptr = (vfs_inode_t *)GET_PTR( parent_xp );
     1119
     1120    // get parent inode context local pointer
     1121    parent_ctx = (vfs_ctx_t *)hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->ctx ) );
    8441122
    8451123    // create dentry
    8461124    if( parent_cxy == local_cxy )      // parent cluster is the local cluster
    8471125    {
    848         error = vfs_dentry_create( type,
     1126        error = vfs_dentry_create( fs_type,
    8491127                                   name,
    8501128                                   parent_ptr,
     
    8541132    {
    8551133        rpc_vfs_dentry_create_client( parent_cxy,
    856                                       type,
     1134                                      fs_type,
    8571135                                      name,
    8581136                                      parent_ptr,
     
    8871165    {
    8881166        error = vfs_inode_create( dentry_xp,
    889                                   type,
     1167                                  fs_type,
     1168                                  inode_type,
    8901169                                  attr,
    8911170                                  mode,
     
    8981177        rpc_vfs_inode_create_client( child_cxy,
    8991178                                     dentry_xp,
    900                                      type,
     1179                                     fs_type,
     1180                                     inode_type,
    9011181                                     attr,
    9021182                                     mode,
     
    9251205
    9261206
     1207
     1208
     1209//////////////////////////////////////////////////////////////////////////////////////////
     1210//            Mapper related functions
     1211//////////////////////////////////////////////////////////////////////////////////////////
     1212
     1213////////////////////////////////////////////////
     1214error_t vfs_move_page_to_mapper( page_t * page )
     1215{
     1216    error_t         error = 0;
     1217
     1218    assert( (page != NULL) , __FUNCTION__ , "page pointer is NULL\n" );
     1219
     1220    mapper_t * mapper = page->mapper;
     1221
     1222    assert( (mapper != NULL) , __FUNCTION__ , "no mapper for page\n" );
     1223
     1224    // get FS type
     1225    vfs_fs_type_t fs_type = mapper->inode->ctx->type;
     1226
     1227    // update mapper if permitted by file system type
     1228    if( fs_type == FS_TYPE_FATFS )
     1229    {
     1230        // get mapper lock in WRITE_MODE
     1231        rwlock_wr_lock( &mapper->lock );
     1232
     1233        error = fatfs_read_page( page );
     1234
     1235        // release mapper lock
     1236        rwlock_wr_unlock( &mapper->lock );
     1237    }
     1238    else if( fs_type == FS_TYPE_RAMFS )
     1239    {
     1240        assert( false , __FUNCTION__ , "should not be called for RAMFS\n" );
     1241    }
     1242    else if( fs_type == FS_TYPE_DEVFS )
     1243    {
     1244        assert( false , __FUNCTION__ , "should not be called for DEVFS\n" );
     1245    }
     1246    else
     1247    {
     1248        assert( false , __FUNCTION__ , "undefined file system type\n" );
     1249    }
     1250
     1251    return error;
     1252
     1253}  // end vfs_move_page_to_mapper()
     1254
     1255//////////////////////////////////////////////////
     1256error_t vfs_move_page_from_mapper( page_t * page )
     1257{
     1258    error_t         error = 0;
     1259
     1260    assert( (page != NULL) , __FUNCTION__ , "page pointer is NULL\n" );
     1261
     1262    mapper_t * mapper = page->mapper;
     1263
     1264    assert( (mapper != NULL) , __FUNCTION__ , "no mapper for page\n" );
     1265
     1266    // get FS type
     1267    vfs_fs_type_t  fs_type = mapper->inode->ctx->type;
     1268
     1269    // update file system if permitted by file system type
     1270    if( fs_type == FS_TYPE_FATFS )
     1271    {
     1272            if( page_is_flag( page , PG_DIRTY ) )
     1273            {
     1274            // get mapper lock in READ_MODE
     1275            rwlock_rd_lock( &mapper->lock );
     1276
     1277            error = fatfs_write_page( page );
     1278
     1279            // release mapper lock from READ_MODE
     1280            rwlock_rd_unlock( &mapper->lock );
     1281
     1282            // clear dirty bit if success
     1283                    if( error == 0 ) page_undo_dirty( page );
     1284         }
     1285    }
     1286    else if( fs_type == FS_TYPE_RAMFS )
     1287    {
     1288        assert( false , __FUNCTION__ , "should not be called for RAMFS\n" );
     1289    }
     1290    else if( fs_type == FS_TYPE_DEVFS )
     1291    {
     1292        assert( false , __FUNCTION__ , "should not be called for DEVFS\n" );
     1293    }
     1294    else
     1295    {
     1296        assert( false , __FUNCTION__ , "undefined file system type\n" );
     1297    }
     1298       
     1299    return error;
     1300
     1301}  // end vfs_move_page_from_mapper()
     1302
     1303
  • trunk/kernel/vfs/vfs.h

    r14 r23  
    22 * vfs.h - Virtual File System definition.
    33 *
    4  * Author  Mohamed Lamine Karaoui (2015)
    5  *         Alain Greiner (2016)
     4 * Author  Mohamed Lamine Karaoui (2014,2015)
     5 *         Alain Greiner (2016,2017)
    66 *
    77 * Copyright (c) UPMC Sorbonne Universites
     
    4242#include <fatfs.h>
    4343#include <ramfs.h>
     44#include <devfs.h>
    4445
    4546/****  Forward declarations  ***/
     
    6364struct device_s;
    6465struct vseg_s;
    65 
    66 /*********************************************************************************************
    67  * This defines the various Flags arguments for an open() or opendir() system call.
    68  ********************************************************************************************/
    69 
    70 #define VFS_O_APPEND         0x00080000
    71 #define VFS_O_RDONLY         0x00100000
    72 #define VFS_O_WRONLY         0x00200000
    73 #define VFS_O_RDWR           0x00300000
    74 #define VFS_O_CREATE         0x00400000
    75 #define VFS_O_EXCL           0x00800000
    76 #define VFS_O_TRUNC          0x01000000
    77 #define VFS_O_SYNC               0x08000000
    78 
    79 /*********************************************************************************************
    80  * This defines the various types of command for an lseek() system call.
    81  ********************************************************************************************/
    82 
    83 #define VFS_SEEK_SET         0
    84 #define VFS_SEEK_CUR         1
    85 #define VFS_SEEK_END         2
    86 
    87 /*********************************************************************************************
    88  * TODO : the following flags were defined in the vfs-params.h file...
    89  *        ... and must be documented. [AG]
    90  ********************************************************************************************/
    91 
    92 
    93 //////////////////////////////////////
    94 ///    keep these flags compact    ///
    95 //////////////////////////////////////
    96 #define VFS_REGFILE          0x0000000
    97 #define VFS_DIR              0x0000001
    98 #define VFS_FIFO             0x0000002
    99 #define VFS_DEV_CHR          0x0000004
    100 #define VFS_DEV_BLK          0x0000008
    101 #define VFS_DEV              0x000000C
    102 #define VFS_SOCK             0x0000010
    103 #define VFS_SYMLNK           0x0000020
    104 //////////////////////////////////////
    105 
    106 #define VFS_RD_ONLY          0x0000040
    107 #define VFS_SYS              0x0000080
    108 #define VFS_ARCHIVE          0x0000100
    109 #define VFS_PIPE             0x0000200
    110 
    111 #define VFS_IFMT             0x0170000
    112 #define VFS_IFSOCK           0x0140000
    113 #define VFS_IFLNK            0x0120000
    114 #define VFS_IFREG            0x0100000
    115 #define VFS_IFBLK            0x0060000
    116 #define VFS_IFDIR            0x0040000
    117 #define VFS_IFCHR            0x0020000
    118 #define VFS_IFIFO            0x0010000
    119 
    120 #define VFS_ISUID            0x0004000
    121 #define VFS_ISGID            0x0002000
    122 #define VFS_ISVTX            0x0001000
     66struct page_s;
     67
     68
     69/******************************************************************************************
     70 * These flags are used to define the working mode of the vfs_lookup() function. 
     71 *****************************************************************************************/
     72
     73#define VFS_LOOKUP_DIR      0x01     /* the searched inode is a directory                */
     74#define VFS_LOOKUP_OPEN         0x02     /* the search is for an open/opendir                */
     75#define VFS_LOOKUP_PARENT       0x04     /* return the parent inode (not the inode itself)   */
     76#define VFS_LOOKUP_CREATE   0x10     /* file must be created if missing                  */
     77#define VFS_LOOKUP_EXCL     0x20     /* file cannot previously exist                     */   
     78
     79/******************************************************************************************
     80 * This define the masks for the POSIX access rights to inodes
     81 *****************************************************************************************/
     82
     83#define VFS_ISUID                0x0004000
     84#define VFS_ISGID                0x0002000
     85#define VFS_ISVTX                0x0001000
    12386
    12487#define VFS_IRWXU            0x0000700
     
    12689#define VFS_IWUSR            0x0000200
    12790#define VFS_IXUSR            0x0000100
     91
    12892#define VFS_IRWXG            0x0000070
    12993#define VFS_IRGRP            0x0000040
    13094#define VFS_IWGRP            0x0000020
    13195#define VFS_IXGRP            0x0000010
     96
    13297#define VFS_IRWXO            0x0000007
    13398#define VFS_IROTH            0x0000004
     
    139104#define VFS_IEXEC            VFS_IXUSR
    140105
    141 #define VFS_SET(state,flag)    (state) |= (flag)
    142 #define VFS_IS(state,flag)     (state) & (flag)
    143 #define VFS_CLEAR(state,flag)  (state) &= ~(flag)
    144 
    145 
    146 /* Lookup flags */
    147 #define VFS_LOOKUP_FILE         0x1
    148 #define VFS_LOOKUP_LAST         0x2
    149 #define VFS_LOOKUP_OPEN         0x4
    150 #define VFS_LOOKUP_RESTART      0x8
    151 #define VFS_LOOKUP_RETRY        0x10
    152 #define VFS_LOOKUP_PARENT       0x20
    153 #define VFS_LOOKUP_HELD         0x40
    154 
    155 /* Context flags*/
    156 #define VFS_FS_LOCAL            0x1
    157 #define VFS_FS_USE_MAPPER       0x2
    158 
    159 
    160 
     106
     107/******************************************************************************************
     108 * This structure defines informations common to all inodes and dentries
     109 * of a given file system. As it is declared a global variable in the kdata segment,
     110 * it is replicated in all clusters and handled as private by each OS intance.
     111 *****************************************************************************************/
     112
     113typedef enum
     114{
     115        FS_TYPE_DEVFS = 0,
     116        FS_TYPE_FATFS = 1,
     117        FS_TYPE_RAMFS = 2,
     118 
     119        FS_TYPES_NR   = 3,
     120}
     121vfs_fs_type_t;
     122
     123typedef enum
     124{
     125    CTX_ATTR_READ_ONLY    = 0x01,            /*! write access prohibited                 */
     126    CTX_ATTR_SYNC         = 0x10,            /*! synchronise FS on each write            */
     127}
     128vfs_ctx_attr_t;
     129
     130typedef struct vfs_ctx_s
     131{
     132        vfs_fs_type_t  type;                     /*! File System type                        */
     133        uint32_t           attr;                     /*! global attributes for all files in FS   */
     134        uint32_t       count;                    /*! total number of clusters on device      */
     135        uint32_t       blksize;                  /*! device cluster size (bytes)             */
     136        xptr_t         root_xp;                  /*! extended pointer on root inode          */
     137    spinlock_t     lock;                     /*! lock protecting inum allocator          */
     138    uint32_t       bitmap[BITMAP_SIZE(CONFIG_VFS_MAX_INODES)];  /* inum allocator        */
     139    void         * extend;                   /*! FS specific context extension           */
     140}
     141vfs_ctx_t;
    161142
    162143/******************************************************************************************
     
    166147 * The <parent> inode is unique for a directory (not hard links for directories).
    167148 * For a file, the parent field points to the first dentry who created this inode.
    168  * Syncronisation:
     149 * Syncrhonisation:
    169150 * - the main_lock (spinlock) is used during the inode tree traversal or for inode
    170151 *   modification (add/remove children).
     
    172153 *   in the mapper.
    173154 * - the mapper lock (rwlock) is only used during the radix tree traversal to return
    174  *   to return the relevant page for red/write.
    175  *****************************************************************************************/
     155 *   the relevant page for read/write.
     156 *****************************************************************************************/
     157
     158/* this enum define the VFS inode types values */
    176159
    177160typedef enum   
    178161{
    179     INODE_TYPE_NORMAL,                 /*! file or directory                            */
    180     INODE_TYPE_PIPE,                   /*! POSIX pipe                                   */
    181     INODE_TYPE_SOCKET,                 /*! POSIX socket                                 */
    182     INODE_TYPE_DEV,                    /*! peripheral channel                           */
     162    INODE_TYPE_FILE    =     0x001,      /*! file                                        */
     163    INODE_TYPE_DIR     =     0x002,      /*! directory                                   */
     164    INODE_TYPE_FIFO    =     0x004,      /*! POSIX named pipe                            */
     165    INODE_TYPE_PIPE    =     0x008,      /*! POSIX anonymous pipe                        */
     166    INODE_TYPE_SOCKET  =     0x010,      /*! POSIX socket                                */
     167    INODE_TYPE_DEV     =     0x020,      /*! character peripheral channel                */
     168    INODE_TYPE_SYML    =     0x080,      /*! symbolic link                               */
    183169}
    184170vfs_inode_type_t;
    185171
     172/* this enum define the VFS inode attributes values */
     173
    186174typedef enum
    187175{
    188     INODE_ATTR_DIRTY  = 0x01,
    189     INODE_ATTR_DIR    = 0x02,
    190     INODE_ATTR_INLOAD = 0x04,
    191     INODE_ATTR_NEW    = 0x08,
     176    INODE_ATTR_DIRTY   =     0x01,       /* modified versus the value on device          */
     177    INODE_ATTR_INLOAD  =     0x04,       /* loading from device in progress              */
     178    INODE_ATTR_NEW     =     0x08,       /* not saved on device yet                      */
    192179}
    193180vfs_inode_attr_t;
     
    195182typedef struct vfs_inode_s
    196183{
    197         struct vfs_ctx_s      * ctx;         /*! Rlocal pointer on FS context                */
     184        struct vfs_ctx_s      * ctx;         /*! local pointer on FS context                 */
    198185    uint32_t                gc;          /*! generation counter                          */
    199186        uint32_t                inum;        /*! inode identifier (unique in file system)    */
    200187        uint32_t                attr;        /*! inode attributes (see above)                */
    201         uint32_t                type;        /*! inode type (see above)                      */
     188        vfs_inode_type_t        type;        /*! inode type (see above)                      */
    202189        uint32_t                size;        /*! number of bytes                             */
    203190        uint32_t                links;       /*! number of alias dentry                      */
    204191        uid_t                   uid;         /*! user owner identifier                       */
    205192        gid_t                   gid;         /*! group owner identifier                      */
    206     uint32_t                mode;        /*! access mode                                 */
     193    uint32_t                rights;      /*! access rights                               */
    207194        uint32_t                    refcount;    /*! reference counter (all pointers)            */
    208195        xptr_t                  parent_xp;   /*! extended pointer on parent dentry           */
    209         xhtab_t                 children;    /*! embedded htab of dir entries (for dir type) */
     196        xhtab_t                 children;    /*! embedded xhtab of vfs_dentry_t              */
    210197        remote_rwlock_t         data_lock;   /*! protect read/write to data and to size      */
    211198        remote_spinlock_t       main_lock;   /*! protect inode tree traversal and modifs     */
    212         xlist_entry_t           xlist;       /*! member of set of inodes in same cluster     */
     199        list_entry_t            list;        /*! member of set of inodes in same cluster     */
    213200        xlist_entry_t           wait_root;   /*! root of threads waiting on this inode       */
    214201        struct vfs_inode_op_s * op;          /*! TODO ???                                    */
     
    240227
    241228/******************************************************************************************
    242  * This structure describes an open file/directory for a given process.
     229 * This file structure describes an open file/directory for a given process.
    243230 * It is not replicated, and is dynamically allocated in the cluster that contains
    244231 * the inode, when a thread makes an open() or opendir() system call.
    245  *****************************************************************************************/
    246 
     232 * It cannot exist a file structure without an inode structure.
     233 * Aa the fd_array (containing extended pointers on the open file descriptors)
     234 * is replicated in all process descriptors, we need a references counter.
     235 *****************************************************************************************/
    247236
    248237typedef enum
    249238{
    250     FD_ATTR_READ_ENABLE  = 0x01,       /*! read access possible                         */
    251     FD_ATTR_WRITE_ENABLE = 0x02,       /*! write access possible                        */
    252     FD_ATTR_APPEND       = 0x04,       /*! append on each write                         */
    253     FD_ATTR_CLOSE_EXEC   = 0x08,       /*! close file on exec                           */
    254     FD_ATTR_SYNC         = 0x10,       /*! synchronise FS on each write                 */
    255     FD_ATTR_IS_DIR       = 0x20,       /*! this is a directory                          */
    256 }
    257 vfs_fd_attr_t;
     239    FD_ATTR_READ_ENABLE    = 0x01,     /*! read access possible                         */
     240    FD_ATTR_WRITE_ENABLE   = 0x02,     /*! write access possible                        */
     241    FD_ATTR_APPEND         = 0x04,     /*! append on each write                         */
     242    FD_ATTR_CLOSE_EXEC     = 0x08,     /*! close file on exec                           */
     243    FD_ATTR_SYNC           = 0x10,     /*! synchronise FS on each write                 */
     244    FD_ATTR_IS_DIR         = 0x20,     /*! this is a directory                          */
     245}
     246vfs_file_attr_t;
    258247
    259248typedef struct vfs_file_s
    260249{
     250        struct vfs_ctx_s      * ctx;        /*! local pointer on FS context.                 */
    261251        uint32_t                gc;         /*! generation counter                           */
    262         uint32_t                type;       /*! see above                                    */
    263         uint32_t                attr;       /*! see above                                    */
     252        vfs_file_attr_t         attr;       /*! file attributes bit vector (see above)       */
     253        vfs_inode_type_t        type;       /*! same type as inode                           */
    264254        uint32_t                offset;     /*! seek position in file                        */
    265         uint32_t                refcount;   /*! all pointers on this file                    */
    266         remote_rwlock_t       lock;       /*! protect offset modifications                 */
     255        uint32_t                refcount;   /*! all pointers on this file descriptor         */
     256        remote_rwlock_t         lock;       /*! protect offset modifications                 */
    267257        struct mapper_s       * mapper;     /*! associated file cache                        */
    268258        struct vfs_inode_s    * inode;      /*! local pointer on associated inode            */
    269         struct vfs_ctx_s      * ctx;        /*! file system features                         */
    270         struct vfs_file_op_s  * op;         /*! local set of function pointers               */
     259        void                  * extend;     /*! FS specific extension                        */
    271260}
    272261vfs_file_t;
    273262
    274263/******************************************************************************************
    275  * This structure defines informations common to all inodes and dentries
    276  * of a given file system. As it is declared a global variable in the kdata segment,
    277  * it is replicated in all clusters and handled as private by each OS intance.
    278  *****************************************************************************************/
    279 
    280 typedef enum
    281 {
    282         FS_TYPE_SYSFS = 0,
    283         FS_TYPE_DEVFS = 1,
    284         FS_TYPE_FATFS = 2,
    285         FS_TYPE_RAMFS = 3,
    286  
    287         FS_TYPES_NR   = 4,
    288 }
    289 vfs_types_t;
    290 
    291 typedef enum
    292 {
    293     CTX_ATTR_READ_ONLY    = 0x01,       /*! read access possible                         */
    294     CTX_ATTR_SYNC         = 0x10,       /*! synchronise FS on each write                 */
    295 }
    296 vfs_ctx_attr_t;
    297 
    298 typedef struct vfs_ctx_s
    299 {
    300         uint32_t                      type;          /*! File System type                        */
    301         uint32_t                      attr;          /*! global attributes for all files in FS   */
    302         uint32_t                  count;         /*! number of clusters                      */
    303         uint32_t                  blksize;       /*! cluster size                            */
    304     xptr_t                    ioc_xp;        /*! extended pointer on IOC device          */
    305         xptr_t                    root_xp;       /*! extended pointer on root inode          */
    306 
    307     spinlock_t                lock;          /*! lock protecting inum allocator          */
    308         BITMAP( inum , CONFIG_VFS_MAX_INODES );  /*! inum allocator                          */
    309 
    310     void                    * extend;        /*! FS specific context extension           */
    311 }
    312 vfs_ctx_t;
    313 
    314 /******************************************************************************************
    315  * This structure define the informations associated to a given file descriptor,
    316  * that are returned by the vfs_stat() function.
     264 * This structure define the informations associated to a file descriptor,
     265 * returned to user space by the stat() system call.
    317266 *****************************************************************************************/
    318267
     
    335284vfs_stat_t;
    336285
    337 
    338 
    339 
    340 
    341 
    342 /******************************************************************************************
    343  * This structure defines the set of operations that can be done on a VFS context.
    344  * TODO A quoi cela sert-il ? [AG]
    345  *****************************************************************************************/
    346 
    347 typedef error_t (vfs_create_context_t)  ( vfs_ctx_t * context );
    348 typedef error_t (vfs_destroy_context_t) ( vfs_ctx_t * context );
    349 typedef error_t (vfs_read_root_t)       ( vfs_ctx_t * context , vfs_inode_t * root );
    350 typedef error_t (vfs_reply_root_t)      ( vfs_ctx_t * context , vfs_inode_t * root );
    351 typedef error_t (vfs_write_root_t)      ( vfs_ctx_t * context , vfs_inode_t * root );
    352 
    353 struct vfs_ctx_op_s
    354 {
    355         vfs_create_context_t  * create;      /*! allocate memory and initialize a context   */
    356         vfs_destroy_context_t * destroy;     /*! release memory allocated to a context      */
    357         vfs_read_root_t       * read_root;   /*! TODO                                       */
    358         vfs_reply_root_t      * repli_root;  /*! TODO                                       */
    359         vfs_write_root_t      * write_root;  /*! TODO                                       */
    360 }
    361 vfs_ctx_op_t;
    362 
    363 /******************************************************************************************
    364  * This structure defines the set of operations that can be done on a VFS inode.
    365  * TODO A quoi cela sert-il ? [AG]
    366  *****************************************************************************************/
    367 
    368 typedef error_t (vfs_init_inode_t)    ( vfs_inode_t * inode );
    369 typedef error_t (vfs_create_inode_t)  ( vfs_inode_t * parent , vfs_dentry_t  * dentry );
    370 typedef error_t (vfs_lookup_inode_t)  ( vfs_inode_t * parent , vfs_dentry_t  * dentry );
    371 typedef error_t (vfs_write_inode_t)   ( vfs_inode_t * inode );
    372 typedef error_t (vfs_release_inode_t) ( vfs_inode_t * inode );
    373 typedef error_t (vfs_unlink_inode_t)  ( vfs_inode_t * parent , vfs_dentry_t  * dentry , uint32_t flags );
    374 typedef error_t (vfs_stat_inode_t)    ( vfs_inode_t * inode );
    375 typedef error_t (vfs_trunc_inode_t)   ( vfs_inode_t * inode );
    376 typedef error_t (vfs_delete_inode_t)  ( vfs_inode_t * inode );
    377 
    378 typedef struct vfs_inode_op_s
    379 {
    380         vfs_init_inode_t    * init;     /*! initialise inode from scratch                    */
    381         vfs_create_inode_t  * create;   /*! allocate memory for one inode                    */
    382         vfs_lookup_inode_t  * lookup;   /*! get one directory entry by name                  */
    383         vfs_write_inode_t   * write;    /*! update the device from the inode                 */
    384         vfs_release_inode_t * release;  /*! reset one inode and release associated objects   */
    385         vfs_unlink_inode_t  * unlink;   /*! unlink a directory entry from parent inode       */
    386         vfs_delete_inode_t  * delete;   /*! release memory allocated to inode when count = 0 */
    387         vfs_stat_inode_t    * stat;     /*! TODO                                             */
    388         vfs_trunc_inode_t   * trunc;    /*! change the size of a file                        */
    389 }
    390 vfs_inode_op_t;
    391 
    392 /******************************************************************************************
    393  * This structure defines the set of operations that can be done on a VFS dentry.
    394  * TODO A quoi cela sert-il ? [AG]
    395  *****************************************************************************************/
    396 
    397 typedef error_t (vfs_compare_dentry_t) ( char * first , char * second );
    398 
    399 typedef struct vfs_dentry_op_s
    400 {
    401         vfs_compare_dentry_t * compare;
    402 }
    403 vfs_dentry_op_t;
    404 
    405 /******************************************************************************************
    406  * This structure defines the set of operations that can be done on a VFS file. 
    407  * TODO A quoi cela sert-il ? [AG]
    408  *****************************************************************************************/
    409 
    410 typedef error_t (vfs_open_file_t)    ( vfs_file_t * file , void * priv );
    411 typedef error_t (vfs_read_file_t)    ( vfs_file_t * file , char * buffer );
    412 typedef error_t (vfs_write_file_t)   ( vfs_file_t * file , char * buffer );
    413 typedef error_t (vfs_lseek_file_t)   ( vfs_file_t * file );
    414 typedef error_t (vfs_close_file_t)   ( vfs_file_t * file );
    415 typedef error_t (vfs_release_file_t) ( vfs_file_t * file );
    416 typedef error_t (vfs_read_dir_t)     ( vfs_file_t * file );
    417 typedef error_t (vfs_mmap_file_t)    ( vfs_file_t * file , struct vseg_s * vseg );
    418 typedef error_t (vfs_munmap_file_t)  ( vfs_file_t * file , struct vseg_s * vseg );
    419 
    420 typedef struct vfs_file_op_s
    421 {
    422         vfs_open_file_t    * open;
    423         vfs_read_file_t    * read;
    424         vfs_write_file_t   * write;
    425         vfs_lseek_file_t   * lseek;
    426         vfs_read_dir_t     * readdir;
    427         vfs_close_file_t   * close;
    428         vfs_release_file_t * release;
    429         vfs_mmap_file_t    * mmap;
    430         vfs_munmap_file_t  * munmap;
    431 }
    432 vfs_file_op_t;
    433 
    434 
    435 
     286/*********************************************************************************************
     287 * This structure defines the information associated to a directory entry,
     288 * returned to user space by the readdir() system call.
     289 ********************************************************************************************/
     290
     291typedef struct vfs_dirent_s
     292{
     293    uint32_t    inum;                               /*! inode identifier                    */
     294    uint32_t    type;                               /*! inode type                          */
     295    char        name[CONFIG_VFS_MAX_NAME_LENGTH];   /*! dentry name                         */
     296}
     297vfs_dirent_t;
    436298
    437299
     
    441303/*****************************************************************************************/
    442304
    443 /******************************************************************************************
    444  * This function initializes the Virtual File System.     
    445  *****************************************************************************************/
    446 void vfs_init();
    447 
    448 /******************************************************************************************
    449  * This function mount a given file system type for a given process.     
     305
     306/******************************************************************************************
     307 * This function mount a given file system type for a given process TODO.     
    450308 *****************************************************************************************/
    451309error_t vfs_mount_fs_root( struct device_s  * device,
     
    482340
    483341
    484 /*****************************************************************************************/
    485 /************************ File Descriptor related functions ******************************/
     342
     343/*****************************************************************************************/
     344/********************* Inode related functions *******************************************/
     345/*****************************************************************************************/
     346
     347/******************************************************************************************
     348 * This function allocates memory from local cluster for an inode descriptor and the
     349 * associated mapper. It initialise these descriptors from arguments values.
     350 * The parent dentry must have been previously created.
     351 * If the client thread is not running in the cluster containing this inode,
     352 * it must use the rpc_vfs_inode_create_client() function.
     353 ******************************************************************************************
     354 * @ dentry_xp  : extended pointer on associated dentry (in parent inode cluster).
     355 * @ fs_type    : file system type.
     356 * @ inode_type : inode type.
     357 * @ attr       : inode attributes.
     358 * @ rights     : inode access rights.
     359 * @ uid        : user owner ID.
     360 * @ gid        : group owner ID.
     361 * @ inode_xp   : [out] buffer for extended pointer on created inode.
     362 * # return 0 if success / return ENOMEM or EINVAL if error.
     363 *****************************************************************************************/
     364error_t vfs_inode_create( xptr_t            dentry_xp,
     365                          vfs_fs_type_t     fs_type,
     366                          vfs_inode_type_t  inode_type,
     367                          uint32_t          attr,
     368                          uint32_t          rights,
     369                          uid_t             uid,
     370                          gid_t             gid,
     371                          xptr_t          * inode_xp );
     372
     373/******************************************************************************************
     374 * This function releases memory allocated to an inode descriptor.
     375 * It must be executed by a thread running in the cluster containing the inode,
     376 * and the inode refcount must be zero.
     377 * If the client thread is not running in the owner cluster, it must use the
     378 * rpc_vfs_inode_destroy_client() function.
     379 ******************************************************************************************
     380 * @ inode  : local pointer on inode descriptor.
     381 *****************************************************************************************/
     382void vfs_inode_destroy( vfs_inode_t *  inode ); 
     383
     384/******************************************************************************************
     385 * This function atomically increment/decrement the inode refcount.
     386 * It can be called by any thread running in any cluster.
     387 *****************************************************************************************/
     388void vfs_inode_remote_up( xptr_t  inode_xp );
     389void vfs_inode_remote_down( xptr_t  inode_xp );
     390
     391/******************************************************************************************
     392 * This function returns the <size> of a file/dir from a remote inode,
     393 * taking the remote_rwlock protecting <size> in READ_MODE.
     394 *****************************************************************************************
     395 * @ inode_xp  : extended pointer on the remote inode.
     396 * @ return the current size.
     397 *****************************************************************************************/
     398uint32_t vfs_inode_get_size( xptr_t inode_xp );
     399
     400/******************************************************************************************
     401 * This function set the <size> of a file/dir to a remote inode,
     402 * taking the remote_rwlock protecting <size> in WRITE_MODE.
     403 *****************************************************************************************
     404 * @ inode_xp  : extended pointer on the remote inode.
     405 * @ size      : value to be written.
     406 *****************************************************************************************/
     407void vfs_inode_set_size( xptr_t   inode_xp,
     408                         uint32_t size );
     409
     410/******************************************************************************************
     411 * This function takes the main lock of a remote inode.
     412 * This lock protect all inode fiels, including the children dentries.
     413 *****************************************************************************************
     414 * @ inode_xp  : extended pointer on the remote inode.
     415 *****************************************************************************************/
     416void vfs_inode_remote_lock( xptr_t inode_xp );
     417
     418/******************************************************************************************
     419 * This function releases the main lock of a remote inode.
     420 * This lock protect all inode fiels, including the children dentries.
     421 *****************************************************************************************
     422 * @ inode_xp  : extended pointer on the remote inode.
     423 *****************************************************************************************/
     424void vfs_inode_remote_unlock( xptr_t inode_xp );
     425
     426
     427
     428
     429/******************************************************************************************
     430 * This function TODO                                                         
     431 *****************************************************************************************/
     432error_t vfs_inode_hold( vfs_inode_t * inode,
     433                        uint32_t      gc );
     434
     435/******************************************************************************************
     436 * This function TODO                                                         
     437 *****************************************************************************************/
     438error_t vfs_inode_trunc( vfs_inode_t * inode );
     439
     440/******************************************************************************************
     441 * This function TODO                                                         
     442 *****************************************************************************************/
     443error_t vfs_inode_link( vfs_inode_t * inode,
     444                        uint32_t      igc );
     445
     446/******************************************************************************************
     447 * This function TODO                                                         
     448 *****************************************************************************************/
     449error_t vfs_inode_unlink( vfs_inode_t * inode );
     450
     451/******************************************************************************************
     452 * This function TODO                                                         
     453 *****************************************************************************************/
     454error_t vfs_inode_stat( vfs_inode_t * inode,
     455                        uint32_t      inum );
     456
     457/******************************************************************************************
     458 * This function TODO                                                         
     459 *****************************************************************************************/
     460error_t vfs_icache_del( vfs_inode_t * inode );
     461
     462
     463/******************************************************************************************
     464 * This function TODO  Pourquoi 2 arguments ?
     465 *****************************************************************************************/
     466error_t vfs_stat_inode( vfs_inode_t * inode,
     467                        uint32_t      inum );
     468
     469
     470/*****************************************************************************************/
     471/***************** Dentry related functions **********************************************/
     472/*****************************************************************************************/
     473
     474/******************************************************************************************
     475 * This function allocates memory from local cluster for a dentry descriptor,
     476 * initialises it from  arguments values, and returns the extended pointer on dentry.
     477 * The inode field is not initialized, because the inode does not exist yet.
     478 * If the client thread is not running in the target cluster for this inode,
     479 * it must use the rpc_dentry_create_client() function.
     480 ******************************************************************************************
     481 * @ fs_type    : file system type.
     482 * @ name       : directory entry file/dir name.
     483 * @ parent     : local pointer on parent inode.
     484 * @ dentry_xp  : [out] buffer for extended pointer on created dentry.
     485 * @ return 0 if success / return ENOMEM or EINVAL if error.
     486 *****************************************************************************************/
     487error_t vfs_dentry_create( vfs_fs_type_t   fs_type,
     488                           char          * name,
     489                           vfs_inode_t   * parent,
     490                           xptr_t        * dentry_xp );
     491 
     492/******************************************************************************************
     493 * This function releases memory allocated to a dentry descriptor.
     494 * It must be executed by a thread running in the cluster containing the dentry,
     495 * and the dentry refcount must be zero.
     496 * If the client thread is not running in the owner cluster, it must use the
     497 * rpc_dentry_destroy_client() function.
     498 ******************************************************************************************
     499 * @ dentry  : local pointer on dentry descriptor.
     500 *****************************************************************************************/
     501void vfs_dentry_destroy( vfs_dentry_t *  dentry ); 
     502
     503/******************************************************************************************
     504 * These functions atomically increment/decrement the dentry refcount.
     505 * It can be called by any thread running in any cluster.
     506 *****************************************************************************************/
     507void vfs_dentry_remote_up( xptr_t dentry_xp );
     508void vfs_dentry_remote_down( xptr_t dentry_xp );
     509
     510
     511/*****************************************************************************************/
     512/************************ File descriptor related functions ******************************/
    486513/*****************************************************************************************/
    487514
    488515/******************************************************************************************
    489516 * This function allocates memory and initializes a new local file descriptor.
    490  * It must be executed in the owner cluster containing the inode.
     517 * It must be executed in the cluster containing the inode.
    491518 * If the client thread is not running in the owner cluster, it must use the
    492519 * rpc_vfs_file_create_client() function.
    493520 ******************************************************************************************
    494  * @ inode_xp : extended pointer on associated inode.
    495  * @ type     : file descriptor type.
     521 * @ inode    : local pointer on associated inode.
    496522 * @ attr     : file descriptor attributes.
    497523 * @ file_xp  : [out] buffer for extended pointer on created file descriptor.
    498524 * @ return 0 if success / return ENOMEM if error.
    499525 *****************************************************************************************/
    500 error_t vfs_file_create( xptr_t     inode_xp,
    501                          uint32_t   type,
    502                          uint32_t   attr,
    503                          xptr_t   * file_xp ); 
     526error_t vfs_file_create( vfs_inode_t * inode,
     527                         uint32_t      attr,
     528                         xptr_t      * file_xp ); 
    504529
    505530/******************************************************************************************
     
    510535 * rpc_vfs_file_destroy_client() function.
    511536 ******************************************************************************************
    512  * @ file_xp  : extended pointer on file descriptor.
    513  *****************************************************************************************/
    514 void vfs_file_destroy( xptr_t  file_xp ); 
    515 
     537 * @ file  : local pointer on file descriptor.
     538 *****************************************************************************************/
     539void vfs_file_destroy( vfs_file_t *  file ); 
    516540
    517541/******************************************************************************************
     
    525549
    526550/*****************************************************************************************/
    527 /********************* Inode related functions *******************************************/
    528 /*****************************************************************************************/
    529 
    530 /******************************************************************************************
    531  * This function allocates memory from local cluster for an inode descriptor and the
    532  * associated mapper. It initialise these descriptors from arguments values.
    533  * The parent dentry must have been previously created.
    534  * If the client thread is not running in the cluster containing this inode,
    535  * it must use the rpc_vfs_inode_create_client() function.
    536  ******************************************************************************************
    537  * @ dentry_xp  : extended pointer on associated dentry (in parent inode cluster).
    538  * @ type       : file system type.
    539  * @ attr       : inode attributes.
    540  * @ mode       : inode access mode.
    541  * @ uid        : user owner ID.
    542  * @ gid        : group owner ID.
    543  * @ inode_xp   : [out] buffer for extended pointer on created inode.
    544  * # return 0 if success / return ENOMEM or EINVAL if error.
    545  *****************************************************************************************/
    546 error_t vfs_inode_create( xptr_t      dentry_xp,
    547                           uint32_t    type,
    548                           uint32_t    attr,
    549                           uint32_t    mode,
    550                           uid_t       uid,
    551                           gid_t       gid,
    552                           xptr_t    * inode_xp );
    553 
    554 /******************************************************************************************
    555  * This function releases memory allocated to an inode descriptor.
    556  * It must be executed by a thread running in the cluster containing the inode,
    557  * and the inode refcount must be zero.
    558  * If the client thread is not running in the owner cluster, it must use the
    559  * rpc_vfs_inode_destroy_client() function.
    560  ******************************************************************************************
    561  * @ inode  : local pointer on inode descriptor.
    562  *****************************************************************************************/
    563 void vfs_inode_destroy( vfs_inode_t *  inode ); 
    564 
    565 /******************************************************************************************
    566  * This function atomically increment the inode refcount.
    567  * It can be called by any thread running in any cluster.
    568  *****************************************************************************************/
    569 void vfs_inode_remote_up( xptr_t  inode_xp );
    570 
    571 /******************************************************************************************
    572  * This function atomically decrement the inode refcount.
    573  * It can be called by any thread running in any cluster.
    574  *****************************************************************************************/
    575 void vfs_inode_remote_down( xptr_t  inode_xp );
    576 
    577 /******************************************************************************************
    578  * This function returns the <size> of a file/dir from a remote inode,
    579  * taking the remote_rwlock protecting <size> in READ_MODE.
    580  *****************************************************************************************
    581  * @ inode_xp  : extended pointer on the remote inode.
    582  * @ return the current size.
    583  *****************************************************************************************/
    584 uint32_t vfs_inode_get_size( xptr_t inode_xp );
    585 
    586 /******************************************************************************************
    587  * This function set the <size> of a file/dir to a remote inode,
    588  * taking the remote_rwlock protecting <size> in WRITE_MODE.
    589  *****************************************************************************************
    590  * @ inode_xp  : extended pointer on the remote inode.
    591  * @ size      : value to be written.
    592  *****************************************************************************************/
    593 void vfs_inode_set_size( xptr_t   inode_xp,
    594                          uint32_t size );
    595 
    596 /******************************************************************************************
    597  * This function takes the main lock of a remote inode.
    598  * This lock protect all inode fiels, including the children dentries.
    599  *****************************************************************************************
    600  * @ inode_xp  : extended pointer on the remote inode.
    601  *****************************************************************************************/
    602 void vfs_inode_remote_lock( xptr_t inode_xp );
    603 
    604 /******************************************************************************************
    605  * This function releases the main lock of a remote inode.
    606  * This lock protect all inode fiels, including the children dentries.
    607  *****************************************************************************************
    608  * @ inode_xp  : extended pointer on the remote inode.
    609  *****************************************************************************************/
    610 void vfs_inode_remote_unlock( xptr_t inode_xp );
    611 
    612 
    613 
    614 
    615 /******************************************************************************************
    616  * This function TODO                                                         
    617  *****************************************************************************************/
    618 error_t vfs_inode_hold( vfs_inode_t * inode,
    619                         uint32_t      gc );
    620 
    621 /******************************************************************************************
    622  * This function TODO                                                         
    623  *****************************************************************************************/
    624 error_t vfs_inode_trunc( vfs_inode_t * inode );
    625 
    626 /******************************************************************************************
    627  * This function TODO                                                         
    628  *****************************************************************************************/
    629 error_t vfs_inode_link( vfs_inode_t * inode,
    630                         uint32_t      igc );
    631 
    632 /******************************************************************************************
    633  * This function TODO                                                         
    634  *****************************************************************************************/
    635 error_t vfs_inode_unlink( vfs_inode_t * inode );
    636 
    637 /******************************************************************************************
    638  * This function TODO                                                         
    639  *****************************************************************************************/
    640 error_t vfs_inode_stat( vfs_inode_t * inode,
    641                         uint32_t      inum );
    642 
    643 /******************************************************************************************
    644  * This function TODO                                                         
    645  *****************************************************************************************/
    646 error_t vfs_icache_del( vfs_inode_t * inode );
    647 
    648 
    649 /******************************************************************************************
    650  * This function TODO  Pourquoi 2 arguments ?
    651  *****************************************************************************************/
    652 error_t vfs_stat_inode( vfs_inode_t * inode,
    653                         uint32_t      inum );
    654 
    655 
    656 /*****************************************************************************************/
    657 /***************** Dentry related functions **********************************************/
    658 /*****************************************************************************************/
    659 
    660 /******************************************************************************************
    661  * This function allocates memory from local cluster for a dentry descriptor,
    662  * initialises it from  arguments values, and returns the extended pointer on dentry.
    663  * The inode field is not initialized, because the inode does not exist yet.
    664  * If the client thread is not running in the target cluster for this inode,
    665  * it must use the rpc_dentry_create_client() function.
    666  ******************************************************************************************
    667  * @ type       : file system type.
    668  * @ name       : directory entry file/dir name.
    669  * @ parent     : local pointer on parent inode.
    670  * @ dentry_xp  : [out] buffer for extended pointer on created inode.
    671  * @ return 0 if success / return ENOMEM or EINVAL if error.
    672  *****************************************************************************************/
    673 error_t vfs_dentry_create( uint32_t      type,
    674                            char        * name,
    675                            vfs_inode_t * parent,
    676                            xptr_t      * dentry_xp );
    677  
    678 /******************************************************************************************
    679  * This function releases memory allocated to a dentry descriptor.
    680  * It must be executed by a thread running in the cluster containing the dentry,
    681  * and the dentry refcount must be zero.
    682  * If the client thread is not running in the owner cluster, it must use the
    683  * rpc_dentry_destroy_client() function.
    684  ******************************************************************************************
    685  * @ dentry  : local pointer on dentry descriptor.
    686  *****************************************************************************************/
    687 void vfs_dentry_destroy( vfs_dentry_t *  dentry ); 
    688 
    689 /******************************************************************************************
    690  * This function atomically increment the dentry refcount.                               
    691  * It can be called by any thread running in any cluster.
    692  *****************************************************************************************/
    693 void vfs_dentry_remote_up( xptr_t dentry_xp );
    694 
    695 /******************************************************************************************
    696  * This function atomically decrement the dentry refcount.                               
    697  * It can be called by any thread running in any cluster.
    698  *****************************************************************************************/
    699 void vfs_dentry_remote_down( xptr_t dentry_xp );
    700 
    701 
    702 /*****************************************************************************************/
    703 /*                 Inode-Tree related functions                                          */
     551/******************* Inode-Tree related functions ****************************************/
    704552/*****************************************************************************************/
    705553
     
    721569/******************************************************************************************
    722570 * This function takes a pathname (absolute or relative to cwd) and returns an extended
    723  * pointer on the associated inode, and an extended pointer on the inode context.
    724  * If a given name in the path is not found in the inode tree, it try to load the missing
    725  * dentry/inode couple, from informations found in the parent directory.
    726  * If this directory entry does not exist on device, it returns an error.
    727  ******************************************************************************************
    728  * @ cwd_xp     : extended pointer on current directory (for relative path).
    729  * @ pathname   : path in kernel space (can be relative or absolute).
    730  * @ client_uid : client thread user ID (for checking).
    731  * @ client_gid : client thread group ID (for checking).
    732  * @ inode_xp   : [out] buffer for extended pointer on inode.
    733  * @ ctx_xp     : [out] buffer for extended pointer on inode context.
    734  * @ return 0 if success / ENOENT if inode not found / EACCES if permissopn denied
    735  *****************************************************************************************/
    736 error_t vfs_lookup( xptr_t       cwd_xp,
    737                     char       * pathname,
    738                     uint32_t     client_uid,
    739                     uint32_t     client_gid,
    740                                         xptr_t     * inode_xp,
    741                     xptr_t     * ctx_xp );
     571 * pointer on the associated inode.
     572 * - If a given name in the path is not found in the inode tree, it try to load the missing
     573 *   dentry/inode couple, from informations found in the parent directory.
     574 * - If this directory entry does not exist on device, it returns an error.
     575 * - If the the file identified by the pathname does not exist on device but the
     576 *   flag CREATE is set, the inode is created.
     577 * - If the the file identified by the pathname exist on device but both flags EXCL
     578 *   and CREATE are set, an error is returned.
     579 ******************************************************************************************
     580 * @ cwd_xp      : extended pointer on current directory (for relative path).
     581 * @ pathname    : path in kernel space (can be relative or absolute).
     582 * @ lookup_mode : flags defining the working mode (defined above in this file).
     583 * @ inode_xp    : [out] buffer for extended pointer on inode.
     584 * @ return 0 if success / ENOENT if inode not found , EACCES if permissopn denied,
     585 *                        EAGAIN if a new complete lookup must be made
     586 *****************************************************************************************/
     587error_t vfs_lookup( xptr_t             cwd_xp,
     588                    char             * pathname,
     589                    uint32_t           lookup_mode,
     590                                        xptr_t           * inode_xp );
    742591
    743592/******************************************************************************************
     
    747596 * - The dentry is created in the cluster containing the existing <parent_xp> inode.
    748597 * - the child inode and its associated mapper are created in a randomly selected cluster.
    749  * - The dentry name is defined by the <name> argument.
    750  ******************************************************************************************
    751  * @ type       : new inode type
     598 * - The new dentry name is defined by the <name> argument.
     599 * - The new inode and the parent inode can have different FS types.
     600 ******************************************************************************************
     601 * @ inode_type : new inode type
     602 * @ fs_type    : new inode FS type.
    752603 * @ parent_xp  : extended pointer on parent inode.
    753604 * @ name       : new directory entry name.
     
    755606 * @ return 0 if success / ENOENT if entry not found in parent directory
    756607 *****************************************************************************************/
    757 error_t vfs_add_child_in_parent( uint32_t type,
    758                                  xptr_t   parent_xp,
    759                                  char   * name,   
    760                                  xptr_t * child_xp );
    761 
    762 /******************************************************************************************
    763  * TODO
     608error_t vfs_add_child_in_parent( vfs_inode_type_t   inode_type,
     609                                 vfs_fs_type_t      fs_type,
     610                                 xptr_t             parent_xp,
     611                                 char             * name,   
     612                                 xptr_t           * child_xp );
     613
     614/******************************************************************************************
     615 * This function removes a couple dentry/inode from the Inode-Tree, and remove it from
     616 * the external device.
     617 * TODO                   
    764618 ******************************************************************************************
    765619 * @ child_xp   : extended pointer on removed inode.
     
    767621error_t vfs_remove_child_from_parent( xptr_t child_xp );
    768622
    769 /*****************************************************************************************/
    770 /************************ File related functions *****************************************/
     623
     624
     625
     626
     627
     628/*****************************************************************************************/
     629/****************** File access API ******************************************************/
    771630/*****************************************************************************************/
    772631
    773632/******************************************************************************************
    774633 * This function allocates a vfs_file_t structure in the cluster containing the inode
    775  * associated to the requested file, initializes it, and returns an extended pointer
    776  * on this remote open file descriptor.
     634 * associated to the file identified by <cwd_xp> & <path>.
     635 * It initializes it, register it in the reference process fd_array, and returns both
     636 * the extended pointer on the remote file descriptor, and the index in the fd_array.
    777637 * The pathname can be relative to current directory or absolute.
    778  * If the inode does not exist in the inode cache, it try to find file on the mounted
     638 * If the inode does not exist in the inode cache, it try to find the file on the mounted
    779639 * device, and creates an inode on a pseudo randomly selected cluster if found.
    780640 * It the requested file does not exist on device, it creates a new inode if the
    781641 * O_CREAT flag is set and return an error otherwise.
    782642 ******************************************************************************************
    783  * @ cwd_xp    : extended pointer on current directory file descriptor (for relative path).
    784  * @ path      : file pathname (absolute or relative to current directory).
    785  * @ flags     : O_RDONLY, O_WRONLY, O_CREATE etc...
    786  * @ file_xp   : [out] buffer for extended pointer on created remote file descriptor.
     643 * @ cwd_xp      : extended pointer on current working directory file descriptor.
     644 * @ path        : file pathname (absolute or relative to current directory).
     645 * @ flags       : defined above
     646 * @ mode        : access rights (as defined by chmod)
     647 * @ file_xp     : [out] buffer for extended pointer on created remote file descriptor.
     648 * @ file_id     : [out] buffer for created file descriptor index in reference fd_array.
    787649 * @ return 0 if success / return non-zero if error.
    788650 *****************************************************************************************/
     
    790652                          char     * path,
    791653                          uint32_t   flags,
    792                           xptr_t   * file_xp );
    793 
    794 /******************************************************************************************
    795  * This function moves <size> bytes from the file identified by the open file descriptor
    796  * <file_xp> to the local kernel <buffer> , taken into account the offset in <file_xp>.
    797  ******************************************************************************************
    798  * @ file_xp   : extended pointer on the remote open file descriptor.
    799  * @ buffer    : local pointer on destination kernel buffer.
     654                  uint32_t   mode,
     655                          xptr_t   * file_xp,
     656                          uint32_t * file_id );
     657
     658/******************************************************************************************
     659 * This function moves <size> bytes between the file identified by the open file descriptor
     660 * <file_xp> and a local kernel <buffer> , taken into account the offset in <file_xp>.
     661 * The transfer direction is defined by the <to_buffer> argument.
     662 ******************************************************************************************
     663 * @ to_buffer : mapper -> buffer if true / buffer->mapper if false.
     664 * @ file_xp   : extended pointer on the remote file descriptor.
     665 * @ buffer    : local pointer on local kernel buffer.
    800666 * @ size      : requested number of bytes from offset.
    801  * @ returns number of bytes actually transfered / 0 if EOF / -1 if error.
    802  *****************************************************************************************/
    803 uint32_t vfs_read( xptr_t   file_xp,
    804                    void   * buffer,
    805                    uint32_t size );
    806 
    807 /******************************************************************************************
    808  * This function moves <size> bytes from the local kernel <buffer> to the open file
    809  * descriptor <file_xp>, taken into account the offset defined in <file_xp>.
    810  ******************************************************************************************
    811  * @ file_xp   : extended pointer on the remote open file descriptor.
    812  * @ buffer    : local pointer on source kernel buffer.
    813  * @ size      : requested number of bytes to be written from offset.
    814667 * @ returns number of bytes actually transfered / -1 if error.
    815668 *****************************************************************************************/
    816 uint32_t vfs_write( xptr_t   file_xp,
    817                     void   * buffer,
    818                     uint32_t size );
     669error_t vfs_move( bool_t   to_buffer,
     670                  xptr_t   file_xp,
     671                  void   * buffer,
     672                  uint32_t size );
    819673
    820674/******************************************************************************************
     
    837691
    838692/******************************************************************************************
    839  * This function close an open file descriptor.                             
     693 * This function close an open file descriptor:
     694 * 1) All entries in fd_array copies are directly cancelled by the calling thread,
     695 *    using remote accesses.
     696 * 2) The memory allocated to file descriptor in cluster containing the inode is released.
     697 *    It requires a RPC if cluster containing the file descriptor is remote.
    840698 ******************************************************************************************
    841699 * @ file_xp     : extended pointer on the file descriptor.
    842  * @ refcount    : number of references after close.
    843  * @ return 0 if success / return -1 if error
    844  *****************************************************************************************/
    845 error_t vfs_close( xptr_t     file_xp,
    846                    uint32_t * refcount );
    847 
    848 /******************************************************************************************
    849  * This function remove from the file system a directory entry identified by its pathname.
    850  * The pathname can be relative to current directory or absolute.
    851  ******************************************************************************************
    852  * @ cwd_xp   : extended pointer on the current directory file descriptor.
     700 * @ file_id     : file descriptor index in fd_array.
     701 * @ returns 0 if success / -1 if error.
     702 *****************************************************************************************/
     703error_t vfs_close( xptr_t    file_xp,
     704                   uint32_t  file_id );
     705
     706/******************************************************************************************
     707 * This function remove from the file system a directory entry identified by the
     708 * <cwd_xp> & <path> arguments.
     709 ******************************************************************************************
     710 * @ cwd_xp   : extended pointer on the current working directory file descriptor.
    853711 * @ path     : pathname (absolute or relative to current directory).
     712 * @ returns 0 if success / -1 if error.
    854713 *****************************************************************************************/
    855714error_t vfs_unlink( xptr_t   cwd_xp,
     
    857716
    858717/******************************************************************************************
    859  * This function returns in the <ustat> structure various informations on the file TODO
     718 * This function returns, in the structure pointed by the <k_stat> kernel pointer,
     719 * various informations on the file descriptor identified by the <file_xp> argument.
     720 * TODO not implemented yet...
     721 ******************************************************************************************
     722 * @ file_xp    : extended pointer on the file descriptor of the searched directory .
     723 * @ k_dirent   : local pointer on the dirent_t structure in kernel space.
     724 * @ returns 0 if success / -1 if error.
    860725 *****************************************************************************************/
    861726error_t vfs_stat( xptr_t       file_xp,
    862                   vfs_stat_t * ustat );
    863 
    864 
    865 
    866 
    867 /*****************************************************************************************/
    868 /************************ Directory related functions ************************************/
    869 /*****************************************************************************************/
    870 
    871 /******************************************************************************************
    872  * This function TODO                                                         
    873  *****************************************************************************************/
    874 error_t vfs_opendir( xptr_t      cwd_xp,
    875                      char      * path,
    876                      uint32_t    flags,
    877                      xptr_t      file_xp );
    878 
    879 /******************************************************************************************
    880  * This function TODO                                                         
    881  *    fat32_readdir need cleaning
    882  *****************************************************************************************/
    883 error_t vfs_readdir( xptr_t            file_xp,
    884                      char            * path );
    885 
    886 /******************************************************************************************
    887  * This function TODO                                                         
    888  *****************************************************************************************/
    889 error_t vfs_mkdir( xptr_t            file_xp,
    890                    char            * path,
    891                    uint32_t          mode );
    892 
    893 /******************************************************************************************
    894  * This function remove a directory from the file system.
    895  *****************************************************************************************/
    896 error_t vfs_rmdir( xptr_t            file_xp,
    897                    char            * path );
    898 
    899 /******************************************************************************************
    900  * This function TODO                                                         
    901  *****************************************************************************************/
    902 error_t vfs_chdir( char            * pathname,
    903                    xptr_t            cwd_xp );
    904 
    905 /******************************************************************************************
    906  * This function TODO                                                         
    907  *****************************************************************************************/
    908 error_t vfs_chmod( char            * pathname,
    909                    vfs_file_t      * cwd,
    910                    uint32_t          mode );
    911 
    912 /******************************************************************************************
    913  * This function TODO                                                         
    914  *****************************************************************************************/
    915 error_t vfs_closedir( xptr_t       file_xp,
    916                       uint32_t   * refcount );
    917 
    918 
    919 
    920 
    921 /*****************************************************************************************/
    922 /*******************  Pipe related functions *********************************************/
    923 /*****************************************************************************************/
    924 
    925 /******************************************************************************************
    926  * This function TODO ???                                                         
    927  *****************************************************************************************/
    928 error_t vfs_pipe( xptr_t pipefd[2] );
    929 
    930 /******************************************************************************************
    931  * This function TODO                                                         
    932  *****************************************************************************************/
    933 error_t vfs_mkfifo( xptr_t            cwd_xp,
    934                     char            * path,
    935                     uint32_t          mode );
    936 
    937 
    938 
     727                  vfs_stat_t * k_stat );
     728
     729/******************************************************************************************
     730 * This function returns, in the structure pointed by the <k_dirent> kernel pointer,
     731 * various infos on the directory entry currently pointed by the <file_xp> file descriptor.
     732 * TODO not implemented yet...
     733 ******************************************************************************************
     734 * @ file_xp    : extended pointer on the file descriptor of the searched directory .
     735 * @ k_dirent   : local pointer on the dirent_t structure in kernel space.
     736 * @ returns 0 if success / -1 if error.
     737 *****************************************************************************************/
     738error_t vfs_readdir( xptr_t         file_xp,
     739                     vfs_dirent_t * k_dirent );
     740
     741/******************************************************************************************
     742 * This function  creates a new inode and associated dentry  for the directory defined
     743 * by the <cwd_xp> & <path> arguments.
     744 * TODO not implemented yet...
     745 ******************************************************************************************
     746 * @ cwd_xp   : extended pointer on the current working directory file descriptor.
     747 * @ path     : pathname (absolute or relative to current directory).                     
     748 * @ mode     : access rights (as defined by chmod)
     749 * @ returns 0 if success / -1 if error.
     750 *****************************************************************************************/
     751error_t vfs_mkdir( xptr_t     cwd_xp,
     752                   char     * path,
     753                   uint32_t   mode );
     754
     755/******************************************************************************************
     756 * This function remove a directory identified by the <cwd_xp / path> arguments
     757 * from the file system.
     758 * TODO not implemented yet...
     759 ******************************************************************************************
     760 * @ cwd_xp   : extended pointer on the current working directory file descriptor.
     761 * @ path     : pathname (absolute or relative to current directory).                     
     762 * @ returns 0 if success / -1 if error.
     763 *****************************************************************************************/
     764error_t vfs_rmdir( xptr_t   cwd_xp,
     765                   char   * path );
     766
     767/******************************************************************************************
     768 * This function makes the directory identified by <cwd_xp / path> arguments to become
     769 * the working directory for the calling process.
     770 ******************************************************************************************
     771 * @ cwd_xp      : extended pointer on current directory file descriptor (relative path).
     772 * @ path        : file pathname (absolute or relative to current directory).
     773 * return 0 if success / -1 if error.
     774 *****************************************************************************************/
     775error_t vfs_chdir( xptr_t   cwd_xp,
     776                   char   * path );
     777
     778/******************************************************************************************
     779 * This function change the access rigths for the file identified by the <cwd_xp / path>
     780 * arguments. The new access rights are defined by the <mode> argument value.
     781 ******************************************************************************************
     782 * @ cwd_xp      : extended pointer on current directory file descriptor (relative path).
     783 * @ path        : file pathname (absolute or relative to current directory).
     784 * @ mode        : access rights new value.
     785 * return 0 if success / -1 if error.
     786 *****************************************************************************************/
     787error_t vfs_chmod( xptr_t        cwd_xp,
     788                   char        * path,
     789                   uint32_t      mode );
     790
     791/******************************************************************************************
     792 * This function creates a named FIFO file.
     793 * TODO not implemented yet                                                         
     794 ******************************************************************************************
     795 * @ path        : FIFO pathname (absolute or relative to current directory).
     796 * @ cwd_xp      : extended pointer on the current working directory file descriptor.
     797 * @ mode        : access rights new value.
     798 *****************************************************************************************/
     799error_t vfs_mkfifo( xptr_t       cwd_xp,
     800                    char       * path,
     801                    uint32_t     mode );
     802
     803
     804/*****************************************************************************************/
     805/****************** Mapper access API ****************************************************/
     806/*****************************************************************************************/
     807
     808/******************************************************************************************
     809 * This function makes an I/O operation to move one page from VFS to a given mapper,
     810 * in case of MISS on the mapper cache.
     811 * Depending on the file system type, it calls the proper, FS specific function.
     812 * It must be executed by a thread running in the cluster containing the mapper.
     813 * The mapper pointer is obtained from the page descriptor.
     814 * It takes the mapper lock before launching the IO operation.
     815 ******************************************************************************************
     816 * @ page   : local pointer on the page descriptor.
     817 * @ returns 0 if success / return EINVAL if it cannot access the external device.
     818 *****************************************************************************************/
     819error_t vfs_move_page_to_mapper( struct page_s * page );
     820
     821/******************************************************************************************
     822 * This function makes an I/0 operation to move one page from a given mapper to VFS,
     823 * when a dirty page in the mapper cache must be updated in the File System.
     824 * Depending on the file system type, it calls the proper, FS specific function.
     825 * It must be executed by a thread running in the cluster containing the mapper.
     826 * The mapper pointer is obtained from the page descriptor.
     827 * It takes the mapper lock before launching the IO operation.
     828 * It does nothing if the page is not dirty. If the page is dirty, it clear the page
     829 * dirty bit, and remove the page from the PPM dirty list.
     830 ******************************************************************************************
     831 * @ page   : local pointer on the page descriptor.
     832 * @ returns 0 if success / return EINVAL if it cannot access the external device.
     833 *****************************************************************************************/
     834error_t vfs_move_page_from_mapper( struct page_s * page );       
     835
     836
     837
     838
     839
     840
     841///////////////////////////////////////////////////////////////////////////////////////////
     842// These typedef define the FS specific operations that must be implemented by any
     843// specific file system to be supported by the ALMOS_MKH VFS.
     844// These typedef are not actually used, and are only defined for documentation
     845///////////////////////////////////////////////////////////////////////////////////////////
     846
     847typedef error_t (fs_init_t)          ( xptr_t vfs_root_xp );
     848
     849typedef error_t (fs_inode_extend_t)  ( struct vfs_inode_s * inode,
     850                                       void               * extend );
     851 
     852typedef void    (fs_inode_release_t) ( struct vfs_inode_s * inode );
     853
     854typedef error_t (fs_write_page_t)    ( struct page_s * page );
     855
     856typedef error_t (fs_read_page_t)     ( struct page_s * page );
     857
     858
     859
     860
     861
     862
     863
     864
     865/* deprecated [AG]
     866
     867typedef error_t (lookup_inode_t)  ( vfs_inode_t  * parent ,
     868                                    vfs_dentry_t * dentry );
     869
     870typedef error_t (write_inode_t)   ( vfs_inode_t  * inode );
     871
     872typedef error_t (release_inode_t) ( vfs_inode_t  * inode );
     873
     874typedef error_t (unlink_inode_t)  ( vfs_inode_t  * parent,
     875                                    vfs_dentry_t * dentry,
     876                                    uint32_t       flags );
     877
     878typedef error_t (stat_inode_t)    ( vfs_inode_t  * inode );
     879
     880typedef error_t (trunc_inode_t)   ( vfs_inode_t  * inode );
     881
     882typedef error_t (delete_inode_t)  ( vfs_inode_t  * inode );
     883
     884typedef struct vfs_inode_op_s
     885{
     886        init_inode_t    * init;   
     887        create_inode_t  * create; 
     888        lookup_inode_t  * lookup; 
     889        write_inode_t   * write;
     890        release_inode_t * release;
     891        unlink_inode_t  * unlink;
     892        delete_inode_t  * delete;
     893        stat_inode_t    * stat;
     894        trunc_inode_t   * trunc;    // change the size of a file
     895}
     896vfs_inode_op_t;
     897
     898 ******************************************************************************************
     899 * These typedef define the set of FS specific operations on a VFS DENTRY descriptor.
     900 * They must be implemented by any specific file system to be supported by ALMOS_MKH.
     901 * This code is not actually used, and is only defined for documentation
     902 ******************************************************************************************
     903
     904
     905typedef error_t (vfs_compare_dentry_t) ( char * first , char * second );
     906
     907typedef struct vfs_dentry_op_s
     908{
     909        vfs_compare_dentry_t * compare;
     910}
     911vfs_dentry_op_t;
     912
     913
     914 ******************************************************************************************
     915 * These typedef define the set of FS specific operations on FILE descriptors
     916 * They must be implemented by any specific file system to be supported by ALMOS_MKH.
     917 * This code is not actually used, and is only defined for documentation
     918 ******************************************************************************************
     919
     920
     921typedef error_t (open_file_t   ) ( vfs_file_t * file,
     922                                   void       * extend );
     923
     924typedef error_t (read_file_t   ) ( vfs_file_t * file,
     925                                   char       * buffer,
     926                                   uint32_t     count );
     927
     928typedef error_t (write_file_t  ) ( vfs_file_t * file,
     929                                   char       * buffer,
     930                                   uint32_t     count );
     931
     932typedef error_t (lseek_file_t  ) ( vfs_file_t * file );
     933
     934typedef error_t (close_file_t  ) ( vfs_file_t * file );
     935
     936typedef error_t (release_file_t) ( vfs_file_t * file );
     937
     938typedef error_t (read_dir_t    ) ( vfs_file_t * file );
     939
     940typedef error_t (mmap_file_t   ) ( vfs_file_t    * file ,
     941                                   struct vseg_s * vseg );
     942
     943typedef error_t (munmap_file_t ) ( vfs_file_t    * file,
     944                                   struct vseg_s * vseg );
     945
     946typedef struct vfs_file_op_s
     947{
     948        open_file_t    * open;
     949        read_file_t    * read;
     950        write_file_t   * write;
     951        lseek_file_t   * lseek;
     952        read_dir_t     * readdir;
     953        close_file_t   * close;
     954        release_file_t * release;
     955        mmap_file_t    * mmap;
     956        munmap_file_t  * munmap;
     957}
     958vfs_file_op_t;
     959
     960*/
    939961
    940962#endif  /* _VFS_H_ */
Note: See TracChangeset for help on using the changeset viewer.