Changeset 459 for trunk


Ignore:
Timestamp:
Aug 13, 2018, 1:43:20 PM (6 years ago)
Author:
alain
Message:

Introduce the math library, to support the floating point
data used by the multi-thread fft application.
Fix several bugs regarding the FPU context save/restore.
Introduce support for the %f format in printf.

Location:
trunk
Files:
28 edited

Legend:

Unmodified
Added
Removed
  • trunk/Makefile

    r457 r459  
    4242                user/pgdc/build/pgcd.elf           \
    4343                user/idbg/build/idbg.elf           \
    44                 user/sort/build/sort.elf
     44                user/sort/build/sort.elf           \
     45        user/fft/build/fft.elf
    4546
    4647# Virtual disk path
     
    6566         user/idbg/build/idbg.elf          \
    6667         user/sort/build/sort.elf          \
     68         user/fft/build/fft.elf           \
    6769         list
    6870
     
    9799        $(MAKE) -C user/pgcd clean
    98100        $(MAKE) -C user/idbg clean
     101        $(MAKE) -C user/fft clean
    99102        $(MAKE) -C $(HAL_ARCH) clean
    100103
     
    138141        $(MAKE) -C $(LIBPTHREAD_PATH) headers
    139142        $(MAKE) -C $(LIBSEMAPHORE_PATH) headers
     143        $(MAKE) -C $(LIBMATH_PATH) headers
    140144        $(MAKE) -C $(LIBC_PATH)
    141145        $(MAKE) -C $(LIBALMOSMKH_PATH)
    142146        $(MAKE) -C $(LIBPTHREAD_PATH)
    143147        $(MAKE) -C $(LIBSEMAPHORE_PATH)
     148        $(MAKE) -C $(LIBMATH_PATH)
    144149
    145150#####################################################################
     
    177182        $(MAKE) -C user/sort
    178183        mcopy -o -i $(DISK_IMAGE) $@ ::/bin/user
     184user/fft/build/fft.elf: build_libs
     185        $(MAKE) -C user/fft
     186        mcopy -o -i $(DISK_IMAGE) $@ ::/bin/user
  • trunk/hal/generic/hal_user.h

    r457 r459  
    22 * hal_user.h - User-side, architecture specific API definition.
    33 *
    4  * Author      Alain Greiner (2016,2017)
     4 * Author      Alain Greiner (2016,2017,2018)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
  • trunk/hal/tsar_mips32/core/hal_context.c

    r457 r459  
    186186    // get remote child thread cluster and local pointer
    187187    cxy_t      child_cxy = GET_CXY( child_xp );
    188     thread_t * child_ptr = (thread_t *)GET_PTR( child_xp );
     188    thread_t * child_ptr = GET_PTR( child_xp );
    189189
    190190    // get remote child cpu_context local pointer
     
    257257    // get thread cluster and local pointer
    258258    cxy_t      cxy = GET_CXY( thread_xp );
    259     thread_t * ptr = (thread_t *)GET_PTR( thread_xp );
     259    thread_t * ptr = GET_PTR( thread_xp );
    260260
    261261    // get context pointer
     
    358358{
    359359    // allocate a local FPU context in kernel stack
    360     hal_fpu_context_t  context;
     360    hal_fpu_context_t  src_context;
    361361
    362362    // get remote child cluster and local pointer
    363363    cxy_t      thread_cxy = GET_CXY( thread_xp );
    364     thread_t * thread_ptr = (thread_t *)GET_PTR( thread_xp );
     364    thread_t * thread_ptr = GET_PTR( thread_xp );
    365365
    366366    asm volatile(
     
    399399    "swc1    $f31,  31*4(%0)  \n"   
    400400    ".set reorder             \n"
    401     : : "r"(&context) );
     401    : : "r"(&src_context) );
     402
     403    // get local pointer on target thread FPU context
     404    void * dst_context = hal_remote_lpt( XPTR( thread_cxy , &thread_ptr->fpu_context ) );
    402405
    403406    // copy local context to remote child context)
    404     hal_remote_memcpy( XPTR( thread_cxy , &thread_ptr->fpu_context ),
    405                        XPTR( local_cxy  , &context ) ,
     407    hal_remote_memcpy( XPTR( thread_cxy , dst_context ),
     408                       XPTR( local_cxy  , &src_context ),
    406409                       sizeof( hal_fpu_context_t ) );
    407410
     
    411414void hal_fpu_context_restore( thread_t * thread )
    412415{
     416    // get pointer on FPU context and cast to uint32_t
    413417    uint32_t ctx = (uint32_t)thread->fpu_context;
    414418
  • trunk/hal/tsar_mips32/core/hal_exception.c

    r457 r459  
    311311        {
    312312            assert( false , __FUNCTION__ ,
    313             "thread %x in process %x / core[%x,%d] / epc %x / vaddr %x / cycle %d\n",
    314             this->trdid, this->process->pid, local_cxy, this->core->lid,
    315             excPC, bad_vaddr, (uint32_t)hal_get_cycles() );
     313            "thread %x in process %x / epc %x / badvaddr %x / cycle %d\n",
     314            this->trdid, this->process->pid, excPC, bad_vaddr, (uint32_t)hal_get_cycles() );
    316315
    317316            return EXCP_KERNEL_PANIC;
     
    428427            case XCODE_CPU:    // can be non fatal
    429428        {
    430             if( ((uzone[UZ_CR] >> 28) & 0x3) == 1 )     // unavailable FPU
    431             {
    432                 error = hal_fpu_exception( this );
     429            if( ((uzone[UZ_CR] >> 28) & 0x3) == 1 ) // FPU
     430            {
     431                error = hal_fpu_exception( this );              // FPU exception
    433432            }
    434433            else
  • trunk/hal/tsar_mips32/core/hal_shared_types.h

    r452 r459  
    11/*
    2  * hal_kernel_types.h - Data types shared by kernel & libraries for TSAR-MIPS32.
     2 * hal_shared_types.h - Data types shared by kernel & libraries for TSAR-MIPS32.
    33 *
    44 * Author  Alain Greiner (2016)
     
    2626
    2727/*******************i***************************************************************
    28  * This file defines - for the TSAR_MIPS32 architecture - the <reg_t> type, used
    29  * by the hal_user_syscall() function, called by several user-level libraries
    30  * to pass syscall arguments to the  kernel, and used by the do_syscall() function,
    31  * called by the kernel syscall handler, to analyse arguments.
    32  * It is also used by various kernel functions such as the hal_*_irq() functions
    33  * to save/restore the SR register value.
     28 * This file defines - for the TSAR_MIPS32 architecture - types that can be used
     29 * by both the kernel and the user applications.
     30 *
     31 * - the <reg_t> type, is used by the hal_user_syscall() function, called by
     32 *   several user-level libraries to pass syscall arguments to the  kernel,
     33 *   and used by the do_syscall() kernel function, to analyse arguments.
     34 *   It is also used by the hal_*_irq() kernel functions to save/restore
     35 *   the SR register value.
    3436 **********************************************************************************/
    3537
     
    4042typedef unsigned long int     reg_t;    // core register
    4143
    42 #endif  /* HAL_TYPES_H_ */
     44#endif
  • trunk/hal/tsar_mips32/core/hal_special.c

    r457 r459  
    113113void hal_fpu_enable()
    114114{
     115    // set CU1 bit (FPU enable) in c0_sr
    115116        asm volatile
    116117        ( ".set noat                         \n"
     
    120121      "mtc0   $27,    $12                \n"
    121122      ".set at                           \n" );
     123
     124    // set CU1 bit in calling thread UZONE
     125    uint32_t * uzone = CURRENT_THREAD->uzone_current;
     126    uzone[34] |= 0x20000000;
    122127}
    123128
     
    125130void hal_fpu_disable()
    126131{
     132    // reset CU1 bit (FPU enable) in c0_sr
    127133        asm volatile
    128134        ( ".set noat                         \n"
     
    133139      "mtc0   $27,    $12                \n"
    134140          ".set at                           \n");
     141
     142    // reset CU1 bit in calling thread UZONE
     143    uint32_t * uzone = CURRENT_THREAD->uzone_current;
     144    uzone[34] &= 0xDFFFFFFF;
    135145}
    136146
  • trunk/kernel/fs/vfs.c

    r457 r459  
    247247}  // end vfs_inode_create() 
    248248
    249 /////////////////////////////////////////////
    250 void vfs_inode_destroy( vfs_inode_t * inode )
    251 {
    252     if( inode->refcount )
    253     {
    254         assert( false , __FUNCTION__ , "inode refcount non zero\n" );
    255     }       
     249////////////////////////////////////////////////
     250error_t vfs_inode_destroy( vfs_inode_t * inode )
     251{
     252    assert( (inode->refcount == 0), __FUNCTION__ , "inode refcount non zero\n" );
    256253
    257254    // release memory allocated for mapper
     
    264261        kmem_free( &req );
    265262
     263    return 0;
     264
    266265}  // end vfs_inode_destroy()
    267266
     
    315314    return error;
    316315
    317 } // end vfs_load_inode()
     316} // end vfs_inode_load()
    318317
    319318////////////////////////////////////////////
     
    432431    vfs_dentry_t   * dentry;     // dentry descriptor (to be allocated)
    433432        kmem_req_t       req;        // request to kernel memory allocator
     433    error_t          error;
    434434
    435435#if DEBUG_VFS_DENTRY_CREATE
    436436uint32_t cycle = (uint32_t)hal_get_cycles();
    437437if( DEBUG_VFS_DENTRY_CREATE < cycle )
    438 printk("\n[DBG] %s : thread %x enter for <%s> / parent_inode %x / cycle %d\n",
    439 __FUNCTION__, CURRENT_THREAD , name , parent , cycle );
     438printk("\n[DBG] %s : thread %x in process %x enter for <%s> / parent_inode %x / cycle %d\n",
     439__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, name, parent, cycle );
    440440#endif
    441441
     
    444444    else if( fs_type == FS_TYPE_RAMFS ) ctx = &fs_context[FS_TYPE_RAMFS];
    445445    else if( fs_type == FS_TYPE_DEVFS ) ctx = &fs_context[FS_TYPE_DEVFS];
    446     else
     446    else 
    447447    {
    448448        ctx = NULL;
    449         assert( false , __FUNCTION__ , "undefined file system type\n" );
     449        return EINVAL;
    450450    }
    451451
     
    453453    uint32_t length = strlen( name );
    454454
    455     if( length >= CONFIG_VFS_MAX_NAME_LENGTH )
    456     {
    457 
    458 #if DEBUG_SYSCALLS_ERROR
    459 printk("\n[ERROR] in %s : name <name> too long\n", __FUNCTION__ , name );
    460 #endif
    461         return EINVAL;
    462     }
     455    if( length >= CONFIG_VFS_MAX_NAME_LENGTH ) return EINVAL;
    463456
    464457    // allocate memory for dentry descriptor
     
    468461        dentry     = (vfs_dentry_t *)kmem_alloc( &req );
    469462
    470     if( dentry == NULL )
    471     {
    472 
    473 #if DEBUG_SYSCALLS_ERROR
    474 printk("\n[ERROR] in %s : cannot allocate dentry\n", __FUNCTION__ );
    475 #endif
    476         return ENOMEM;
    477     }
     463    if( dentry == NULL ) return ENOMEM;
    478464
    479465    // initialize dentry descriptor
     
    491477
    492478    // register dentry in hash table rooted in parent inode
    493     xhtab_insert( XPTR( local_cxy , &parent->children ),
    494                   name,
    495                   XPTR( local_cxy , &dentry->list ) );
     479    error = xhtab_insert( XPTR( local_cxy , &parent->children ),
     480                          name,
     481                          XPTR( local_cxy , &dentry->list ) );
     482
     483    if( error ) return EINVAL;
    496484
    497485#if( DEBUG_VFS_DENTRY_CREATE & 1 )
     
    507495cycle = (uint32_t)hal_get_cycles();
    508496if( DEBUG_VFS_DENTRY_CREATE < cycle )
    509 printk("\n[DBG] %s : thread %x exit for <%s> / dentry %x / cycle %d\n",
    510 __FUNCTION__, CURRENT_THREAD , name , dentry , cycle );
     497printk("\n[DBG] %s : thread %x in process %x exit for <%s> / dentry %x / cycle %d\n",
     498__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, name, dentry, cycle );
    511499#endif
    512500
     
    515503}  // end vfs_dentry_create()
    516504
    517 ////////////////////////////////////////////////
    518 void vfs_dentry_destroy( vfs_dentry_t * dentry )
    519 {
    520     if( dentry->refcount )
    521     {
    522         assert( false , __FUNCTION__ , "dentry refcount non zero\n" );
    523     }       
    524 
     505///////////////////////////////////////////////////
     506error_t vfs_dentry_destroy( vfs_dentry_t * dentry )
     507{
     508    error_t error;
     509
     510    assert( (dentry->refcount == 0) , __FUNCTION__ , "dentry refcount non zero\n" );
     511
     512    // get pointer on parent inode
     513    vfs_inode_t * parent = dentry->parent;
     514
     515    // remove this dentry from parent inode htab
     516    error = xhtab_remove( XPTR( local_cxy , &parent->children ),
     517                          dentry->name,
     518                          XPTR( local_cxy , &dentry->list ) );
     519
     520    if( error ) return EINVAL;     
     521
     522    // release memory allocated to dentry
    525523        kmem_req_t req;
    526524        req.ptr   = dentry;
    527525        req.type  = KMEM_VFS_DENTRY;
    528526        kmem_free( &req );
     527
     528    return 0;
    529529}
    530530
     
    564564
    565565    *file_xp = XPTR( local_cxy , file );
     566
     567#if DEBUG_VFS_OPEN
     568uint32_t cycle = (uint32_t)hal_get_cycles();
     569if( DEBUG_VFS_OPEN < cycle )
     570printk("\n[DBG] %s : thread %x in process %x created file %x in cluster %x / cycle %d\n",
     571__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, file, local_cxy, cycle );
     572#endif
     573
    566574    return 0;
    567575
     
    581589        kmem_free( &req );
    582590
     591#if DEBUG_VFS_CLOSE
     592uint32_t cycle = (uint32_t)hal_get_cycles();
     593if( DEBUG_VFS_CLOSE < cycle )
     594printk("\n[DBG] %s : thread %x in process %x deleted file %x in cluster %x / cycle %d\n",
     595__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, file, local_cxy, cycle );
     596#endif
     597
    583598}  // end vfs_file_destroy()
    584599
     
    589604    // get file cluster and local pointer
    590605    cxy_t        file_cxy = GET_CXY( file_xp );
    591     vfs_file_t * file_ptr = (vfs_file_t *)GET_PTR( file_xp );
     606    vfs_file_t * file_ptr = GET_PTR( file_xp );
    592607
    593608    // atomically increment count
     
    600615    // get file cluster and local pointer
    601616    cxy_t        file_cxy = GET_CXY( file_xp );
    602     vfs_file_t * file_ptr = (vfs_file_t *)GET_PTR( file_xp );
     617    vfs_file_t * file_ptr = GET_PTR( file_xp );
    603618
    604619    // atomically decrement count
     
    630645uint32_t cycle = (uint32_t)hal_get_cycles();
    631646if( DEBUG_VFS_OPEN < cycle )
    632 printk("\n[DBG] %s :  thread %x enter for <%s> / cycle %d\n",
    633 __FUNCTION__, CURRENT_THREAD, path, cycle );
     647printk("\n[DBG] %s :  thread %x in process %x enter for <%s> / cycle %d\n",
     648__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, path, cycle );
    634649#endif
    635650
     
    677692cycle = (uint32_t)hal_get_cycles();
    678693if( DEBUG_VFS_OPEN < cycle )
    679 printk("\n[DBG] %s : thread %x exit for <%s> / file %x in cluster %x / cycle %d\n",
    680 __FUNCTION__, CURRENT_THREAD, path, GET_PTR(file_xp), GET_CXY(file_xp), cycle );
     694printk("\n[DBG] %s :  thread %x in process %x exit for <%s> / fdid %d / cluster %x / cycle %d\n",
     695__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, path,
     696file_id, GET_CXY( file_xp ), cycle );
    681697#endif
    682698
     
    868884                   uint32_t file_id )
    869885{
     886    cluster_t  * cluster;          // local pointer on local cluster
     887    cxy_t        file_cxy;         // cluster containing the file descriptor.
     888    vfs_file_t * file_ptr;         // local ponter on file descriptor
     889    cxy_t        owner_cxy;        // process owner cluster
     890    lpid_t       lpid;             // process local index
     891    xptr_t       root_xp;          // root of list of process copies
     892    xptr_t       lock_xp;          // lock protecting the list of copies
     893    xptr_t       iter_xp;          // iterator on list of process copies
     894    xptr_t       process_xp;       // extended pointer on one process copy
     895    cxy_t        process_cxy;      // process copy cluster
     896    process_t  * process_ptr;      // process copy local pointer
     897
    870898    assert( (file_xp != XPTR_NULL) , __FUNCTION__ , "file_xp == XPTR_NULL" );
    871899
     
    875903    process_t * process = this->process;
    876904
    877     // get cluster and local pointer on remote file descriptor
    878     cxy_t        file_cxy = GET_CXY( file_xp );
    879     vfs_file_t * file_ptr = (vfs_file_t *)GET_PTR( file_xp );
     905#if DEBUG_VFS_CLOSE
     906uint32_t cycle = (uint32_t)hal_get_cycles();
     907if( DEBUG_VFS_CLOSE < cycle )
     908printk("\n[DBG] %s : thread %x in process %x enter / fdid %d / cycle %d\n",
     909__FUNCTION__, this->trdid, process->pid, file_id, cycle );
     910#endif
    880911
    881912    // get local pointer on local cluster manager
    882     cluster_t * cluster = LOCAL_CLUSTER;
     913    cluster = LOCAL_CLUSTER;
    883914
    884915    // get owner process cluster and lpid
    885     cxy_t   owner_cxy  = CXY_FROM_PID( process->pid );
    886     lpid_t  lpid       = LPID_FROM_PID( process->pid );
     916    owner_cxy  = CXY_FROM_PID( process->pid );
     917    lpid       = LPID_FROM_PID( process->pid );
    887918
    888919    // get extended pointers on copies root and lock
    889     xptr_t root_xp = XPTR( owner_cxy , &cluster->pmgr.copies_root[lpid] );
    890     xptr_t lock_xp = XPTR( owner_cxy , &cluster->pmgr.copies_lock[lpid] );
    891 
    892     // take the lock protecting the copies
     920    root_xp = XPTR( owner_cxy , &cluster->pmgr.copies_root[lpid] );
     921    lock_xp = XPTR( owner_cxy , &cluster->pmgr.copies_lock[lpid] );
     922
     923    // 1) loop on the process descriptor copies to reset all fd_array[file_id] entries
     924
     925    // take the lock protecting the list of copies
    893926    remote_spinlock_lock( lock_xp );
    894927
    895     // 1) loop on the process descriptor copies to cancel all fd_array[file_id] entries
    896     xptr_t  iter_xp;
    897928    XLIST_FOREACH( root_xp , iter_xp )
    898929    {
    899         xptr_t      process_xp  = XLIST_ELEMENT( iter_xp , process_t , copies_list );
    900         cxy_t       process_cxy = GET_CXY( process_xp );
    901         process_t * process_ptr = (process_t *)GET_PTR( process_xp );
    902 
    903         xptr_t lock_xp  = XPTR( process_cxy , &process_ptr->fd_array.lock );
    904         xptr_t entry_xp = XPTR( process_cxy , &process_ptr->fd_array.array[file_id] );
    905 
    906         // lock is required for atomic write of a 64 bits word
    907         remote_rwlock_wr_lock( lock_xp );
     930        process_xp  = XLIST_ELEMENT( iter_xp , process_t , copies_list );
     931        process_cxy = GET_CXY( process_xp );
     932        process_ptr = GET_PTR( process_xp );
     933
     934#if (DEBUG_VFS_CLOSE & 1 )
     935if( DEBUG_VFS_CLOSE < cycle )
     936printk("\n[DBG] %s : reset fd_array[%d] for process %x in cluster %x\n",
     937__FUNCTION__, file_id, process_ptr, process_cxy );
     938#endif
     939
     940// fd_array lock is required for atomic write of a 64 bits word
     941// xptr_t fd_array_lock_xp = XPTR( process_cxy , &process_ptr->fd_array.lock );
     942
     943        xptr_t entry_xp         = XPTR( process_cxy , &process_ptr->fd_array.array[file_id] );
     944
     945// remote_rwlock_wr_lock( fd_array_lock_xp );
     946
    908947        hal_remote_swd( entry_xp , XPTR_NULL );
    909         remote_rwlock_wr_unlock( lock_xp );
     948       
     949// remote_rwlock_wr_unlock( fd_array_lock_xp );
     950
     951        vfs_file_count_down( file_xp );
    910952
    911953        hal_fence();
    912954    }   
    913955
     956    // release the lock protecting the list of copies
     957    remote_spinlock_unlock( lock_xp );
     958
     959#if (DEBUG_VFS_CLOSE & 1)
     960if( DEBUG_VFS_CLOSE < cycle )
     961printk("\n[DBG] %s : thread %x in process %x reset all fd-array copies\n",
     962__FUNCTION__, this->trdid, process->pid );
     963#endif
     964
    914965    // 2) release memory allocated to file descriptor in remote cluster
     966
     967    // get cluster and local pointer on remote file descriptor
     968    file_cxy = GET_CXY( file_xp );
     969    file_ptr = GET_PTR( file_xp );
     970
    915971    if( file_cxy == local_cxy )             // file cluster is local
    916972    {
     
    921977        rpc_vfs_file_destroy_client( file_cxy , file_ptr );
    922978    }
     979
     980#if DEBUG_VFS_CLOSE
     981cycle = (uint32_t)hal_get_cycles();
     982if( DEBUG_VFS_CLOSE < cycle )
     983printk("\n[DBG] %s : thread %x in process %x exit / fdid %d closed / cycle %d\n",
     984__FUNCTION__, this->trdid, process->pid, file_id, cycle );
     985#endif
    923986
    924987    return 0;
     
    13511414    cxy_t              child_cxy;    // cluster for child inode
    13521415    vfs_inode_t      * child_ptr;    // local pointer on child inode 
    1353     vfs_inode_type_t   child_type;   // child inode type
    13541416    vfs_fs_type_t      fs_type;      // File system type
    13551417    vfs_ctx_t        * ctx_ptr;      // local pointer on FS context
     
    13581420    bool_t             last;         // true when the name is the last in path
    13591421    bool_t             found;        // true when a child has been found
     1422    bool_t             dir;          // searched inode is a directory
     1423    bool_t             create;       // searched inode must be created if not found
     1424    bool_t             excl;         // searched inode must not exist
    13601425    thread_t         * this;         // pointer on calling thread descriptor
    13611426    process_t        * process;      // pointer on calling process descriptor
     
    13681433uint32_t cycle = (uint32_t)hal_get_cycles();
    13691434if( DEBUG_VFS_LOOKUP < cycle )
    1370 printk("\n[DBG] %s : thread %x enter for <%s> / cycle %d\n",
    1371 __FUNCTION__, CURRENT_THREAD, pathname, cycle );
    1372 #endif
    1373 
     1435printk("\n[DBG] %s : thread %x in process %x enter for <%s> / cycle %d\n",
     1436__FUNCTION__, this->trdid, process->pid, pathname, cycle );
     1437#endif
     1438
     1439    // compute lookup flags
     1440    dir    = mode & VFS_LOOKUP_DIR;
     1441    create = mode & VFS_LOOKUP_CREATE;
     1442    excl   = mode & VFS_LOOKUP_EXCL;
     1443   
    13741444    // get extended pointer on first inode to search
    13751445    if( pathname[0] == '/' ) parent_xp = process->vfs_root_xp;
     
    13861456
    13871457    // sequencially loop on nodes in pathname
    1388     // load from device if one node not found in inode tree
     1458    // load from device if one node in path not found in inode tree
    13891459    // exit loop when last name found (i.e. last == true)
    13901460    do
     
    13951465#if (DEBUG_VFS_LOOKUP & 1)
    13961466if( DEBUG_VFS_LOOKUP < cycle )
    1397 printk("\n[DBG] %s : look for <%s> / last = %d\n", __FUNCTION__ , name , last );
     1467printk("\n[DBG] %s : look for <%s> / last = %d\n",
     1468__FUNCTION__ , name , last );
    13981469#endif
    13991470
     
    14031474                               &child_xp );
    14041475
    1405         // if a child inode is not found in the inode tree:
    1406         // - we create the missing inode/dentry couple in the inode tree,
    1407         // - we scan the parent mapper to complete the child inode (type and extension),
    1408         // - we return an error if child not found on device.
    1409         // - if the missing child is a directory, we load the child mapper from device
    1410 
    1411         // for the last name, the behaviour depends on the "mode" argument:
    1412 
    1413         if (found == false ) // child node not found in inode tree
     1476        if (found == false )  // child not found in inode tree
    14141477        {
    14151478
    14161479#if (DEBUG_VFS_LOOKUP & 1)
    14171480if( DEBUG_VFS_LOOKUP < cycle )
    1418 printk("\n[DBG] %s : miss <%s> => load it\n", __FUNCTION__ , name );
    1419 #endif
     1481printk("\n[DBG] %s : miss <%s> node => try to create it\n",
     1482__FUNCTION__ , name );
     1483#endif
     1484            // if a child node is not found in the inode tree,
     1485            // we introduce a new (dentry/inode) in inode tree,
     1486            // and try to find it by scanning the parent directory mapper.
     1487            // . if it is found in parent mapper:
     1488            //   - if the child is a directory, the child mapper is loaded from device
     1489            //   - if the child is not a directory, the search is completed
     1490            // . if it is not found in the parent mapper:
     1491            //   - if ( not last or not create ) an error is reported
     1492            //   - if (last and create and dir) a new directory is created
     1493            //   - if (last and create and not dir) a new file is created
    14201494
    14211495            // release lock on parent inode
    14221496            vfs_inode_unlock( parent_xp );
    1423 
     1497 
    14241498            // get parent inode FS type
    14251499            parent_cxy = GET_CXY( parent_xp );
    1426             parent_ptr = (vfs_inode_t *)GET_PTR( parent_xp );
    1427             ctx_ptr    = (vfs_ctx_t *)hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->ctx ) );
     1500            parent_ptr = GET_PTR( parent_xp );
     1501            ctx_ptr    = (vfs_ctx_t *)hal_remote_lpt( XPTR( parent_cxy,&parent_ptr->ctx ) );
    14281502            fs_type    = hal_remote_lw( XPTR( parent_cxy , &ctx_ptr->type ) );
    14291503
     
    14311505            child_cxy = vfs_cluster_random_select();
    14321506 
    1433             // insert a new child dentry/inode in parent inode
     1507            // insert a new child dentry/inode in inode tree
    14341508            error = vfs_add_child_in_parent( child_cxy,
    1435                                              INODE_TYPE_DIR,
     1509                                             0,           // type will be updated later
    14361510                                             fs_type,
    14371511                                             parent_xp,
    14381512                                             name,
    1439                                              NULL,     // fs_type_specific inode extend
     1513                                             NULL,        // fs_type_specific inode extend
    14401514                                             &child_xp );
    14411515            if( error )
    14421516            {
    1443                 printk("\n[ERROR] in %s : thread %x cannot allocate inode for path <%s>\n",
    1444                 __FUNCTION__ , this , pathname );
     1517                printk("\n[ERROR] in %s : cannot create node %s for path <%s>\n",
     1518                __FUNCTION__ , name, pathname );
    14451519                return ENOMEM;
    14461520            }
    14471521
    1448             // scan parent mapper to complete the missing inode
     1522            // get child inode cluster and local pointer
     1523            child_cxy = GET_CXY( child_xp );
     1524            child_ptr = GET_PTR( child_xp );
     1525
     1526#if (DEBUG_VFS_LOOKUP & 1)
     1527if( DEBUG_VFS_LOOKUP < cycle )
     1528printk("\n[DBG] %s : missing <%s> inode speculatively created / cxy %x / ptr %x\n",
     1529__FUNCTION__ , name , child_cxy, child_ptr );
     1530#endif
     1531             // scan parent mapper to complete the missing inode
    14491532            if( parent_cxy == local_cxy )
    14501533            {
     
    14621545            }
    14631546
    1464             if ( error )
     1547            if ( error )   // child not found in parent mapper
    14651548            {
    1466                 printk("\n[ERROR] in %s : thread %x / <%s> node not found in <%s>\n",
    1467                 __FUNCTION__ , this , name , pathname );
    1468                 return ENOENT;
    1469             }
    1470 
    1471             // get child inode type
    1472             child_ptr  = (vfs_inode_t *)GET_PTR( child_xp );
    1473             child_type = hal_remote_lw( XPTR( child_cxy , &child_ptr->type ) );
    1474 
    1475             // load child mapper from device if it is a directory
    1476             if( child_type == INODE_TYPE_DIR )
    1477             {
    1478                 if( child_cxy == local_cxy )
     1549                if( last && create && dir )  // new directory  => update inode type
    14791550                {
    1480                     error = vfs_mapper_load_all( child_ptr );
     1551                     hal_remote_sw( XPTR( child_cxy, &child_ptr->type ), INODE_TYPE_DIR );
     1552
     1553#if (DEBUG_VFS_LOOKUP & 1)
     1554if( DEBUG_VFS_LOOKUP < cycle )
     1555printk("\n[DBG] %s : created node <%s> in path %s / type DIR\n",
     1556__FUNCTION__ , name, pathname );
     1557#endif
    14811558                }
    1482                 else
     1559                else if ( last && create )   // new file => update inode type
    14831560                {
    1484                     rpc_vfs_mapper_load_all_client( child_cxy,
    1485                                                     child_ptr,
    1486                                                     &error );
     1561                     hal_remote_sw( XPTR( child_cxy, &child_ptr->type ), INODE_TYPE_FILE );
     1562
     1563#if (DEBUG_VFS_LOOKUP & 1)
     1564if( DEBUG_VFS_LOOKUP < cycle )
     1565printk("\n[DBG] %s : created node <%s> in path %s / type FILE\n",
     1566__FUNCTION__ , name, pathname );
     1567#endif
    14871568                }
    1488 
    1489                 if ( error )
    1490                 {
    1491                     printk("\n[ERROR] in %s : thread %x / cannot access device for <%s>\n",
    1492                     __FUNCTION__ , this , name );
    1493                     return EIO;
     1569                else                         // not last or not create => remove created node
     1570                {                       
     1571                     printk("\n[ERROR] in %s : <%s> node not found in parent for <%s>\n",
     1572                     __FUNCTION__ , name , pathname );
     1573                     vfs_remove_child_from_parent( child_xp );
     1574                     return ENOENT;
    14941575                }
    14951576            }
    1496 
    1497             // TODO handle lookup mode here [AG]
     1577            else          // child found in parent
     1578            {
     1579                // load child mapper from device if child is a directory (prefetch)
     1580                if( hal_remote_lw( XPTR( child_cxy , &child_ptr->type ) ) == INODE_TYPE_DIR )
     1581                {
     1582                    if( child_cxy == local_cxy )
     1583                    {
     1584                        error = vfs_mapper_load_all( child_ptr );
     1585                    }
     1586                    else
     1587                    {
     1588                        rpc_vfs_mapper_load_all_client( child_cxy,
     1589                                                        child_ptr,
     1590                                                        &error );
     1591                    }
     1592                    if ( error )
     1593                    {
     1594                        printk("\n[ERROR] in %s : cannot load <%s> from device\n",
     1595                        __FUNCTION__ , name );
     1596                        vfs_remove_child_from_parent( child_xp );
     1597                        return EIO;
     1598                    }
     1599
     1600#if (DEBUG_VFS_LOOKUP & 1)
     1601if( DEBUG_VFS_LOOKUP < cycle )
     1602printk("\n[DBG] %s : load mapper from device for node <%s> in path %s\n",
     1603__FUNCTION__ , name, pathname );
     1604#endif
     1605                }
     1606            }
    14981607
    14991608            // take lock on parent inode
    15001609            vfs_inode_lock( parent_xp );
    1501 
    1502 #if (DEBUG_VFS_LOOKUP & 1)
    1503 if( DEBUG_VFS_LOOKUP < cycle )
    1504 printk("\n[DBG] %s : created node <%s>\n", __FUNCTION__ , name );
    1505 #endif
    1506 
    15071610        }
    1508 
     1611        else   // child found in inode tree
     1612        {
     1613       
    15091614#if (DEBUG_VFS_LOOKUP & 1)
    15101615if( DEBUG_VFS_LOOKUP < cycle )
     
    15121617__FUNCTION__ , name , GET_PTR(child_xp) , GET_CXY(child_xp) );
    15131618#endif
     1619            child_ptr  = GET_PTR( child_xp );
     1620            child_cxy  = GET_CXY( child_xp );
     1621            parent_cxy = GET_CXY( parent_xp );
     1622            parent_ptr = GET_PTR( parent_xp );
     1623
     1624            if( last && (mode & VFS_LOOKUP_CREATE) && (mode & VFS_LOOKUP_EXCL) )
     1625            {
     1626                printk("\n[ERROR] in %s : node already exist <%s>\n", __FUNCTION__, name );
     1627                return EINVAL;
     1628            }
     1629        }
    15141630
    15151631        // TODO check access rights here [AG]
     
    15401656cycle = (uint32_t)hal_get_cycles();
    15411657if( DEBUG_VFS_LOOKUP < cycle )
    1542 printk("\n[DBG] %s : thread %x exit for <%s> / inode %x in cluster %x / cycle %d\n",
    1543 __FUNCTION__, CURRENT_THREAD, pathname, GET_PTR(child_xp), GET_CXY(child_xp), cycle );
     1658printk("\n[DBG] %s : thread %x in process %x exit for <%s>\n"
     1659"     parent %x in cluster %x / child %x in cluster %x / cycle %d\n",
     1660__FUNCTION__ , this->trdid, process->pid, pathname,
     1661parent_ptr, parent_cxy, child_ptr, child_cxy, cycle );
    15441662#endif
    15451663
    15461664    // return searched pointer
    1547     *inode_xp = child_xp;
     1665    if( mode & VFS_LOOKUP_PARENT ) *inode_xp = parent_xp;
     1666    else                           *inode_xp = child_xp;
    15481667
    15491668    return 0;
     
    16381757    // get parent inode cluster and local pointer
    16391758    parent_cxy = GET_CXY( parent_xp );
    1640     parent_ptr = (vfs_inode_t *)GET_PTR( parent_xp );
     1759    parent_ptr = GET_PTR( parent_xp );
    16411760
    16421761#if DEBUG_VFS_ADD_CHILD
    16431762uint32_t cycle = (uint32_t)hal_get_cycles();
    16441763if( DEBUG_VFS_ADD_CHILD < cycle )
    1645 printk("\n[DBG] %s : thread %x enter for <%s> / child_cxy = %x / parent_cxy = %x\n",
    1646 __FUNCTION__ , CURRENT_THREAD , name , child_cxy , parent_cxy );
     1764printk("\n[DBG] %s : thread %x enter for <%s> / child_cxy = %x / parent_cxy = %x / cycle %d\n",
     1765__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, name,
     1766child_cxy, parent_cxy, (uint32_t)hal_get_cycles() );
    16471767#endif
    16481768
     
    17361856               __FUNCTION__ , child_cxy );
    17371857 
    1738         vfs_dentry_t * dentry = (vfs_dentry_t *)GET_PTR( dentry_xp );
     1858        vfs_dentry_t * dentry = GET_PTR( dentry_xp );
    17391859        if( parent_cxy == local_cxy ) vfs_dentry_destroy( dentry );
    1740         else rpc_vfs_dentry_destroy_client( parent_cxy , dentry );
     1860        else rpc_vfs_dentry_destroy_client( parent_cxy , dentry , &error );
    17411861        return ENOMEM;
    17421862    }
     
    17501870cycle = (uint32_t)hal_get_cycles();
    17511871if( DEBUG_VFS_ADD_CHILD < cycle )
    1752 printk("\n[DBG] %s : thread %x exit for <%s>\n",
    1753 __FUNCTION__ , CURRENT_THREAD , name );
     1872printk("\n[DBG] %s : thread %x in process %x exit for <%s>\n",
     1873__FUNCTION__, CURRENT_THREAD, CURRENT_THREAD->process->pid, name );
    17541874#endif
    17551875
     
    17581878    return 0;
    17591879
     1880    // FIXME update the refcount fields in both inode and dentry
     1881
    17601882}  // end vfs_add_child_in_parent()
     1883
     1884///////////////////////////////////////////////////////
     1885error_t vfs_remove_child_from_parent( xptr_t inode_xp )
     1886{
     1887    cxy_t          inode_cxy;
     1888    vfs_inode_t  * inode_ptr;
     1889    xptr_t         dentry_xp;
     1890    cxy_t          dentry_cxy;
     1891    vfs_dentry_t * dentry_ptr;
     1892    error_t        error;
     1893   
     1894    // get inode cluster and local pointer
     1895    inode_cxy = GET_CXY( inode_xp );
     1896    inode_ptr = GET_PTR( inode_xp );
     1897
     1898    // get cluster and pointers of associated dentry
     1899    dentry_xp  = hal_remote_lwd( XPTR( inode_cxy , &inode_ptr->parent_xp ) );
     1900    dentry_cxy = GET_CXY( dentry_xp );
     1901    dentry_ptr = GET_PTR( dentry_xp );
     1902
     1903    // FIXME update the refcount fields in both inode and dentry
     1904
     1905    // delete dentry
     1906    if( dentry_cxy == local_cxy )
     1907    {
     1908         error = vfs_dentry_destroy( dentry_ptr );
     1909    }
     1910    else
     1911    {
     1912         rpc_vfs_dentry_destroy_client( dentry_cxy,
     1913                                        dentry_ptr,
     1914                                        &error );
     1915    }
     1916    if( error ) return EINVAL;
     1917
     1918    // delete inode
     1919    if( inode_cxy == local_cxy )
     1920    {
     1921         vfs_inode_destroy( inode_ptr );
     1922    }
     1923    else
     1924    {
     1925         rpc_vfs_inode_destroy_client( inode_cxy,
     1926                                       inode_ptr,
     1927                                       &error );
     1928    }
     1929    if( error ) return EINVAL;
     1930
     1931    return 0;
     1932
     1933}  // end vfs_remove_child_from_parent()
    17611934
    17621935//////////////////////////////////////////////////////////////////////////////////////////
  • trunk/kernel/fs/vfs.h

    r457 r459  
    227227 * It is not replicated, and is dynamically allocated in the cluster that contains
    228228 * the inode, when a thread makes an open() or opendir() system call.
    229  * It cannot exist a file structure without an inode structure.
     229 * It cannot exist a file structure without an inode structure in same cluster.
    230230 * As the fd_array (containing extended pointers on the open file descriptors)
    231231 * is replicated in all process descriptors, we need a references counter.
     
    338338 * @ gid        : group owner ID.
    339339 * @ inode_xp   : [out] buffer for extended pointer on created inode.
    340  * # return 0 if success / return ENOMEM or EINVAL if error.
     340 * @ return 0 if success / return ENOMEM or EINVAL if error.
    341341 *****************************************************************************************/
    342342error_t vfs_inode_create( xptr_t            dentry_xp,
     
    353353 * This function releases memory allocated to an inode descriptor.
    354354 * It must be executed by a thread running in the cluster containing the inode,
    355  * and the inode refcount must be zero.
    356  * If the client thread is not running in the owner cluster, it must use the
    357  * rpc_vfs_inode_destroy_client() function.
     355 * and the inode refcount must be zero. If the client thread is not running in the owner
     356 * cluster, you must use the rpc_vfs_inode_destroy_client() function.
    358357 ******************************************************************************************
    359358 * @ inode  : local pointer on inode descriptor.
    360  *****************************************************************************************/
    361 void vfs_inode_destroy( vfs_inode_t *  inode ); 
     359 * @ return 0 if success / return EINVAL if error.
     360 *****************************************************************************************/
     361error_t vfs_inode_destroy( vfs_inode_t *  inode ); 
    362362
    363363/******************************************************************************************
     
    432432
    433433
    434 
    435 
    436 
    437 
    438 /******************************************************************************************
    439  * This function TODO                                                         
    440  *****************************************************************************************/
    441 error_t vfs_inode_trunc( vfs_inode_t * inode );
    442 
    443 /******************************************************************************************
    444  * This function TODO                                                         
    445  *****************************************************************************************/
    446 error_t vfs_inode_link( vfs_inode_t * inode,
    447                         uint32_t      igc );
    448 
    449 /******************************************************************************************
    450  * This function TODO                                                         
    451  *****************************************************************************************/
    452 error_t vfs_inode_unlink( vfs_inode_t * inode );
    453 
    454 
    455434/*****************************************************************************************/
    456435/***************** Dentry related functions **********************************************/
     
    478457 * This function releases memory allocated to a dentry descriptor.
    479458 * It must be executed by a thread running in the cluster containing the dentry,
    480  * and the dentry refcount must be zero.
    481  * If the client thread is not running in the owner cluster, it must use the
    482  * rpc_dentry_destroy_client() function.
     459 * and the dentry refcount must be zero. If the client thread is not running in the owner
     460 * cluster, you must use the rpc_dentry_destroy_client() function.
    483461 ******************************************************************************************
    484462 * @ dentry  : local pointer on dentry descriptor.
    485  *****************************************************************************************/
    486 void vfs_dentry_destroy( vfs_dentry_t *  dentry ); 
     463 * @ return 0 if success / return EINVAL if error.
     464 *****************************************************************************************/
     465error_t vfs_dentry_destroy( vfs_dentry_t *  dentry ); 
    487466
    488467/******************************************************************************************
     
    562541 * This function takes a pathname (absolute or relative to cwd) and returns an extended
    563542 * pointer on the associated inode.
    564  * - If a given name in the path is not found in the inode tree, it try to load the missing
    565  *   dentry/inode couple, from informations found in the parent directory.
     543 * - If a given directory name in the path is not found in the inode tree, it try to load
     544 *   the missing dentry/inode couple, from informations found in the parent directory.
    566545 * - If this directory entry does not exist on device, it returns an error.
    567546 * - If the the file identified by the pathname does not exist on device but the
     
    613592 * This function removes a couple dentry/inode from the Inode-Tree, and remove it from
    614593 * the external device.
    615  * TODO                   
    616594 ******************************************************************************************
    617595 * @ child_xp   : extended pointer on removed inode.
    618596 *****************************************************************************************/
    619 error_t vfs_remove_child_from_parent( xptr_t child_xp );
     597error_t vfs_remove_child_from_parent( xptr_t inode_xp );
    620598
    621599/******************************************************************************************
     
    716694
    717695/******************************************************************************************
    718  * This function close an open file descriptor:
    719  * 1) All entries in fd_array copies are directly cancelled by the calling thread,
     696 * This function close the -non-replicated- file descriptor identified by the <file_xp>
     697 * and <file_id> arguments.
     698 * 1) All entries in the fd_array copies are directly reset by the calling thread,
    720699 *    using remote accesses.
    721700 * 2) The memory allocated to file descriptor in cluster containing the inode is released.
    722701 *    It requires a RPC if cluster containing the file descriptor is remote.
    723702 ******************************************************************************************
    724  * @ file_xp     : extended pointer on the file descriptor.
     703 * @ file_xp     : extended pointer on the file descriptor in owner cluster.
    725704 * @ file_id     : file descriptor index in fd_array.
    726705 * @ returns 0 if success / -1 if error.
     
    848827
    849828/******************************************************************************************
    850  * This function makes I/O operations to move, from device to mapper, all pages covering
    851  * a given inode, identified by the <inode> argument. Inode be a directory or a file,
    852  * but this function is mainly used to load (prefetch) a complete directory to the mapper.
     829 * This function makes the I/O operations required to move, from device to mapper,
     830 * all pages covering a given inode, identified by the <inode> argument. The target
     831 * inode can be a directory or a file, but this function is mainly used to load (prefetch)
     832 * a complete directory to the mapper.
    853833 * Depending on the file system type, it calls the proper, FS specific function.
    854834 * It must be executed by a thread running in the cluster containing the mapper.
     
    862842
    863843
    864 
    865 /* deprecated [AG]
    866 
    867 typedef error_t (lookup_inode_t)  ( vfs_inode_t  * parent ,
    868                                     vfs_dentry_t * dentry );
    869 
    870 typedef error_t (write_inode_t)   ( vfs_inode_t  * inode );
    871 
    872 typedef error_t (release_inode_t) ( vfs_inode_t  * inode );
    873 
    874 typedef error_t (unlink_inode_t)  ( vfs_inode_t  * parent,
    875                                     vfs_dentry_t * dentry,
    876                                     uint32_t       flags );
    877 
    878 typedef error_t (stat_inode_t)    ( vfs_inode_t  * inode );
    879 
    880 typedef error_t (trunc_inode_t)   ( vfs_inode_t  * inode );
    881 
    882 typedef error_t (delete_inode_t)  ( vfs_inode_t  * inode );
    883 
    884 typedef 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 }
    896 vfs_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 
    905 typedef error_t (vfs_compare_dentry_t) ( char * first , char * second );
    906 
    907 typedef struct vfs_dentry_op_s
    908 {
    909         vfs_compare_dentry_t * compare;
    910 }
    911 vfs_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 
    921 typedef error_t (open_file_t   ) ( vfs_file_t * file,
    922                                    void       * extend );
    923 
    924 typedef error_t (read_file_t   ) ( vfs_file_t * file,
    925                                    char       * buffer,
    926                                    uint32_t     count );
    927 
    928 typedef error_t (write_file_t  ) ( vfs_file_t * file,
    929                                    char       * buffer,
    930                                    uint32_t     count );
    931 
    932 typedef error_t (lseek_file_t  ) ( vfs_file_t * file );
    933 
    934 typedef error_t (close_file_t  ) ( vfs_file_t * file );
    935 
    936 typedef error_t (release_file_t) ( vfs_file_t * file );
    937 
    938 typedef error_t (read_dir_t    ) ( vfs_file_t * file );
    939 
    940 typedef error_t (mmap_file_t   ) ( vfs_file_t    * file ,
    941                                    struct vseg_s * vseg );
    942 
    943 typedef error_t (munmap_file_t ) ( vfs_file_t    * file,
    944                                    struct vseg_s * vseg );
    945 
    946 typedef 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 }
    958 vfs_file_op_t;
    959 
    960 */
    961 
    962844#endif  /* _VFS_H_ */
  • trunk/kernel/kern/printk.c

    r457 r459  
    406406        remote_spinlock_lock_busy( lock_xp , &save_sr );
    407407
    408         // call nolock_printk to print function_name
    409         nolock_printk("\n[PANIC] on core[%x,%d] in %s : " ,
    410         local_cxy , CURRENT_THREAD->core->lid , function_name );
     408        // call nolock_printk to print core, function_name, and cycle
     409        nolock_printk("\n[PANIC] on core[%x,%d] in %s at cycle %d : " ,
     410        local_cxy, CURRENT_THREAD->core->lid, function_name, (uint32_t)hal_get_cycles() );
    411411
    412412        // call kernel_printf on TXT0, in busy waiting to print format
  • trunk/kernel/kern/process.c

    r457 r459  
    10181018                if( entry != XPTR_NULL )
    10191019                {
    1020             // increment file descriptor ref count
     1020            // increment file descriptor refcount
    10211021            vfs_file_count_up( entry );
    10221022
  • trunk/kernel/kern/rpc.c

    r457 r459  
    980980                                  error_t      * error )     // out
    981981{
     982#if DEBUG_RPC_VFS_INODE_CREATE
     983uint32_t cycle = (uint32_t)hal_get_cycles();
     984if( cycle > DEBUG_RPC_VFS_INODE_CREATE )
     985printk("\n[DBG] %s : thread %x enter on core[%x,%d] / cycle %d\n",
     986__FUNCTION__ , CURRENT_THREAD , local_cxy, CURRENT_THREAD->core->lid , cycle );
     987#endif
     988
    982989    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
    983990
     
    10051012    *error    = (error_t)rpc.args[9];
    10061013
     1014#if DEBUG_RPC_VFS_INODE_CREATE
     1015uint32_t cycle = (uint32_t)hal_get_cycles();
     1016if( cycle > DEBUG_RPC_VFS_INODE_CREATE )
     1017printk("\n[DBG] %s : thread %x exit on core[%x,%d] / cycle %d\n",
     1018__FUNCTION__ , CURRENT_THREAD , local_cxy, CURRENT_THREAD->core->lid , cycle );
     1019#endif
    10071020}
    10081021
     
    10101023void rpc_vfs_inode_create_server( xptr_t xp )
    10111024{
     1025#if DEBUG_RPC_VFS_INODE_CREATE
     1026uint32_t cycle = (uint32_t)hal_get_cycles();
     1027if( cycle > DEBUG_RPC_VFS_INODE_CREATE )
     1028printk("\n[DBG] %s : thread %x enter on core[%x,%d] / cycle %d\n",
     1029__FUNCTION__ , CURRENT_THREAD , local_cxy, CURRENT_THREAD->core->lid , cycle );
     1030#endif
     1031
    10121032    xptr_t           dentry_xp;
    10131033    uint32_t         fs_type;
     
    10501070    hal_remote_swd( XPTR( client_cxy , &desc->args[9] ) , (uint64_t)error );
    10511071
     1072#if DEBUG_RPC_VFS_INODE_CREATE
     1073uint32_t cycle = (uint32_t)hal_get_cycles();
     1074if( cycle > DEBUG_RPC_VFS_INODE_CREATE )
     1075printk("\n[DBG] %s : thread %x exit on core[%x,%d] / cycle %d\n",
     1076__FUNCTION__ , CURRENT_THREAD , local_cxy, CURRENT_THREAD->core->lid , cycle );
     1077#endif
    10521078}
    10531079
     
    10581084/////////////////////////////////////////////////////////////
    10591085void rpc_vfs_inode_destroy_client( cxy_t                cxy,
    1060                                    struct vfs_inode_s * inode )
    1061 {
     1086                                   struct vfs_inode_s * inode,
     1087                                   error_t            * error )
     1088{
     1089#if DEBUG_RPC_VFS_INODE_DESTROY
     1090uint32_t cycle = (uint32_t)hal_get_cycles();
     1091if( cycle > DEBUG_RPC_VFS_INODE_DESTROY )
     1092printk("\n[DBG] %s : thread %x enter on core[%x,%d] / cycle %d\n",
     1093__FUNCTION__ , CURRENT_THREAD , local_cxy, CURRENT_THREAD->core->lid , cycle );
     1094#endif
     1095
    10621096    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
    10631097
     
    10741108    rpc_send( cxy , &rpc );
    10751109
     1110#if DEBUG_RPC_VFS_INODE_DESTROY
     1111uint32_t cycle = (uint32_t)hal_get_cycles();
     1112if( cycle > DEBUG_RPC_VFS_INODE_DESTROY )
     1113printk("\n[DBG] %s : thread %x exit on core[%x,%d] / cycle %d\n",
     1114__FUNCTION__ , CURRENT_THREAD , local_cxy, CURRENT_THREAD->core->lid , cycle );
     1115#endif
    10761116}
    10771117
     
    10791119void rpc_vfs_inode_destroy_server( xptr_t xp )
    10801120{
     1121#if DEBUG_RPC_VFS_INODE_DESTROY
     1122uint32_t cycle = (uint32_t)hal_get_cycles();
     1123if( cycle > DEBUG_RPC_VFS_INODE_DESTROY )
     1124printk("\n[DBG] %s : thread %x enter on core[%x,%d] / cycle %d\n",
     1125__FUNCTION__ , CURRENT_THREAD , local_cxy, CURRENT_THREAD->core->lid , cycle );
     1126#endif
     1127
    10811128    vfs_inode_t * inode;
     1129    error_t       error;
    10821130
    10831131    // get client cluster identifier and pointer on RPC descriptor
     
    10891137                       
    10901138    // call local kernel function
    1091     vfs_inode_destroy( inode );
    1092 
     1139    error = vfs_inode_destroy( inode );
     1140
     1141    // set output argument
     1142    hal_remote_swd( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error );
     1143
     1144#if DEBUG_RPC_VFS_INODE_DESTROY
     1145uint32_t cycle = (uint32_t)hal_get_cycles();
     1146if( cycle > DEBUG_RPC_VFS_INODE_DESTROY )
     1147printk("\n[DBG] %s : thread %x exit on core[%x,%d] / cycle %d\n",
     1148__FUNCTION__ , CURRENT_THREAD , local_cxy, CURRENT_THREAD->core->lid , cycle );
     1149#endif
    10931150}
    10941151
     
    11941251///////////////////////////////////////////////////////
    11951252void rpc_vfs_dentry_destroy_client( cxy_t          cxy,
    1196                                     vfs_dentry_t * dentry )
     1253                                    vfs_dentry_t * dentry,
     1254                                    error_t      * error )
    11971255{
    11981256#if DEBUG_RPC_VFS_DENTRY_DESTROY
     
    12361294
    12371295    vfs_dentry_t * dentry;
     1296    error_t        error;
    12381297
    12391298    // get client cluster identifier and pointer on RPC descriptor
     
    12451304                       
    12461305    // call local kernel function
    1247     vfs_dentry_destroy( dentry );
     1306    error = vfs_dentry_destroy( dentry );
     1307
     1308    // set output argument
     1309    hal_remote_swd( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error );
    12481310
    12491311#if DEBUG_RPC_VFS_DENTRY_DESTROY
  • trunk/kernel/kern/rpc.h

    r457 r459  
    350350 * @ cxy       :  server cluster identifier
    351351 * @ inode     : [in]  local pointer on inode.
     352 * @ error     : [out] error status (0 if success).
    352353 **********************************************************************************/
    353354void rpc_vfs_inode_destroy_client( cxy_t                 cxy,
    354                                    struct vfs_inode_s * inode );
     355                                   struct vfs_inode_s * inode,
     356                                   error_t            * error );
    355357
    356358void rpc_vfs_inode_destroy_server( xptr_t xp );
     
    377379
    378380/***********************************************************************************
    379  * [13] The RPC_VFS_DENTRY_DESTROY releases memory allocated for an dentry descriptor
    380  * in a remote cluster.
     381 * [13] The RPC_VFS_DENTRY_DESTROY remove a denfry from the parent inode XHTAB,
     382 * and releases memory allocated for the dentry descriptor in a remote cluster.
    381383 ***********************************************************************************
    382384 * @ cxy       :  server cluster identifier
    383385 * @ dentry     : [in]  local pointer on dentry.
     386 * @ error     : [out] error status (0 if success).
    384387 **********************************************************************************/
    385388void rpc_vfs_dentry_destroy_client( cxy_t                 cxy,
    386                                     struct vfs_dentry_s * dentry );
     389                                    struct vfs_dentry_s * dentry,
     390                                    error_t             * error );
    387391
    388392void rpc_vfs_dentry_destroy_server( xptr_t xp );
  • trunk/kernel/kern/thread.h

    r457 r459  
    118118 * This structure defines a thread descriptor.
    119119 * It is used for both the user threads and the kernel threads.
    120  * In a process, a user thread is identified by a unique TRDID (thread identifier),
    121  * that is returned by the kernel to the user:
     120 * In a process, a user thread is identified by a unique TRDID (thread identifier):
    122121 * - The TRDID 16 LSB bits contain the LTID (Local Thread Index).
    123122 * - The TRDID 16 MSB bits contain the CXY of cluster containing the thread.
    124  * - The LTID is used to index the th_tbl[] array in the local process descriptor.
    125  _* This TRDID is computed by the process_register_thread() function, when the user
     123 * The main thread LTID value is always 0.
     124 * The LTID is used to index the th_tbl[] array in the local process descriptor.
     125 * This TRDID is computed by the process_register_thread() function, when the user
    126126 * thread is registered in the local copy of the process descriptor.
    127  *
    128127 * WARNING : Don't modify the first 4 fields order, as this order is used by the
    129128 * hal_kentry assembly code for the TSAR architecture.
  • trunk/kernel/kernel_config.h

    r457 r459  
    109109#define DEBUG_RPC_PROCESS_MAKE_FORK    0
    110110#define DEBUG_RPC_PROCESS_SIGACTION    0
     111#define DEBUG_RPC_VFS_INODE_CREATE     0
     112#define DEBUG_RPC_VFS_INODE_DESTROY    0
    111113#define DEBUG_RPC_VFS_DENTRY_CREATE    0
    112114#define DEBUG_RPC_VFS_DENTRY_DESTROY   0
     
    117119
    118120#define DEBUG_SCHED_HANDLE_SIGNALS     2
    119 #define DEBUG_SCHED_YIELD              1    // must be activated by the trace() syscall
     121#define DEBUG_SCHED_YIELD              2    // must be activated by the trace() syscall
    120122
    121123#define DEBUG_SYSCALLS_ERROR           2
    122124
     125#define DEBUG_SYS_CLOSE                2
    123126#define DEBUG_SYS_DISPLAY              0
    124127#define DEBUG_SYS_EXEC                 0
    125 #define DEBUG_SYS_EXIT                 0
     128#define DEBUG_SYS_EXIT                 1
    126129#define DEBUG_SYS_FG                   0
    127130#define DEBUG_SYS_FORK                 0
     
    130133#define DEBUG_SYS_IS_FG                0
    131134#define DEBUG_SYS_KILL                 0
     135#define DEBUG_SYS_OPEN                 2
    132136#define DEBUG_SYS_MMAP                 0
    133137#define DEBUG_SYS_READ                 0
     
    158162#define DEBUG_THREAD_BLOCK             0
    159163
     164#define DEBUG_VFS_CLOSE                0
    160165#define DEBUG_VFS_INODE_CREATE         0
    161166#define DEBUG_VFS_INODE_LOAD           0
  • trunk/kernel/libk/htab.h

    r457 r459  
    22 * htab.h - Generic embedded hash table definition.
    33 *
    4  * Authors  Alain Greiner (2016,2017)
     4 * Authors  Alain Greiner (2016,2017,2018)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    4242// - From the pointer on <key>, we use an item type specific htab_index() function,
    4343//   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
     44// - As several items can have the same <index>, we use the item type specific
    4545//   htab_scan() function for a final associative search on the subset.
    4646// - Each registered item is a structure, that must contain an embedded list_entry_t,
  • trunk/kernel/libk/xhtab.h

    r457 r459  
    22 * xhtab.h - Remote access embedded hash table definition.
    33 *
    4  * Author     Alain Greiner  (2016,2017)
     4 * Author     Alain Greiner  (2016,2017,2018)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    5454//
    5555// Implementation Note:
    56 // For each supported item type ***, you must define four item-type-specific
     56// To inroduce a new item type, you must define the four item-type-specific
    5757// functions specified below, and you must update the xhtab_init() function
    5858// and the xhtab_item_type_t.
     
    8282
    8383/******************************************************************************************
    84  * This structure define the root of the remote accessible hash table.
     84 * This structure define the root of the remotely accessible hash table.
    8585 *****************************************************************************************/
    8686
     
    124124 * This function safely remove an item from the hash table, using the lock protecting it.
    125125 ******************************************************************************************
    126  * @ xhtab_xp       : extended pointer on hash table.
    127  * @ key            : local pointer on item identifier.
    128  * @ xlist_entry_xp : extended pointer on xlist_entry embedded in item to be removed.
     126 * @ xhtab_xp   : extended pointer on hash table.
     127 * @ key        : local pointer on item identifier.
     128 * @ xlist_xp  : extended pointer on xlist_entry embedded in item to be removed.
    129129 * @ return 0 if success / return EINVAL if item not found.
    130130 *****************************************************************************************/
  • trunk/kernel/syscalls/shared_include/shared_fcntl.h

    r445 r459  
    11/*
    2  *upashared_fcntl.h - Shared structures used by file related syscalls.
     2 * shared_fcntl.h - Shared structures used by file related syscalls.
    33 *
    44 * Author  Alain Greiner (2016,2017,2018)
     
    3333    O_RDONLY   = 0x0010000,    /*! open file in read-only mode                            */
    3434    O_WRONLY   = 0x0020000,    /*! open file in write-only mode                           */
    35     O_RDWR     = 0x0030000,    /*! open file in read/write mode                           */
     35    O_RDWR     = 0x0000000,    /*! open file in read/write mode                           */
    3636    O_NONBLOCK = 0x0040000,    /*! do not block if data non available                     */
    3737    O_APPEND   = 0x0080000,    /*! append on each write                                   */
  • trunk/kernel/syscalls/sys_close.c

    r457 r459  
    3939        process_t * process = this->process;
    4040
     41#if DEBUG_SYS_CLOSE
     42uint32_t     tm_start;
     43uint32_t     tm_end;
     44tm_start = hal_get_cycles();
     45if( DEBUG_SYS_CLOSE < tm_start )
     46printk("\n[DBG] %s : thread %x in process %x enter / fdid %d / cycle %d\n",
     47__FUNCTION__, this->trdid, process->pid, file_id, (uint32_t)tm_start );
     48#endif
     49 
    4150    // check file_id argument
    4251        if( file_id >= CONFIG_PROCESS_FILE_MAX_NR )
     
    7281        hal_fence();
    7382
     83#if DEBUG_SYS_CLOSE
     84tm_end = hal_get_cycles();
     85if( DEBUG_SYS_CLOSE < tm_start )
     86printk("\n[DBG] %s : thread %x in process %x exit / cost %d / cycle %d\n",
     87__FUNCTION__, this->trdid, process->pid, (uint32_t)(tm_end - tm_start), (uint32_t)tm_start );
     88#endif
     89 
    7490        return 0;
    7591}
  • trunk/kernel/syscalls/sys_open.c

    r457 r459  
    4646    process_t    * process  = this->process;
    4747
     48#if DEBUG_SYS_OPEN
     49uint32_t     tm_start;
     50uint32_t     tm_end;
     51tm_start = hal_get_cycles();
     52#endif
     53 
    4854    // check fd_array not full
    4955    if( process_fd_array_full() )
     
    6672    hal_strcpy_from_uspace( kbuf , pathname , CONFIG_VFS_MAX_PATH_LENGTH );
    6773
     74#if DEBUG_SYS_OPEN
     75if( DEBUG_SYS_OPEN < tm_start )
     76printk("\n[DBG] %s : thread %x in process %x enter / path %s / flags %x / cycle %d\n",
     77__FUNCTION__, this->trdid, process->pid, kbuf, flags, (uint32_t)tm_start );
     78#endif
     79 
    6880    // get cluster and local pointer on reference process
    6981    xptr_t      ref_xp  = process->ref_xp;
     
    8799    if( error )
    88100    {
    89         printk("\n[ERROR] in %s : cannot create file descriptor\n", __FUNCTION__ );
     101        printk("\n[ERROR] in %s : cannot create file descriptor for %s\n",
     102        __FUNCTION__ , kbuf );
    90103        this->errno = ENFILE;
    91104        return -1;
     
    97110    remote_spinlock_unlock( XPTR( local_cxy , &process->fd_array.lock ) );
    98111
     112    hal_fence();
     113
     114#if DEBUG_SYS_OPEN
     115tm_end = hal_get_cycles();
     116if( DEBUG_SYS_OPEN < tm_start )
     117printk("\n[DBG] %s : thread %x in process %x exit / cost %d / cycle %d\n",
     118__FUNCTION__, this->trdid, process->pid, (uint32_t)(tm_end - tm_start), (uint32_t)tm_start );
     119#endif
     120 
    99121    return file_id;
    100122}
  • trunk/kernel/syscalls/sys_read.c

    r457 r459  
    7272tm_start = hal_get_cycles();
    7373if( DEBUG_SYS_READ < tm_start )
    74 printk("\n[DBG] %s : thread %x enter / process %x / vaddr = %x / count %d / cycle %d\n",
    75 __FUNCTION__, this, process->pid, vaddr, count, (uint32_t)tm_start );
     74printk("\n[DBG] %s : thread %x in process %x enter / vaddr %x / count %d / cycle %d\n",
     75__FUNCTION__, this->trdid, process->pid, vaddr, count, (uint32_t)tm_start );
    7676#endif
    7777
     
    231231tm_end = hal_get_cycles();
    232232if( DEBUG_SYS_READ < tm_end )
    233 printk("\n[DBG] %s : thread %x exit / process %x / cycle %d\n"
    234 "nbytes = %d / file_id = %d / cost = %d\n",
    235 __FUNCTION__ , this, process->pid,
     233printk("\n[DBG] %s : thread %x in process %x exit / cycle %d\n"
     234"nbytes %d / file_id %d / cost %d\n",
     235__FUNCTION__ , this->trdid, process->pid,
    236236(uint32_t)tm_start , nbytes , file_id , (uint32_t)(tm_end - tm_start) );
    237237#endif
  • trunk/kernel/syscalls/sys_write.c

    r457 r459  
    7373tm_start = hal_get_cycles();
    7474if( DEBUG_SYS_WRITE < tm_start )
    75 printk("\n[DBG] %s : thread %x enter / process %x / vaddr %x / count %d / cycle %d\n",
    76 __FUNCTION__, this, process->pid, vaddr, count, (uint32_t)tm_start );
     75printk("\n[DBG] %s : thread %x in process %x enter / vaddr %x / count %d / cycle %d\n",
     76__FUNCTION__, this->trdid, process->pid, vaddr, count, (uint32_t)tm_start );
    7777#endif
    7878 
     
    195195tm_end = hal_get_cycles();
    196196if( DEBUG_SYS_WRITE < tm_end )
    197 printk("\n[DBG] %s : thread %x exit / process %x / cycle %d\n"
    198 "nbytes = %d / file_id = %d / cost = %d\n",
    199 __FUNCTION__, this, process->pid, (uint32_t)tm_start,
     197printk("\n[DBG] %s : thread %x in process %x exit / cycle %d\n"
     198"nbytes %d / file_id %d / cost %d\n",
     199__FUNCTION__, this->trdid, process->pid, (uint32_t)tm_start,
    200200nbytes, file_id , (uint32_t)(tm_end - tm_start) );
    201201#endif
  • trunk/libs/mini-libc/stdio.c

    r457 r459  
    2626#include <almosmkh.h>
    2727#include <unistd.h>
     28#include <fcntl.h>
     29
     30////////////////////////////////////////////////////////////////////////////////////////
     31//          stdio library global variables
     32////////////////////////////////////////////////////////////////////////////////////////
     33
     34FILE open_file_array[MAX_OPEN_FILE_PER_PROCESS];  // array of open files structures
     35
     36////////////////////////////////////////////////////////////////////////////////////////
     37//          stdio library functions
     38////////////////////////////////////////////////////////////////////////////////////////
    2839
    2940//////////////////////////////////////////
     
    144155                break;
    145156            }
    146 /*
    147157            case ('f'):             // IEEE754 64 bits
    148158                                    // integer part : up to 10 decimal digits
     
    234244                break;
    235245            }
    236 */                   
    237246            default:       // unsupported argument type
    238247            {
     
    272281    {
    273282        string[count] = 0;
     283
    274284        return write( 1 , &string , count );
    275285    }
    276 }
     286}  // end printf()
    277287
    278288/////////////
     
    309319
    310320    return count;
    311 }
    312 
    313 
    314 
    315 
    316 
     321}  // end snprintf()
     322
     323////////////////////////////////////
     324FILE * fopen( const char * pathname,
     325              const char * mode )
     326{
     327    //TODO handle the "mode" argument
     328    if( mode != NULL )
     329    {
     330        printf("\n[ERROR] in %s : the mode argument must be NULL\n", __FUNCTION__ );
     331        return NULL;
     332    }
     333
     334    // get a file descriptor from kernel
     335    int fd = open( pathname,
     336                   O_CREAT | O_RDWR,
     337                   0 );
     338
     339    if( fd < 0 )
     340    {
     341        printf("\n[ERROR] in %s : file %s not found\n", __FUNCTION__ , pathname );
     342        return NULL;
     343    }
     344    if( fd > MAX_OPEN_FILE_PER_PROCESS )
     345    {
     346        printf("\n[ERROR] in %s : not enough space for file %s\n", __FUNCTION__ , pathname );
     347        return NULL;
     348    }
     349
     350    // register stream in open_file_array[]
     351    open_file_array[fd].fd  = fd;
     352    open_file_array[fd].key = VALID_OPEN_FILE;
     353
     354    return &open_file_array[fd];
     355}  // end fopen()
     356
     357///////////////////////////
     358int fclose( FILE * stream )
     359{
     360    // check stream valid
     361    if( stream->key != VALID_OPEN_FILE ) return EOF;
     362
     363    // get file descriptor from stream pointer
     364    int fd = stream->fd;
     365
     366    // remove stream from open_file_array[]
     367    open_file_array[fd].key = 0;
     368   
     369    return close( fd );
     370}  // end fclose()
     371
     372/////////////////////////////////
     373int fprintf( FILE       * stream,
     374             const char * format, ... )
     375{
     376    char      string[4096];
     377    va_list   args;
     378    int       count;
     379    int       fd;
     380   
     381    // check stream valid
     382    if( stream->key != VALID_OPEN_FILE ) return EOF;
     383
     384    va_start( args, format );
     385    count = xprintf( string , 4095 , format , &args );
     386    va_end( args );
     387
     388    if ( count == -1 )
     389    {
     390        display_string( "fprintf : xprintf failure" );
     391        return -1;
     392    }
     393    else
     394    {
     395        // get file descriptor from file pointer
     396        fd = stream->fd;
     397       
     398        string[count] = 0;
     399
     400        return write( fd , &string , count );
     401    }
     402}  // end fprintf()
     403
     404
     405
     406
     407
  • trunk/libs/mini-libc/stdio.h

    r445 r459  
    3131 ********************************************************************************************/
    3232
     33/*********************************************************************************************
     34 * This defines the user level FILE structure.
     35 ********************************************************************************************/
     36
     37#define  MAX_OPEN_FILE_PER_PROCESS  256
     38#define  VALID_OPEN_FILE            0x12345678
     39#define  EOF                        -1
     40#define  NULL                       (void *)0
     41
     42typedef struct file_s
     43{
     44    int fd;
     45    int key;
     46}
     47FILE;
    3348
    3449/*********************************************************************************************
     
    6782              const char   * format, ... );
    6883
     84/*********************************************************************************************
     85 * This function opens the file identified by the <pathname> argument and associates
     86 * the stream pointed by <FILE> with it.
     87 * The <mode> argument is a string that can have the following values:
     88 * - "r"   Open text file for reading.
     89 *         The stream is positioned at the beginning of the file.
     90 * - "r+"  Open for reading and writing.
     91 *         The stream is positioned at the beginning of the file.
     92 * - "w"   Truncate the file to zero length or create text file for writing.
     93 *         The stream is positioned at the beginning of the file.
     94 * - "w+"  Open for reading and writing.
     95 *         The file is created if it does not exist, otherwise it is truncated.
     96 *         The stream is positioned at the beginning of the file.
     97 * - "a"   Open for writing.  The file is created if it does not exist.
     98 *         The stream is positioned at the end of the file. 
     99 *         Subsequent writes to the file will always end up at the current end of file,
     100 *         irrespective of any intervening fseek() or similar.
     101 * - "a+"  Open for reading and writing. 
     102 *         The file is created if it does not exist. 
     103 *         The stream is positioned at the end of the file.
     104 *         Subsequent writes to the file will always end up at the current end of file,
     105 *         irrespective of any intervening fseek() or similar.
     106 *********************************************************************************************
     107 * @ pathname  : file pathname.
     108 * @ mode      : must be NULL <=> only "w+" mode is supported.
     109 * @ returns a stream pointer if success / returns NULL if file not found.
     110 ********************************************************************************************/
     111FILE * fopen( const char * pathname,
     112              const char * mode );
     113
     114/*********************************************************************************************
     115 * This function dissociates the stream from its underlying file and close this file.
     116 * If the stream was being used for output, any buffered data is written first.
     117 *********************************************************************************************
     118 * @ stream    : pointer on a stream.
     119 * @ returns 0 if success / returns EOF if failure.
     120 ********************************************************************************************/
     121int fclose( FILE * stream );
     122
     123/*********************************************************************************************
     124 * This function copies a formated string to an output stream identified by the <stream>
     125 * argument. It can be a  regular file or a character oriented output device.
     126 *********************************************************************************************
     127 * @ stream    : pointer on a stream.
     128 * @ format    : formated string.
     129 * @ returns number of characters written if success / returns -1 if failure.
     130 ********************************************************************************************/
     131int fprintf( FILE       * stream,
     132             const char * format, ... );
     133
     134
    69135#endif  // _STDIO_H_
  • trunk/libs/mini-libc/unistd.h

    r449 r459  
    4545
    4646/*****************************************************************************************
    47  * This function read bytes from an open file identified by its file descriptor.
     47 * This function read bytes from an open file identified by the <fd> file descriptor.
    4848 * This file can be a regular file or a character oriented device.
    4949 *****************************************************************************************
    50  * @ file_id  : open file index in fd_array.
     50 * @ fd       : open file index in fd_array.
    5151 * @ buf      : buffer virtual address in user space.
    5252 * @ count    : number of bytes.
     
    5858
    5959/*****************************************************************************************
    60  * This function writes bytes to an open file identified by its file descriptor.
     60 * This function writes bytes to an open file identified by the <fd> file descriptor.
    6161 * This file can be a regular file or character oriented device.
    6262 *****************************************************************************************
    63  * @ file_id  : open file index in fd_array.
     63 * @ fd       : open file index in fd_array.
    6464 * @ buf      : buffer virtual address in user space.
    6565 * @ count    : number of bytes.
     
    112112 * TODO not implemented yet...
    113113 *****************************************************************************************
    114  * @ file_id[0] : [out] read only file descriptor index.
    115  * @ file_id[1] : [out] write only file descriptor index.
     114 * @ fd[0] : [out] read only file descriptor index.
     115 * @ fd[1] : [out] write only file descriptor index.
    116116 * @ return 0 if success / return -1 if failure.
    117117 ****************************************************************************************/
  • trunk/params-soft.mk

    r457 r459  
    4646LIBSEMAPHORE_INCLUDE = $(LIBSEMAPHORE_PATH)/build/include/
    4747
     48# define paths for LIBMATH
     49LIBMATH_PATH    = $(ALMOSMKH_DIR)/libs/libmath
     50LIBMATH         = $(LIBMATH_PATH)/build/lib/
     51LIBMATH_INCLUDE = $(LIBMATH_PATH)/build/include/
     52
    4853# define paths for LIBALMOSMKH
    4954LIBALMOSMKH_PATH    = $(ALMOSMKH_DIR)/libs/libalmosmkh
     
    5257
    5358# define paths for HAL
    54 HAL      = $(ALMOSMKH_DIR)/hal
    55 HAL_ARCH = $(HAL)/$(ARCH_NAME)
     59HAL            = $(ALMOSMKH_DIR)/hal
     60HAL_ARCH       = $(HAL)/$(ARCH_NAME)
     61HAL_INCLUDE    = $(HAL_ARCH)/core
    5662
    57 KERNEL   = $(ALMOSMKH_DIR)/kernel
    58 
     63# define paths for KERNEL
     64KERNEL         = $(ALMOSMKH_DIR)/kernel
    5965SHARED_INCLUDE = $(KERNEL)/syscalls/shared_include/
    6066
  • trunk/user/ksh/ksh.c

    r458 r459  
    795795        unsigned int state;                   // escape sequence state
    796796
    797 char string[80];
     797// @@@
     798// parse( "load /bin/user/fft.elf" );
     799// @@@
    798800
    799801        enum fsm_states
     
    10001002    // get KSH process pid and core
    10011003    parent_pid = getpid();
    1002     get_core( &cxy , & lid );
    1003 
    1004         printf( "\n\n~~~ KSH on core[%x,%d] ~~~\n\n", cxy , lid );
     1004    get_core( &cxy , &lid );
    10051005
    10061006    // initializes the semaphore used to unblock the interactive thread
  • trunk/user/sort/Makefile

    r445 r459  
    11############################################################################
    2 # Makefile for the ALMOS-MKH "sort" application
     2# Makefile for the "sort" application running on ALMOS-MKH
    33############################################################################
    44
     
    1515           -I$(LIBPTHREAD_INCLUDE)  \
    1616           -I$(LIBALMOSMKH_INCLUDE) \
    17            -I$(SHARED_INCLUDE)
     17           -I$(SHARED_INCLUDE)      \
     18           -I$(HAL_INCLUDE)
    1819
    1920compile: dirs build/sort.elf
    2021
    2122build/sort.elf : $(OBJS) sort.ld
    22         $(LD) -o $@ -T sort.ld $(OBJS) -L$(LIBC) -L$(LIBPTHREAD) -L$(LIBALMOSMKH) -lc -lpthread -lalmosmkh -lpthread -lc
     23        $(LD) -o $@ -T sort.ld $(OBJS) -L$(LIBC) -L$(LIBPTHREAD) -L$(LIBALMOSMKH) \
     24        -lc -lpthread -lalmosmkh -lpthread -lc
    2325        $(DU) -D $@ > $@.txt
    2426
  • trunk/user/sort/sort.c

    r457 r459  
    2626#include <pthread.h>
    2727#include <almosmkh.h>
     28#include <hal_macros.h>
    2829
    2930#define ARRAY_LENGTH        0x400    // 1024 values
     
    3334#define DISPLAY_ARRAY       0
    3435#define INTERACTIVE_MODE    0
    35 
    36 ///////////////////////////////////////////////////////
    37 // macros for fixed format cxy <=> (x,y) translation
    38 // TODO these macros are only for TSAR architecture...
    39 ///////////////////////////////////////////////////////
    40 
    41 #define CXY_FROM_XY( x , y )  ((x<<4) + y)
    42 
    43 #define X_FROM_CXY( cxy )     ((cxy>>4) & 0xF)
    44 
    45 #define Y_FROM_CXY( cxy )     (cxy & 0xF)
    4636
    4737/////////////////////////////////////////////////////////////
     
    239229    // get core coordinates and user index for the main thread
    240230    get_core( &main_cxy , & main_lid );
    241     main_x   = X_FROM_CXY( main_cxy );
    242     main_y   = Y_FROM_CXY( main_cxy );
     231    main_x   = HAL_X_FROM_CXY( main_cxy );
     232    main_y   = HAL_Y_FROM_CXY( main_cxy );
    243233    main_uid = (((main_x * y_size) + main_y) * ncores) + main_lid;
    244234
     
    308298                // set thread attributes for all threads
    309299                attr[thread_uid].attributes = PT_ATTR_CLUSTER_DEFINED | PT_ATTR_CORE_DEFINED;
    310                 attr[thread_uid].cxy        = CXY_FROM_XY( x , y );
     300                attr[thread_uid].cxy        = HAL_CXY_FROM_XY( x , y );
    311301                attr[thread_uid].lid        = lid;
    312302
Note: See TracChangeset for help on using the changeset viewer.