Changeset 651 for trunk/kernel/syscalls


Ignore:
Timestamp:
Nov 14, 2019, 11:50:09 AM (4 years ago)
Author:
alain
Message:

1) Improve the VMM MMAP allocator: implement the "buddy" algorithm
to allocate only aligned blocks.
2) fix a bug in the pthread_join() / pthread_exit() mmechanism.

Location:
trunk/kernel/syscalls
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/syscalls/sys_exit.c

    r625 r651  
    108108__FUNCTION__, pid, this->trdid );
    109109#endif
    110         thread_delete( XPTR( local_cxy , this ) , pid , true );
     110        thread_delete( XPTR( local_cxy , this ) , true );    // forced
    111111    }
    112112
  • trunk/kernel/syscalls/sys_get_nb_cores.c

    r639 r651  
    3535#include <syscalls.h>
    3636
    37 ////////////////////////////////////
     37/////////////////////////////////////
    3838int sys_get_nb_cores( uint32_t   cxy,
    3939                      uint32_t * ncores )
     
    5151#if DEBUG_SYS_GET_NB_CORES
    5252if( DEBUG_SYS_GET_NB_CORES < tm_start )
    53 printk("\n[%s] thread[%x,%x] enter / cycle %d\n",
    54 __FUNCTION__, process->pid, this->trdid, (uint32_t)tm_start );
     53printk("\n[%s] thread[%x,%x] enter  for cluster %x / cycle %d\n",
     54__FUNCTION__, process->pid, this->trdid, cxy, (uint32_t)tm_start );
    5555#endif
    5656
     
    8888#if DEBUG_SYS_GET_NB_CORES
    8989if( DEBUG_SYS_GET_NB_CORES < tm_end )
    90 printk("\n[%s] thread[%x,%x] exit / cycle %d\n",
    91 __FUNCTION__ , process->pid, this->trdid, (uint32_t)tm_end );
     90printk("\n[%s] thread[%x,%x] exit / ncores %d / cycle %d\n",
     91__FUNCTION__ , process->pid, this->trdid, k_ncores, (uint32_t)tm_end );
    9292#endif
    9393
  • trunk/kernel/syscalls/sys_lseek.c

    r457 r651  
    11/*
    2  * kern/sys_lseek.c - set the read/write offset of an opened file
     2 * kern/sys_lseek.c - Kernel function implementing the lseek system call.
    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,2018,2019)
     5s
     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 */
     
    3132#include <process.h>
    3233
    33 ////////////////////////////////
    34 int sys_lseek (uint32_t file_id,
    35                uint32_t offset,
    36                uint32_t whence )
     34/////////////////////////////////
     35int sys_lseek ( uint32_t file_id,
     36                uint32_t offset,
     37                uint32_t whence )
    3738{
    3839        error_t    error;
     
    4344        process_t * process = this->process;
    4445
     46#if (DEBUG_SYS_LSEEK || CONFIG_INSTRUMENTATION_SYSCALLS)
     47uint64_t     tm_start = hal_get_cycles();
     48#endif
     49
     50#if DEBUG_SYS_LSEEK
     51if( DEBUG_SYS_LSEEK < tm_start )
     52printk("\n[%s] thread[%x,%x] enter / file_id %d / offset %d / cycle %d\n",
     53__FUNCTION__, process->pid, this->trdid, file_id, offset, (uint32_t)tm_start );
     54#endif
     55
    4556    // check file_id argument
    4657        if( file_id >= CONFIG_PROCESS_FILE_MAX_NR )
    4758        {
    48         printk("\n[ERROR] in %s : illegal file descriptor index = %d\n",
    49                __FUNCTION__ , file_id );
     59
     60#if DEBUG_SYSCALLS_ERROR
     61printk("\n[ERROR] in %s : thread[%x,%x] illegal file descriptor index %d\n",
     62__FUNCTION__ , process->pid, this->trdid, file_id );
     63#endif
    5064                this->errno = EBADFD;
    5165                return -1;
     
    5771    if( file_xp == XPTR_NULL )
    5872    {
    59         printk("\n[ERROR] in %s : undefined file descriptor index = %d\n",
    60                __FUNCTION__ , file_id );
     73
     74#if DEBUG_SYSCALLS_ERROR
     75printk("\n[ERROR] in %s : thread[%x,%x] undefined fd_id %d\n",
     76__FUNCTION__, process->pid, this->trdid, file_id );
     77#endif
    6178                this->errno = EBADFD;
    6279                return -1;
    6380    }
    6481
    65         /* FIXME: file may be closed in parallel
    66          * of seek/read/write/mmap ..etc
    67          * so file may be NULL or invalid */
     82// FIXME: file may be closed in parallel of seek/read/write/mmap ..etc
    6883
    6984    // call relevant VFS function
     
    7287        if( error )
    7388        {
    74         printk("\n[ERROR] in %s : cannot seek file = %d\n",
    75                __FUNCTION__ , file_id );
     89
     90#if DEBUG_SYSCALLS_ERROR
     91printk("\n[ERROR] in %s : thread[%x,%x] cannot seek file_id %d\n",
     92__FUNCTION__, process->pid, this->trdid, file_id );
     93#endif
    7694                this->errno = error;
    7795                return -1;
    7896        }
     97
     98#if (DEBUG_SYS_LSEEK || CONFIG_INSTRUMENTATION_SYSCALLS)
     99uint64_t     tm_end = hal_get_cycles();
     100#endif
     101
     102#if DEBUG_SYS_LSEEK
     103if( DEBUG_SYS_LSEEK < tm_end )
     104printk("\n[%s] thread[%x,%x] exit / cycle %d\n",
     105__FUNCTION__ , process->pid, this->trdid, (uint32_t)tm_end );
     106#endif
     107
     108#if CONFIG_INSTRUMENTATION_SYSCALLS
     109hal_atomic_add( &syscalls_cumul_cost[SYS_LSEEK] , tm_end - tm_start );
     110hal_atomic_add( &syscalls_occurences[SYS_LSEEK] , 1 );
     111#endif
    79112 
    80113        return new_offset;
  • trunk/kernel/syscalls/sys_mmap.c

    r637 r651  
    112112    }
    113113
    114     // FIXME handle Copy_On_Write for MAP_PRIVATE...
     114// FIXME handle Copy_On_Write for MAP_PRIVATE...
    115115
    116116    // test mmap type : can be FILE / ANON / REMOTE
     
    127127#endif
    128128
    129             // FIXME: handle concurent delete of file by another thread
     129// FIXME: handle concurent delete of file by another thread
    130130
    131131                if( fdid >= CONFIG_PROCESS_FILE_MAX_NR )
     
    164164#endif
    165165
    166         // get inode pointer & mapper pointer
    167         vfs_inode_t * inode_ptr  = hal_remote_lpt(XPTR(file_cxy , &file_ptr->inode ));
     166        // get mapper pointer
    168167        mapper_t    * mapper_ptr = hal_remote_lpt(XPTR(file_cxy , &file_ptr->mapper));
    169168
    170         // get file size
    171                 uint32_t size = hal_remote_l32( XPTR( file_cxy , &inode_ptr->size ) );
    172 
    173 #if (DEBUG_SYS_MMAP & 1)
    174 if ( DEBUG_SYS_MMAP < tm_start )
    175 printk("\n[%s] thread[%x,%x] get file size : %d bytes\n",
    176 __FUNCTION__, process->pid, this->trdid, size );
    177 #endif
    178 
    179         // chek offset and length arguments
    180                 if( (offset + length) > size)
    181                 {
    182 
    183 #if DEBUG_SYSCALLS_ERROR
    184 printk("\n[ERROR] in %s: thread[%x,%x] / offset(%d) + len(%d) >= file's size(%d)\n",
    185 __FUNCTION__, process->pid, this->trdid, k_attr.offset, k_attr.length, size );
    186 #endif
    187             this->errno = ERANGE;
    188             return -1;
    189                 }
     169#if (DEBUG_SYS_MMAP & 1)
     170if ( DEBUG_SYS_MMAP < tm_start )
     171printk("\n[%s] thread[%x,%x] get file mapper %x\n",
     172__FUNCTION__, process->pid, this->trdid, mapper_ptr );
     173#endif
    190174
    191175/* TODO
  • trunk/kernel/syscalls/sys_thread_cancel.c

    r506 r651  
    101101    {
    102102        // block target thread and mark it for delete
    103         thread_delete( target_xp , pid , false );
     103        thread_delete( target_xp , false );              // not forced
    104104    }
    105105
  • trunk/kernel/syscalls/sys_thread_create.c

    r637 r651  
    154154        else                                        // set default attributes
    155155        {
    156         kern_attr.attributes = PT_ATTR_DETACH | PT_ATTR_CLUSTER_DEFINED;
     156        kern_attr.attributes = PT_ATTR_CLUSTER_DEFINED;
    157157        child_cxy = dqdt_get_cluster_for_thread( LOCAL_CLUSTER->dqdt_root_xp );
    158158        }
  • trunk/kernel/syscalls/sys_thread_exit.c

    r635 r651  
    3333#include <syscalls.h>
    3434
    35 ////////////////////////////////////////
    36 int sys_thread_exit( void * exit_value )
     35/////////////////////////////////////////
     36int sys_thread_exit( void * exit_status )
    3737{
     38    error_t     error;
     39    vseg_t    * vseg;
     40
    3841        thread_t  * this      = CURRENT_THREAD;
    3942    trdid_t     trdid     = this->trdid;
    4043    process_t * process   = this->process;
    4144    pid_t       pid       = process->pid;
     45   
     46    // check exit_value pointer in user space if required
     47    if( exit_status != NULL )
     48    {
     49        error = vmm_get_vseg( process , (intptr_t)exit_status  , &vseg );
    4250
    43     // check exit_value argument
    44     if( exit_value != NULL )
    45     {
     51        if( error )
     52            {
    4653
    4754#if DEBUG_SYSCALLS_ERROR
    48 printk("\n[ERROR] in %s : thread[%x,%x] / exit_value argument %x must be NULL\n",
    49 __FUNCTION__ , pid, trdid , exit_value );
     55printk("\n[ERROR] in %s : exit_status buffer %x unmapped / thread[%x,%x]\n",
     56__FUNCTION__, (intptr_t)exit_status, process->pid, this->trdid );
    5057#endif
    51         this->errno = EINVAL;
    52         return -1;
     58            this->errno = EINVAL;
     59                return -1;
     60        }
     61    }
     62
     63        // check busylocks
     64    uint32_t count = this->busylocks;
     65        if( count )
     66        {
     67
     68#if DEBUG_SYSCALLS_ERROR
     69printk("\n[ERROR] in %s : busylocks count = %d  / thread[%x,%x]\n",
     70__FUNCTION__ , count, process->pid, this->trdid );
     71#endif
     72            this->errno = EINVAL;
     73                return -1;
    5374    }
    5475
    5576    // If calling thread is the main thread, the process must be deleted.
    56     // => delete all process threads and synchronise with parent process.
    57     // If calling thread is not the main thread, it must be deleted.
    58     // => block the thread and mark it for delete.
    59     if( (CXY_FROM_PID( pid ) == local_cxy) && (LTID_FROM_TRDID(trdid) == 0) )
     77    // => delete all process threads and synchronize with parent process.
     78    // If calling thread is not the main thread, only this thread must be deleted.
     79    // => register exit_status in thread descriptor, block the thread,
     80    //    mark it for delete, and synchronize with joining thread.
     81
     82    if( (CXY_FROM_PID( pid ) == local_cxy) && (LTID_FROM_TRDID(trdid) == 0) )  // main
    6083    {
    6184
     
    6992        sys_exit( 0 );
    7093    }
    71     else
     94    else                                                             // not the main
    7295    {
    7396
     
    78101__FUNCTION__ , pid , trdid , (uint32_t)tm_start );
    79102#endif
     103        // register exit_status in thread descriptor
     104        this->exit_status = exit_status;
     105
    80106        // block calling thread and mark it for delete,
    81         thread_delete( XPTR( local_cxy , this ) , pid , false );
     107        thread_delete( XPTR( local_cxy , this ) , false );   // not forced
    82108
    83109        // deschedule
  • trunk/kernel/syscalls/sys_thread_join.c

    r637 r651  
    11/*
    2  * sys_thread_join.c - passive wait on the end of a given thread.
     2 * sys_thread_join.c - wait termination of of an attached thread.
    33 *
    44 * Authors    Alain Greiner (2016,2017,2018,2019)
     
    2626#include <hal_special.h>
    2727#include <hal_irqmask.h>
     28#include <hal_uspace.h>
    2829#include <thread.h>
    2930#include <vmm.h>
     
    3738///////////////////////////////////////
    3839int sys_thread_join ( trdid_t    trdid,
    39                       void    ** exit_value )
     40                      void    ** exit_status )
    4041{
     42    error_t       error;
    4143    reg_t         save_sr;
    4244    xptr_t        target_xp;
     
    4749    xptr_t        target_flags_xp;
    4850    xptr_t        target_join_xp_xp;
     51    xptr_t        target_exit_status_xp;
    4952    xptr_t        killer_xp;
    5053    xptr_t        joining_xp;
    5154    thread_t    * joining_ptr;
    5255    process_t   * process;
     56    vseg_t      * vseg;
     57    void        * status;
    5358
    5459    // get joining thread pointers
     
    6267
    6368#if DEBUG_SYS_THREAD_JOIN
    64 uint64_t     tm_start;
    65 uint64_t     tm_end;
    66 tm_start = hal_get_cycles();
     69uint64_t  tm_start = hal_get_cycles();
    6770if( DEBUG_SYS_THREAD_JOIN < tm_start )
    68 printk("\n[DBG] %s : joining thread[%x,%x] enter / target thread[%x,%x] / cycle %d\n",
     71printk("\n[%s] joining thread[%x,%x] enter / target thread[%x,%x] / cycle %d\n",
    6972__FUNCTION__ , process->pid, joining_ptr->trdid,
    7073process->pid, trdid, (uint32_t)tm_start );
     
    7780
    7881#if DEBUG_SYSCALLS_ERROR
    79 printk("\n[ERROR] in %s : illegal trdid argument %x\n",
    80 __FUNCTION__, trdid );
     82printk("\n[ERROR] in %s : illegal trdid argument %x / joining thread[%x,%x]\n",
     83__FUNCTION__, trdid, joining_ptr->process->pid, joining_ptr-trdid );
    8184#endif
    8285                joining_ptr->errno = EINVAL;
     
    8487        }
    8588
    86     // check exit_value argument
    87         if( exit_value != NULL )
     89    // check exit_value argument in user space
     90    error = vmm_get_vseg( process , (intptr_t)exit_status  , &vseg );
     91        if( error )
    8892        {
    8993
    9094#if DEBUG_SYSCALLS_ERROR
    91 printk("\n[ERROR] in %s : exit_value argument must be NULL\n",
    92 __FUNCTION__ );
     95printk("\n[ERROR] in %s : exit_status argument %x not mapped / joining thread[%x,%x]\n",
     96__FUNCTION__, exit_status, joining_ptr->process->pid, joining_ptr-trdid );
    9397#endif
    9498                joining_ptr->errno = EINVAL;
     
    101105
    102106#if DEBUG_SYSCALLS_ERROR
    103 printk("\n[ERROR] in %s : this thread (%x) == target thread(%x)\n",
    104 __FUNCTION__, joining_ptr->trdid, trdid );
     107printk("\n[ERROR] in %s : joinig thread[%x,%x] == target thread\n",
     108__FUNCTION__, joining_ptr->process->pid, joining_ptr->trdid );
    105109#endif
    106110        joining_ptr->errno = EDEADLK;
     
    116120
    117121#if DEBUG_SYSCALLS_ERROR
    118 printk("\n[ERROR] in %s : target thread %x not found\n",
    119 __FUNCTION__, trdid );
     122printk("\n[ERROR] in %s : target thread[%x,%x] not found / joining_thread[%x,%x]\n",
     123__FUNCTION__, process->pid, trdid, joining_ptr->process->pid, joining_ptr-trdid );
    120124#endif
    121125        joining_ptr->errno = ESRCH;
     
    124128
    125129    // get extended pointers on various fields in target thread
    126     target_join_lock_xp = XPTR( target_cxy , &target_ptr->join_lock );
    127     target_flags_xp     = XPTR( target_cxy , &target_ptr->flags );
    128     target_join_xp_xp   = XPTR( target_cxy , &target_ptr->join_xp );
     130    target_join_lock_xp   = XPTR( target_cxy , &target_ptr->join_lock );
     131    target_flags_xp       = XPTR( target_cxy , &target_ptr->flags );
     132    target_join_xp_xp     = XPTR( target_cxy , &target_ptr->join_xp );
     133    target_exit_status_xp = XPTR( target_cxy , &target_ptr->exit_status );
    129134
    130135    // check target thread joinable
     
    133138
    134139#if DEBUG_SYSCALLS_ERROR
    135 printk("\n[ERROR] in %s : target thread %x not joinable\n", __FUNCTION__, trdid );
     140printk("\n[ERROR] in %s : target thread[%x,‰x] not attached / joining thread[%x,%x]\n",
     141__FUNCTION__, process->pid, trdid, joining_ptr->process->pid, joining_ptr-trdid );
    136142#endif
    137143        joining_ptr->errno = EINVAL;
     
    146152
    147153    // test the kill_done flag from the target thread
    148     if( hal_remote_l32( target_flags_xp ) & THREAD_FLAG_KILL_DONE )  // killer thread is first
    149     {
     154    if( hal_remote_l32( target_flags_xp ) & THREAD_FLAG_KILL_DONE )  // killer is first
     155    {
     156        // get exit_status from target thread
     157        status = (void*)hal_remote_lpt( target_exit_status_xp );
     158
    150159        // get pointers on killer thread
    151160        killer_xp  = (xptr_t)hal_remote_l64( target_join_xp_xp );
     
    159168        // release the lock protecting join     
    160169        remote_busylock_release( target_join_lock_xp );
    161 
    162 #if DEBUG_SYS_THREAD_JOIN
    163 tm_end = hal_get_cycles();
    164 if( DEBUG_SYS_THREAD_JOIN < tm_end )
    165 printk("\n[DBG] %s : joining thread[%x,%x] exit / target thread[%x,%x] completed / cycle %d\n",
    166 __FUNCTION__, process->pid, joining_ptr->trdid, process->pid, trdid, (uint32_t)tm_end );
    167 #endif
    168 
    169     }
    170     else                                                          // joining thread is first
     170    }
     171    else                                                          // joining is first
    171172    {
    172173        // set the join_done flag in target thread
     
    184185#if DEBUG_SYS_THREAD_JOIN
    185186if( DEBUG_SYS_THREAD_JOIN < tm_start )
    186 printk("\n[DBG] %s : joining thread[%x,%x] deschedules / target thread[%x,%x] not completed\n",
     187printk("\n[%s] joining thread[%x,%x] deschedules / target thread[%x,%x] not completed\n",
    187188__FUNCTION__ , process->pid, joining_ptr->trdid, process->pid, trdid );
    188189#endif
    189190        // deschedule
    190191        sched_yield( "joining thread waiting killer thread" );
     192
     193        // returns exit_status from joining thread
     194        status = joining_ptr->exit_status;
     195    }
    191196   
     197    // returns exit_status to user space
     198    hal_copy_to_uspace( exit_status,
     199                        XPTR( local_cxy , &status ),
     200                        sizeof( void* ) );
     201
     202    // restore IRQs
     203    hal_restore_irq( save_sr );
     204
     205    hal_fence();
     206
     207#if (DEBUG_SYS_THREAD_JOIN || CONFIG_INSTRUMENTATION_SYSCALLS)
     208uint64_t     tm_end = hal_get_cycles();
     209#endif
     210
     211#if CONFIG_INSTRUMENTATION_SYSCALLS
     212hal_atomic_add( &syscalls_cumul_cost[SYS_THREAD_JOIN] , tm_end - tm_start );
     213hal_atomic_add( &syscalls_occurences[SYS_THREAD_JOIN] , 1 );
     214#endif
     215
    192216#if DEBUG_SYS_THREAD_JOIN
    193217tm_end = hal_get_cycles();
    194218if( DEBUG_SYS_THREAD_JOIN < tm_end )
    195 printk("\n[DBG] %s : joining thread[%x,%x] exit / target thread[%x,%x] completed / cycle %d\n",
     219printk("\n[%s] joining thread[%x,%x] exit / target thread[%x,%x] completed / cycle %d\n",
    196220__FUNCTION__ , process->pid, joining_ptr->trdid, process->pid, trdid, (uint32_t)tm_end );
    197221#endif
    198222
    199     }
    200 
    201     // restore IRQs
    202     hal_restore_irq( save_sr );
    203 
    204223    return 0;
    205224
  • trunk/kernel/syscalls/syscalls.h

    r642 r651  
    3737
    3838/******************************************************************************************
    39  * [0] This function terminates the execution of the calling user thread,
    40  * and makes the exit_value pointer available to any successful pthread_join() with the
     39 * [0] This function terminates the execution of the calling user thread, and makes
     40 * the <exit_status> pointer available to any successful pthread_join() with the
    4141 * terminating thread.
    42  * It actually set the THREAD_SIG_EXIT signal, set the THREAD_BLOCKED_GLOBAL bit in the
    43  * thread descriptor and deschedule.
    44  * The thread will be detached from its process, and the memory allocated to the thread
    45  * descriptor will be released later by the scheduler.
    46  ******************************************************************************************
    47  * @ exit_vallue  : pointer to be returned to joining thread if thread is attached.
     42 * - If the calling thread is the main thread, it calls the sys_exit() function to delete
     43 *   completely the user process. 
     44 * - if the calling thread is not the main thread, it registers the <exit_status> pointer
     45 *   in the thread descriptor, and calls the thread_delete() function, that will set the
     46 *   THREAD_SIG_EXIT signal, set the THREAD_BLOCKED_GLOBAL bit in thread descriptor, and
     47 *   deschedules. All memory allocated to the thread is released later by the scheduler.
     48 *   If the thread is in "detached" mode, the thread_delete() function implements
     49 *   the synchonisation with the joining thread.
     50 ******************************************************************************************
     51 * @ exit_status  : pointer to be returned to joining thread if thread is attached.
    4852 * @ return 0 if success / return -1 if all locks not released or illegal argument.
    4953 *****************************************************************************************/
    50 int sys_thread_exit( void * exit_value );
     54int sys_thread_exit( void * exit_status );
    5155
    5256/******************************************************************************************
     
    222226 ******************************************************************************************
    223227 * @ attr       : pointer on attributes structure.
    224  * @ return 0 if success / return -1 if failure.
     228 * @ returns 0 if success / returns -1 if failure.
    225229 *****************************************************************************************/
    226230int sys_mmap( mmap_attr_t * attr );
     
    234238 * @ buf      : buffer virtual address in user space.
    235239 * @ count    : number of bytes.
    236  * @ return number of bytes actually read if success / returns -1 if failure.
     240 * @ returns number of bytes actually read if success / returns -1 if failure.
    237241 *****************************************************************************************/
    238242int sys_read( uint32_t   file_id,
     
    251255 * @ buf      : buffer virtual address in user space.
    252256 * @ count    : number of bytes.
    253  * @ return number of bytes actually written if success / returns -1 if failure.
     257 * @ returns number of bytes actually written if success / returns -1 if failure.
    254258 *****************************************************************************************/
    255259int sys_write( uint32_t   file_id,
     
    258262
    259263/******************************************************************************************
    260  * [16] This function repositions the offset of the file descriptor identified by <file_id>,
    261  * according to the operation type defined by the <whence> argument.
     264 * [16] This function repositions the offset of the file descriptor identified by the
     265 * <file_id> argument, according to the operation type defined by the <whence> argument.
    262266 ******************************************************************************************
    263267 * @ file_id  : open file index in fd_array.
    264268 * @ offset   : used to compute new offset value.
    265269 * @ whence   : operation type (see below).
    266  * @ return 0 if success / returns -1 if failure.
     270 * @ returns new offset value if success / returns -1 if failure.
    267271 *****************************************************************************************/
    268272int sys_lseek( xptr_t    file_id,
     
    276280 ******************************************************************************************
    277281  file_id   : file descriptor index in fd_array.
    278  * @ return 0 if success / returns -1 if failure.
     282 * @ returns 0 if success / returns -1 if failure.
    279283 *****************************************************************************************/
    280284int sys_close( uint32_t file_id );
     
    289293 ******************************************************************************************
    290294 * @ pathname   : pathname (can be relative or absolute).
    291  * @ return 0 if success / returns -1 if failure.
     295 * @ returns 0 if success / returns -1 if failure.
    292296 *****************************************************************************************/
    293297int sys_unlink( char * pathname );
Note: See TracChangeset for help on using the changeset viewer.