Changeset 670 for trunk/kernel


Ignore:
Timestamp:
Nov 19, 2020, 11:45:52 PM (3 years ago)
Author:
alain
Message:

1) Introduce up to 4 command lines arguments in the KSH "load" command.
These arguments are transfered to the user process through the
argc/argv mechanism, using the user space "args" vseg.

2) Introduce the named and anonymous "pipes", for inter-process communication
through the pipe() and mkfifo() syscalls.

3) Introduce the "chat" application to validate the two above mechanisms.

4) Improve printk() and assert() fonctions in printk.c.

Location:
trunk/kernel/syscalls
Files:
31 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/syscalls/shared_include/shared_almos.h

    r664 r670  
    5656    DISPLAY_FAT               = 11,
    5757    DISPLAY_SOCKET            = 12,
     58    DISPLAY_FD                = 13,
     59    DISPLAY_WINDOWS           = 14,
    5860}
    5961display_type_t;
  • trunk/kernel/syscalls/shared_include/shared_fbf.h

    r657 r670  
    11/*
    2  * shared_fbf.h - Shared mnemonics used by the frame buffer related syscalls.
     2 * shared_fbf.h - Shared mnemonics used by the Frame Buffer related syscalls.
    33 *
    44 * Author  Alain Greiner (2016,2017,2018,2019,2020)
     
    3535    FBF_DIRECT_WRITE   = 2,
    3636    FBF_CREATE_WINDOW  = 3,
    37     FBF_DELETE_WINDOW  = 4,
    38     FBF_REFRESH_WINDOW = 5,
    39     FBF_MOVE_WINDOW    = 6,
    40     FBF_RESIZE_WINDOW  = 7,
     37    FBF_ACTIVE_WINDOW  = 4,
     38    FBF_DELETE_WINDOW  = 5,
     39    FBF_REFRESH_WINDOW = 6,
     40    FBF_FRONT_WINDOW   = 7,
     41    FBF_MOVE_WINDOW    = 8,
     42    FBF_RESIZE_WINDOW  = 9,
    4143}
    4244fbf_usr_operation_type_t;
  • trunk/kernel/syscalls/shared_include/shared_socket.h

    r664 r670  
    6969    SOCK_SEND        = 5,
    7070    SOCK_RECV        = 6,
    71     SOCK_SENDTO      = 7,
    72     SOCK_RECVFROM    = 8,
    7371}
    7472socket_operation_type_t;
  • trunk/kernel/syscalls/shared_include/shared_stat.h

    r611 r670  
    2828 * This structure define the informations associated to a file descriptor,
    2929 * returned to user space by the stat() syscall.
     30 *
     31 * The st_mode field contains informations on both access rights and file types.
     32 * - access rights (defined by the inode <rights> field) are stored in st_mode[15:0]
     33 * - file types (defined by the inode <type> field) are stored in st_mode[19:16]
    3034 *****************************************************************************************/
    3135
     
    4549
    4650/******************************************************************************************
    47  * The st_mode field contains informations on both access rights and file types.
    48  * - access rights (defined by the inode <rights> field) are stored in st_mode[15:0]
    49  * - file types (defined by the inode <type> field) are stored in st_mode[19:16]
    5051 * The following macros can be used to extract file type information.
    5152 *
  • trunk/kernel/syscalls/sys_barrier.c

    r637 r670  
    3333#include <remote_barrier.h>
    3434
    35 //////////////////////////////////////////////////////
    36 static char * sys_barrier_op_str( uint32_t operation )
    37 {
    38         if     ( operation == BARRIER_INIT    ) return "INIT";
    39         else if( operation == BARRIER_DESTROY ) return "DESTROY";
    40         else if( operation == BARRIER_WAIT    ) return "WAIT";
    41         else                                    return "undefined";
    42 }
    43 
    4435//////////////////////////////////
    4536int sys_barrier( intptr_t   vaddr,
     
    5546    process_t * process = this->process;
    5647
    57 #if (DEBUG_SYS_BARRIER || CONFIG_INSTRUMENTATION_SYSCALLS)
     48#if DEBUG_SYS_BARRIER || DEBUG_SYSCALLS_ERROR || CONFIG_INSTRUMENTATION_SYSCALLS
    5849uint64_t     tm_start = hal_get_cycles();
    5950#endif
     
    7263
    7364#if DEBUG_SYSCALLS_ERROR
     65if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
    7466printk("\n[ERROR] in %s for %s : unmapped barrier %x / thread[%x,%x]\n",
    7567__FUNCTION__, sys_barrier_op_str(operation), vaddr, process->pid, this->trdid );
     
    9284
    9385#if DEBUG_SYSCALLS_ERROR
     86if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
    9487printk("\n[ERROR] in %s for INIT : unmapped barrier attributes %x / thread[%x,%x]\n",
    9588__FUNCTION__ , attr , process->pid , this->trdid );
     
    108101
    109102#if DEBUG_SYSCALLS_ERROR
     103if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
    110104printk("\n[ERROR] in %s for INIT : count (%d) != x_size (%d) * y_size (%d) * nthreads (%x)\n",
    111105__FUNCTION__, count, k_attr.x_size, k_attr.y_size, k_attr.nthreads );
     
    128122
    129123#if DEBUG_SYSCALLS_ERROR
     124if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
    130125printk("\n[ERROR] in %s for INIT : cannot create barrier %x / thread[%x,%x]\n",
    131126__FUNCTION__ , vaddr , process->pid , this->trdid );
     
    145140
    146141#if DEBUG_SYSCALLS_ERROR
     142if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
    147143printk("\n[ERROR] in %s for WAIT : barrier %x not registered / thread[%x,%x]\n",
    148144__FUNCTION__ , (intptr_t)vaddr , process->pid, this->trdid );
     
    166162
    167163#if DEBUG_SYSCALLS_ERROR
     164if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
    168165printk("\n[ERROR] in %s for DESTROY : barrier %x not registered / thread[%x,%x]\n",
    169166__FUNCTION__ , (intptr_t)vaddr , process->pid, this->trdid );
     
    181178        default:
    182179        {
    183             assert ( false, "illegal operation type <%x>", operation );
     180            assert( __FUNCTION__, false, "illegal operation type <%x>", operation );
    184181        }
    185182        }  // end switch
  • trunk/kernel/syscalls/sys_chdir.c

    r637 r670  
    4646    process_t * process = this->process;
    4747
    48 #if (DEBUG_SYS_CHDIR || CONFIG_INSTRUMENTATION_SYSCALLS)
     48#if DEBUG_SYS_CHDIR || DEBUG_SYSCALLS_ERROR || CONFIG_INSTRUMENTATION_SYSCALLS
    4949uint64_t     tm_start = hal_get_cycles();
    5050#endif
     
    5555
    5656#if DEBUG_SYSCALLS_ERROR
     57if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
    5758printk("\n[ERROR] in %s : pathname too long / thread[%x,%x]\n",
    5859__FUNCTION__, process->pid, this->trdid );
     
    6768
    6869#if DEBUG_SYSCALLS_ERROR
     70if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
    6971printk("\n[ERROR] in %s : user buffer unmapped %x for thread[%x,%x]\n",
    7072__FUNCTION__ , (intptr_t)pathname , process->pid, this->trdid );
     
    8082
    8183#if DEBUG_SYS_CHDIR
    82 if( DEBUG_SYS_CHDIR < tm_start )
     84if( DEBUG_SYS_CHDIR < (uint32_t)tm_start )
    8385printk("\n[%s] thread[%x,%x] enter for <%s> / cycle %d\n",
    8486__FUNCTION__, process->pid, this->trdid, kbuf, (uint32_t)tm_start );
     
    109111
    110112#if DEBUG_SYSCALLS_ERROR
     113if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
    111114printk("\n[ERROR] in %s / thread[%x,%x] : cannot change CWD\n",
    112115__FUNCTION__ , process->pid , this->trdid );
  • trunk/kernel/syscalls/sys_chmod.c

    r637 r670  
    22 * sys_chmod.c - Change file access rights.
    33 *
    4  * Author    Alain Greiner  (2016,2017,2018,2019)
     4 * Author       Alain Greiner  (2016,2017,2018,2019,2020)
    55 *
    66 * Copyright (c) 2015 UPMC Sorbonne Universites
     
    2929#include <thread.h>
    3030#include <process.h>
    31 
    3231#include <syscalls.h>
    3332
     
    3635               uint32_t   rights __attribute__((unused)) )
    3736{
    38     error_t     error;
    3937    char        kbuf[CONFIG_VFS_MAX_PATH_LENGTH];
    4038
    4139    thread_t  * this    = CURRENT_THREAD;
    42     process_t * process = this->process;
     40
     41#if DEBUG_SYS_CHMOD || DEBUG_SYSCALLS_ERROR || CONFIG_INSTRUMENTATION_SYSCALLS
     42process_t * process  = this->process;
     43uint64_t    tm_start = hal_get_cycles();
     44#endif
    4345
    4446    // check pathname length
     
    4749
    4850#if DEBUG_SYSCALLS_ERROR
    49 printk("\n[ERROR] in %s : pathname too long / thread %x in process %x\n",
     51if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     52printk("\n[ERROR] in %s : thread[%x,%x] / pathname too long\n",
    5053__FUNCTION__, this->trdid, process->pid );
    5154#endif
     
    5962                            CONFIG_VFS_MAX_PATH_LENGTH );
    6063
     64
     65
     66
    6167    printk("\n[ERROR] in %s : not implemented yet\n", __FUNCTION__ );
    6268    return -1;
    6369
    64     // get cluster and local pointer on reference process
    65     // xptr_t      ref_xp  = process->ref_xp;
    66     // process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
    67     // cxy_t       ref_cxy = GET_CXY( ref_xp );
    6870
    69     // call the relevant VFS function
    70     // error = vfs_chmod( cwd_xp,
    71     //                    kbuf,
    72     //                    rights );
    7371
    74     if( error )
    75     {
    76         printk("\n[ERROR] in %s : cannot remove directory %s\n",
    77         __FUNCTION__ , kbuf );
    78         this->errno = error;
    79         return -1;
    80     }
     72
     73    hal_fence();
     74
     75#if (DEBUG_SYS_CHMOD || CONFIG_INSTRUMENTATION_SYSCALLS)
     76uint64_t     tm_end = hal_get_cycles();
     77#endif
     78
     79#if DEBUG_SYS_CHMOD
     80if( DEBUG_SYS_CHMOD < tm_end )
     81printk("\n[%s] thread[%x,%x] exit for / cycle %d\n",
     82__FUNCTION__, process->pid, this->trdid, (uint32_t)tm_end );
     83#endif
     84 
     85#if CONFIG_INSTRUMENTATION_SYSCALLS
     86hal_atomic_add( &syscalls_cumul_cost[SYS_CHMOD] , tm_end - tm_start );
     87hal_atomic_add( &syscalls_occurences[SYS_CHMOD] , 1 );
     88#endif
    8189
    8290    return 0;
  • trunk/kernel/syscalls/sys_close.c

    r664 r670  
    11/*
    2  * sys_close.c  close an open file
     2 * sys_close.c  kernel function implementing the <close> syscall
    33 *
    4  * Author    Alain Greiner (2016,2017,2018,2019,2020)
     4 * Author       Alain Greiner (2016,2017,2018,2019,2020)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    4040    cxy_t              file_cxy;
    4141    vfs_file_t       * file_ptr;
    42     vfs_inode_type_t   file_type;
     42    vfs_file_type_t   file_type;
    4343
    4444        thread_t  * this    = CURRENT_THREAD;
    4545        process_t * process = this->process;
    4646
    47 #if (DEBUG_SYS_CLOSE || CONFIG_INSTRUMENTATION_SYSCALLS)
     47#if DEBUG_SYS_CLOSE || DEBUG_SYSCALLS_ERROR || CONFIG_INSTRUMENTATION_SYSCALLS
    4848uint64_t     tm_start = hal_get_cycles();
    4949#endif
    5050
    5151#if DEBUG_SYS_CLOSE
    52 if( DEBUG_SYS_CLOSE < tm_start )
     52if( DEBUG_SYS_CLOSE < (uint32_t)tm_start )
    5353printk("\n[%s] thread[%x,%x] enter / fdid %d / cycle %d\n",
    5454__FUNCTION__, process->pid, this->trdid, fdid, (uint32_t)tm_start );
     
    6060
    6161#if DEBUG_SYSCALLS_ERROR
    62 printk("\n[ERROR] in %s : illegal file descriptor index = %d\n",
    63 __FUNCTION__ , fdid );
     62if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     63printk("\n[ERROR] in %s : thread[%x,%x] / illegal file descriptor index = %d\n",
     64__FUNCTION__ , process->pid , this->trdid , fdid );
    6465#endif
    6566                this->errno = EBADFD;
     
    7475
    7576#if DEBUG_SYSCALLS_ERROR
    76 printk("\n[ERROR] in %s : undefined file descriptor %d\n",
    77 __FUNCTION__ , fdid );
     77if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     78printk("\n[ERROR] in %s : thread[%x,%x] / undefined file descriptor %d\n",
     79__FUNCTION__ , process->pid , this->trdid , fdid );
    7880#endif
    7981        this->errno = EBADFD;
     
    8688    file_type = hal_remote_l32( XPTR( file_cxy , &file_ptr->type ) );
    8789
    88     if( file_type == INODE_TYPE_DIR )
     90    if( file_type == FILE_TYPE_DIR )
    8991        {
    9092
    9193#if DEBUG_SYSCALLS_ERROR
    92 printk("\n[ERROR] in %s : file descriptor %d is a directory\n",
    93 __FUNCTION__ , fdid );
     94if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     95printk("\n[ERROR] in %s : thread[%x,%x] / file descriptor %d is a directory\n",
     96__FUNCTION__ , process->pid , this->trdid , fdid );
    9497#endif
    9598                this->errno = EBADFD;
    9699                return -1;
    97100        }
    98     else if( file_type == INODE_TYPE_SOCK )
     101    else if( file_type == FILE_TYPE_SOCK )
    99102    {
    100103        // call the relevant socket function
    101104        error = socket_close( file_xp , fdid );
    102105    }
    103     else if( file_type == INODE_TYPE_FILE )
     106    else if( (file_type == FILE_TYPE_REG) ||
     107             (file_type == FILE_TYPE_FIFO) )
    104108    {
    105109        // call the relevant VFS function
     
    110114           
    111115#if DEBUG_SYSCALLS_ERROR
    112 printk("\n[WARNING] in %s : type (%d) not supported  / fdid %d\n",
    113 __FUNCTION__ , file_type , fdid );
     116if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     117printk("\n[WARNING] in %s : thread[%x,%x] / file_type (%s) unsupported / fdid %d\n",
     118__FUNCTION__ , process->pid , this->trdid , vfs_inode_type_str(file_type) , fdid );
    114119#endif
    115120        error = 0;       
     
    120125
    121126#if DEBUG_SYSCALLS_ERROR
    122 printk("\n[ERROR] in %s : cannot close file descriptor %d\n",
    123 __FUNCTION__ , fdid );
     127if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     128printk("\n[ERROR] in %s : thread[%x,%x] cannot close file descriptor %d\n",
     129__FUNCTION__ , process->pid , this->trdid , fdid );
    124130#endif
    125131                this->errno = error;
  • trunk/kernel/syscalls/sys_closedir.c

    r614 r670  
    22 * sys_closedir.c - Close an open VFS directory.
    33 *
    4  * Author    Alain Greiner  (2016,2017,2018)
     4 * Author    Alain Greiner  (2016,2017,2018,2019,20120)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    3737{
    3838    xptr_t         dir_xp;       // extended pointer on user_dir_t structure
    39     user_dir_t   * dir_ptr;      // lcal pointer on user_dir_t structure
     39    user_dir_t   * dir_ptr;      // local pointer on user_dir_t structure
    4040    cxy_t          dir_cxy;      // cluster identifier (inode cluster)
    4141
     
    4343        process_t * process = this->process;   // client process
    4444
    45 #if (DEBUG_SYS_CLOSEDIR || CONFIG_INSTRUMENTATION_SYSCALLS)
     45#if DEBUG_SYS_CLOSEDIR || DEBUG_SYSCALLS_ERROR || CONFIG_INSTRUMENTATION_SYSCALLS
    4646uint64_t     tm_start = hal_get_cycles();
    4747#endif
     
    6060
    6161#if DEBUG_SYSCALLS_ERROR
    62 printk("\n[ERROR] in %s / thread[%x,%x] : DIR pointer %x not registered\n",
     62if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     63printk("\n[ERROR] in %s : thread[%x,%x] / DIR pointer %x not registered\n",
    6364__FUNCTION__ , process->pid , this->trdid, dirp );
    6465#endif
     
    6768        }       
    6869
    69     // get cluster and localpointer for user_dir_t structure
     70    // get cluster and local pointer for user_dir_t structure
    7071    dir_ptr = GET_PTR( dir_xp );
    7172    dir_cxy = GET_CXY( dir_xp );
  • trunk/kernel/syscalls/sys_condvar.c

    r635 r670  
    209209                }
    210210        /////////
    211         default: {
    212             assert ( false, "illegal operation type <%x>\n", operation );
     211        default:
     212        {
     213            assert( __FUNCTION__, false, "illegal operation type <%x>\n", operation );
    213214        }
    214215        }   // end switch
  • trunk/kernel/syscalls/sys_display.c

    r664 r670  
    5858    else if( type == DISPLAY_FAT               ) return "FAT";
    5959    else if( type == DISPLAY_SOCKET            ) return "SOCKET";
     60    else if( type == DISPLAY_FD                ) return "FD";
     61    else if( type == DISPLAY_WINDOWS           ) return "WINDOWS";
    6062    else                                         return "undefined";
    6163}
     
    500502
    501503#if DEBUG_SYSCALLS_ERROR
    502 printk("\n[ERROR] in %s SOCKET : pid %x not found\n", __FUNCTION__ , pid );
     504printk("\n[ERROR] in %s for SOCKET : pid %x not found\n", __FUNCTION__ , pid );
    503505#endif
    504506                this->errno = EINVAL;
     
    513515
    514516#if DEBUG_SYSCALLS_ERROR
    515 printk("\n[ERROR] in %s SOCKET : fdid %d not found\n", __FUNCTION__ , fdid );
     517printk("\n[ERROR] in %s for SOCKET : fdid %d not found\n", __FUNCTION__ , fdid );
    516518#endif
    517519                this->errno = EINVAL;
     
    528530            // display socket descriptor on TXT0
    529531            socket_display( XPTR( file_cxy , socket ), NULL );
     532
     533            break;
     534        }
     535        ////////////////
     536        case DISPLAY_FD:
     537        {
     538            pid_t   pid   = (pid_t)arg0;
     539
     540            // get extended pointer on owner process descriptor
     541            xptr_t owner_xp = cluster_get_owner_process_from_pid( pid );
     542
     543            if( owner_xp == XPTR_NULL )
     544            {
     545
     546#if DEBUG_SYSCALLS_ERROR
     547printk("\n[ERROR] in %s for FD : pid %x not found\n", __FUNCTION__ , pid );
     548#endif
     549                this->errno = EINVAL;
     550                return -1;
     551            }
     552
     553            // display fd_array on TXT0
     554            process_fd_display( owner_xp );
     555
     556            break;
     557        }
     558        /////////////////////
     559        case DISPLAY_WINDOWS:
     560        {
     561            pid_t   pid   = (pid_t)arg0;
     562
     563            if( pid != 0 )  // only one target process
     564            {
     565                // get extended pointer on owner process descriptor
     566                xptr_t owner_xp = cluster_get_owner_process_from_pid( pid );
     567
     568                if( owner_xp == XPTR_NULL )
     569                {
     570
     571#if DEBUG_SYSCALLS_ERROR
     572printk("\n[ERROR] in %s for FD : pid %x not found\n", __FUNCTION__ , pid );
     573#endif
     574                    this->errno = EINVAL;
     575                    return -1;
     576                }
     577            }
     578
     579            // display windows state for one, or for all processes
     580            dev_fbf_display_windows( pid );
    530581
    531582            break;
  • trunk/kernel/syscalls/sys_exec.c

    r637 r670  
    22 * sys_exec.c - Kernel function implementing the "exec" system call.
    33 *
    4  * Authors   Alain Greiner (2016,2017,2017,2019)
     4 * Authors   Alain Greiner (2016,2017,2017,2019,2020)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    3838#include <syscalls.h>
    3939
    40 ////////////////////////////////////////////////i//////////////////////////////////////
    41 // This static function is called twice by the sys_exec() function :
    42 // - to register the main() arguments (args) in the exec_info structure.
    43 // - to register the environment variables (envs) in the exec_info structure.
    44 // In both cases the input is an array of string pointers in user space,
    45 // and a set of strings in user space.
    46 // We allocate one physical page to store a kernel copy of the array of pointers,
    47 // we allocate one or several physical pages to store the strings themselve,
    48 // and register these buffers and the number of strings in the exec_info structure.
    49 // The max number of strings is 1024 (for both args and envs). The numbers of pages
    50 // to store the (args) and (envs) strings are configuration parameters.
    51 ///////////////////////////////////////////////////////////////////////////////////////
    52 // @ exec_info   : pointer on the exec_info structure.
    53 // @ is_args     : true if called for (args) / false if called for (envs).
    54 // @ u_pointers  : array of pointers on the strings (in user space).
    55 // @ return 0 if success / non-zero if too many strings or no more memory.
    56 ///////////////////////////////////////////////////////////////////////////////////////
    57 static error_t process_exec_get_strings( exec_info_t  * exec_info,
    58                                          bool_t         is_args,
    59                                          char        ** u_pointers )
     40///////////////////////////////
     41int sys_exec( char  * pathname,       // .elf file pathname in user space
     42              char ** user_args,      // pointer on process arguments in user space
     43              char ** user_envs )     // pointer on env variables in user space
    6044{
    61     uint32_t     index;       // string index
    62     uint32_t     found_null;  // NULL pointer found in array of pointers
    63     uint32_t     length;      // string length
    64     kmem_req_t   req;         // kmem request
    65     uint32_t     order;       // ln2( number of pages to store strings )
    66     char      ** k_pointers;  // base of kernel array of pointers
    67     char       * k_buf_base;  // base address of the kernel strings buffer
    68     char       * k_buf_ptr;   // pointer on first empty slot in kernel strings buffer
    69 
    70     // compute ln2( number of pages for kernel strings buffer )
    71     if( is_args ) order = bits_log2( CONFIG_VMM_ARGS_SIZE );
    72     else          order = bits_log2( CONFIG_VMM_ENVS_SIZE );
    73 
    74     // allocate one physical page for kernel array of pointers
    75     req.type   = KMEM_PPM;
    76     req.order  = 0;
    77     req.flags  = AF_KERNEL | AF_ZERO;
    78     k_pointers = kmem_alloc( &req );
    79 
    80     if( k_pointers == NULL ) return ENOMEM;
    81 
    82     // allocate several physical pages to store the strings themselve
    83     req.type   = KMEM_PPM;
    84     req.order  = order;
    85     req.flags  = AF_KERNEL | AF_ZERO;
    86     k_buf_base = kmem_alloc( &req );
    87 
    88     if( k_buf_base == NULL ) return ENOMEM;
    89 
    90     // copy the array of pointers to kernel buffer
    91     hal_copy_from_uspace( XPTR( local_cxy , k_pointers ),
    92                           u_pointers,
    93                           CONFIG_PPM_PAGE_SIZE );
    94 
    95     // scan kernel array of pointers to copy the strings
    96     found_null = 0;
    97     k_buf_ptr  = k_buf_base;
    98     for( index = 0 ; index < 1024 ; index++ )
    99     {
    100         if( k_pointers[index] == NULL )
    101         {
    102             found_null = 1;
    103             break;
    104         }
    105 
    106         // compute string length
    107         length = hal_strlen_from_uspace( k_pointers[index] );
    108 
    109         // copy the user string to kernel buffer
    110         hal_copy_from_uspace( XPTR( local_cxy , k_buf_ptr ),
    111                               k_pointers[index],
    112                               length );
    113 
    114         // update k_pointer[index] entry
    115         k_pointers[index] = k_buf_ptr;
    116 
    117         // increment pointer on kernel strings buffer
    118         k_buf_ptr += (length + 1);
    119     }
    120 
    121     // update into exec_info structure
    122     if( found_null && is_args )
    123     {
    124         exec_info->args_pointers  =  k_pointers;
    125         exec_info->args_buf_base  =  k_buf_base;
    126         exec_info->args_nr        =  index;
    127     }
    128     else if( found_null && !is_args )
    129     {
    130         exec_info->envs_pointers  =  k_pointers;
    131         exec_info->envs_buf_base  =  k_buf_base;
    132         exec_info->envs_buf_free  =  k_buf_ptr;
    133         exec_info->envs_nr        =  index;
    134     }
    135     else
    136     {
    137         return EINVAL;
    138     }
    139 
    140     return 0;
    141 } // end process_exec_get_strings()
    142 
    143 /////////////////////////////////////////////////////////////////////////////////////////
    144 // Implementation note:
    145 // This function must be called by the main thread (thread 0 in owner cluster).
    146 // It build an exec_info_t structure containing all informations
    147 // required to initialize the new process descriptor and the associated thread.
    148 // It includes the new process main() arguments, the environment variables,
    149 // and the pathname to the new process .elf file.
    150 // It calls the process_exec_get_strings() functions to copy the main() arguments and
    151 // the environment variables from user buffers to the exec_info_t structure, allocate
    152 // and call the process_make_exec() function.
    153 // As it must destroy all process copies, and all other threads in all clusters,
    154 // the process_make_exec() function must be executed in the owner cluster.
    155 //
    156 // TODO : the args & envs arguments are not supported yet : both must be NULL  [AG]
    157 /////////////////////////////////////////////////////////////////////////////////////////
    158 int sys_exec( char  * pathname,       // .elf file pathname
    159               char ** args,           // process arguments
    160               char ** envs )          // environment variables
    161 {
    162     exec_info_t   exec_info;          // structure to pass to process_make_exec()
    16345    error_t       error;
     46    vseg_t      * vseg;
    16447
    16548    // get calling thread, process, & pid
     
    16750    process_t   * process = this->process;
    16851    pid_t         pid     = process->pid;
     52    trdid_t       trdid   = this->trdid;
    16953
    170 #if DEBUG_SYS_EXEC
     54assert( __FUNCTION__, (CXY_FROM_PID( pid ) == local_cxy) ,
     55"must be called in the owner cluster\n");
     56
     57assert( __FUNCTION__, (LTID_FROM_TRDID( trdid ) == 0) ,
     58"must be called by the main thread\n");
     59
     60assert( __FUNCTION__, (user_envs == NULL) ,
     61"environment variables not supported yet\n" );
     62
     63#if DEBUG_SYS_EXEC || DEBUG_SYSCALLS_ERROR
    17164uint64_t     tm_start = hal_get_cycles();
    17265#endif
    17366
    174     assert( (CXY_FROM_PID( pid ) == local_cxy) ,
    175     "must be called in the owner cluster\n");
     67    // check "pathname" mapped in user space
     68    if( vmm_get_vseg( process , (intptr_t)pathname , &vseg ) )
     69        {
    17670
    177     assert( (LTID_FROM_TRDID( this->trdid ) == 0) ,
    178     "must be called by the main thread\n");
     71#if DEBUG_SYSCALLS_ERROR
     72if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     73printk("\n[ERROR] in %s : thread[%x,%] / pathname pointer %x unmapped\n",
     74__FUNCTION__, pid, trdid, pathname );
     75#endif
     76        this->errno = EINVAL;
     77                return -1;
     78        }
    17979
    180     assert( (args == NULL) ,
    181     "args not supported yet\n" );
    182 
    183     assert( (envs == NULL) ,
    184     "args not supported yet\n" );
    185 
    186     // check pathname length
     80    // check "pathname" length
    18781    if( hal_strlen_from_uspace( pathname ) >= CONFIG_VFS_MAX_PATH_LENGTH )
    18882    {
    18983
    19084#if DEBUG_SYSCALLS_ERROR
    191 printk("\n[ERROR] in %s : thread[%x,%x] pathname too long\n",
    192 __FUNCTION__, pid, this->trdid );
     85if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     86printk("\n[ERROR] in %s : thread[%x,%x] / pathname too long\n",
     87__FUNCTION__, pid, trdid );
    19388#endif
    19489        this->errno = ENFILE;
     
    19691    }
    19792
    198     // copy pathname in exec_info structure (kernel space)
    199     hal_strcpy_from_uspace( XPTR( local_cxy , exec_info.path ),
     93    // check "args" mapped in user space if non NULL
     94    if( (user_args != NULL) && (vmm_get_vseg( process , (intptr_t)user_args , &vseg )) )
     95        {
     96
     97#if DEBUG_SYSCALLS_ERROR
     98printk("\n[ERROR] in %s for thread[%x,%] : user_args pointer %x unmapped\n",
     99__FUNCTION__, pid, trdid, user_args );
     100#endif
     101        this->errno = EINVAL;
     102                return -1;
     103        }
     104
     105    // check "envs" mapped in user space if not NULL
     106    if( (user_envs != NULL) && (vmm_get_vseg( process , (intptr_t)user_envs , &vseg )) )
     107        {
     108
     109#if DEBUG_SYSCALLS_ERROR
     110if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     111printk("\n[ERROR] in %s : thread[%x,%] / user_envs pointer %x unmapped\n",
     112__FUNCTION__, pid, trdid, user_envs );
     113#endif
     114        this->errno = EINVAL;
     115                return -1;
     116        }
     117
     118#if DEBUG_SYS_EXEC
     119if( DEBUG_SYS_EXEC < (uint32_t)tm_start )
     120printk("\n[%s] thread[%x,%x] enter / path <%s> / args %x / envs %x / cycle %d\n",
     121__FUNCTION__, pid, trdid, &process->exec_info.path[0], user_args, user_envs, cycle );
     122#endif
     123
     124    // 1. copy "pathname" in kernel exec_info structure
     125    hal_strcpy_from_uspace( XPTR( local_cxy , &process->exec_info.path[0] ),
    200126                            pathname,
    201127                            CONFIG_VFS_MAX_PATH_LENGTH );
    202128
    203 #if DEBUG_SYS_EXEC
    204 if( DEBUG_SYS_EXEC < tm_start )
    205 printk("\n[%s] thread[%x,%x] enter for path <%s> / cycle = %d\n",
    206 __FUNCTION__, pid, this->trdid, exec_info.path, (uint32_t)tm_start );
    207 #endif
    208 
    209     // check and store args in exec_info structure if required
    210     if( args != NULL )
     129    // 2. copy "arguments" pointers & strings in process exec_info if required
     130    if( user_args != NULL )
    211131    {
    212         if( process_exec_get_strings( &exec_info , true , args ) )
     132        if( process_exec_get_strings( true , user_args , &process->exec_info ) )
    213133        {
    214134
    215135#if DEBUG_SYSCALLS_ERROR
    216 printk("\n[ERROR] in %s : thread[%x,%x] cannot access args for <%s>\n",
    217 __FUNCTION__, pid, this->trdid, exec_info.path );
     136if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     137printk("\n[ERROR] in %s : thread[%x,%] get arguments for <%s>\n",
     138__FUNCTION__, pid, trdid, pathname );
    218139#endif
    219140            this->errno = EINVAL;
    220141            return -1;
    221142        }
     143
     144#if DEBUG_SYS_EXEC
     145if( DEBUG_SYS_EXEC < (uint32_t)tm_start )
     146printk("\n[%s] thread[%x,%x] got arguments / arg[0] = <%s>\n",
     147__FUNCTION__, pid, trdid, process->exec_info.args_pointers[0] );
     148#endif
     149
    222150    }
    223151
    224     // check and store envs in exec_info structure if required
    225     if( envs != NULL )
     152    // 3. copy "environment" pointers & strings in process exec_info if required
     153    if( user_envs != NULL )
    226154    {
    227         if( process_exec_get_strings( &exec_info , false , envs ) )
     155        if( process_exec_get_strings( false , user_envs , &process->exec_info ) )
    228156        {
    229157
    230158#if DEBUG_SYSCALLS_ERROR
    231 printk("\n[ERROR] in %s : thread[%x,%x] cannot access envs for <%s>\n",
    232 __FUNCTION__ , pid, this->trdid, exec_info.path );
     159if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     160printk("\n[ERROR] in %s : thread[%x,%] get env variables for <%s>\n",
     161__FUNCTION__, pid, trdid, pathname );
    233162#endif
    234163            this->errno = EINVAL;
    235164            return -1;
    236165        }
     166
     167#if DEBUG_SYS_EXEC
     168if( DEBUG_SYS_EXEC < (uint32_t)tm_start )
     169printk("\n[%s] thread[%x,%x] got envs / env[0] = <%s>\n",
     170__FUNCTION__, pid, trdid, process->exec_info.envs_pointers[0] );
     171#endif
     172
    237173    }
    238174
    239     // call relevant kernel function
    240     error = process_make_exec( &exec_info );
     175    // call relevant kernel function (no return if success)
     176    error = process_make_exec();
    241177
    242178    if( error )
     
    244180
    245181#if DEBUG_SYSCALLS_ERROR
    246 printk("\n[ERROR] in %s : thread[%x,%x] cannot create process for <%s>\n",
    247 __FUNCTION__, pid, this->trdid, exec_info.path );
     182if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     183printk("\n[ERROR] in %s : thread[%x,%x] cannot create process <%s>\n",
     184__FUNCTION__, pid, trdid, process->exec_info.path );
    248185#endif
    249186        this->errno = error;
     
    251188    }
    252189
    253     assert( false , "we should never execute this code" );
    254 
    255190    return 0; 
    256191
  • trunk/kernel/syscalls/sys_exit.c

    r664 r670  
    2929#include <printk.h>
    3030#include <process.h>
     31#include <dev_fbf.h>
    3132#include <shared_syscalls.h>
    3233#include <cluster.h>
     
    9899#endif
    99100
     101    // delete all process registered FBF windows
     102    dev_fbf_cleanup( pid );
     103
     104#if( DEBUG_SYS_EXIT & 1)
     105if( DEBUG_SYS_EXIT < tm_start )
     106printk("\n[%s] thread[%x,%x] deleted all FBF windows for process %x\n",
     107__FUNCTION__, pid, this->trdid, pid );
     108#endif
     109
    100110    // mark for delete all process threads in all clusters,
    101111    // but the main thread and this calling thread
     
    117127__FUNCTION__, pid, this->trdid );
    118128#endif
    119         thread_delete( XPTR( local_cxy , this ) , true );    // forced
     129        thread_delete_request( XPTR( local_cxy , this ) , true );    // forced
    120130    }
    121131
  • trunk/kernel/syscalls/sys_fbf.c

    r657 r670  
    5454#if DEBUG_SYS_FBF
    5555if( DEBUG_SYS_FBF < tm_start )
    56 printk("\n[%s] thread[%x,%x] enter for %s / arg1 %x / arg2 %x / arg3 %x / cycle %d\n",
     56printk("\n[%s] thread[%x,%x] %s / a1 %x / a2 %x / a3 %x / cycle %d\n",
    5757__FUNCTION__, process->pid, this->trdid, dev_fbf_cmd_str( operation ),
    5858arg1, arg2, arg3, (uint32_t)tm_start );
     
    203203        }
    204204        ///////////////////////
     205        case FBF_ACTIVE_WINDOW:
     206        {
     207            uint32_t  wid    = arg1;
     208            uint32_t  active = arg2;
     209
     210            // call relevant kernel function
     211            error = dev_fbf_active_window( wid , active );
     212               
     213            if( error )
     214            {
     215
     216#if DEBUG_SYSCALLS_ERROR
     217printk("\n[ERROR] in %s : cannot %s / thread[%x,%x]\n",
     218__FUNCTION__ , dev_fbf_cmd_str(operation), process->pid, this->trdid );
     219#endif
     220                this->errno = EINVAL;
     221            }
     222            break;
     223        }
     224        ///////////////////////
    205225        case FBF_DELETE_WINDOW:
    206226        {
     
    214234
    215235#if DEBUG_SYSCALLS_ERROR
    216 printk("\n[ERROR] in %s : cannot delete window for %s / thread[%x,%x]\n",
     236printk("\n[ERROR] in %s : cannot %s / thread[%x,%x]\n",
    217237__FUNCTION__ , dev_fbf_cmd_str(operation), process->pid, this->trdid );
    218238#endif
     
    237257
    238258#if DEBUG_SYSCALLS_ERROR
    239 printk("\n[ERROR] in %s : cannot refresh window for %s / thread[%x,%x]\n",
     259printk("\n[ERROR] in %s : cannot %s / thread[%x,%x]\n",
    240260__FUNCTION__ , dev_fbf_cmd_str(operation), process->pid, this->trdid );
    241261#endif
     
    258278
    259279#if DEBUG_SYSCALLS_ERROR
    260 printk("\n[ERROR] in %s : cannot move window / thread[%x,%x]\n",
     280printk("\n[ERROR] in %s : cannot %s / thread[%x,%x]\n",
    261281__FUNCTION__ , dev_fbf_cmd_str(operation), process->pid, this->trdid );
    262282#endif
     
    279299
    280300#if DEBUG_SYSCALLS_ERROR
    281 printk("\n[ERROR] in %s : cannot move window / thread[%x,%x]\n",
     301printk("\n[ERROR] in %s : cannot %s / thread[%x,%x]\n",
     302__FUNCTION__ , dev_fbf_cmd_str(operation), process->pid, this->trdid );
     303#endif
     304                this->errno = EINVAL;
     305            }
     306            break;
     307        }
     308        //////////////////////
     309        case FBF_FRONT_WINDOW:
     310        {
     311            uint32_t  wid = arg1;
     312
     313            // call relevant kernel function
     314            error = dev_fbf_front_window( wid );
     315               
     316            if( error )
     317            {
     318
     319#if DEBUG_SYSCALLS_ERROR
     320printk("\n[ERROR] in %s : cannot %s / thread[%x,%x]\n",
    282321__FUNCTION__ , dev_fbf_cmd_str(operation), process->pid, this->trdid );
    283322#endif
  • trunk/kernel/syscalls/sys_fork.c

    r637 r670  
    22 * sys_fork.c - Kernel function implementing the "fork" system call.
    33 *
    4  * Authors  Alain Greiner  (2016,2017,2018,2019)
     4 * Authors  Alain Greiner  (2016,2017,2018,2019,2020)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    4646    xptr_t            parent_thread_xp;     // extended pointer on parent thread descriptor
    4747    pid_t             parent_pid;           // parent process identifier
    48     thread_t        * parent_thread_ptr;    // local pointer on local parent thread descriptor
     48    thread_t        * parent_thread_ptr;    // local pointer on local parent thread
    4949    cxy_t             parent_cxy;           // parent thread cluster
    5050
    5151    pid_t             child_pid;            // child process identifier
    52     thread_t        * child_thread_ptr;     // local pointer on remote child thread descriptor
     52    thread_t        * child_thread_ptr;     // local pointer on remote child thread
    5353    cxy_t             child_cxy;            // target cluster for forked child process
    5454 
     
    5858
    5959        error_t           error;
    60    
    6160
    6261    // get pointers on local parent process and thread
     
    6766    parent_cxy         = local_cxy;
    6867
    69 #if (DEBUG_SYS_FORK || CONFIG_INSTRUMENTATION_SYSCALLS)
     68#if DEBUG_SYS_FORK || DEBUG_SYSCALLS_ERROR || CONFIG_INSTRUMENTATION_SYSCALLS
    7069uint64_t     tm_start = hal_get_cycles();
    7170#endif
     
    8887
    8988#if DEBUG_SYSCALLS_ERROR
    90 printk("\n[ERROR] in %s : thread[%x,%x] cannot fork : too much children\n",
     89if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     90printk("\n[ERROR] in %s : thread[%x,%x] / too much children\n",
    9191__FUNCTION__, parent_pid, parent_thread_ptr->trdid );
    9292#endif
     
    136136
    137137#if DEBUG_SYSCALLS_ERROR
     138if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
    138139printk("\n[ERROR] in %s : thread[%x,%x] cannot fork\n",
    139140__FUNCTION__, parent_pid, parent_thread_ptr->trdid );
  • trunk/kernel/syscalls/sys_isatty.c

    r664 r670  
    8989
    9090    // get file type
    91     vfs_inode_type_t type = hal_remote_l32( XPTR( file_cxy , &file_ptr->type ) );
     91    vfs_file_type_t type = hal_remote_l32( XPTR( file_cxy , &file_ptr->type ) );
    9292
    9393    // action depend on file type
    94     if( type != INODE_TYPE_DEV )      // not a device
     94    if( type != FILE_TYPE_DEV )      // not a device
    9595    {
    9696        retval = 0;
  • trunk/kernel/syscalls/sys_mkfifo.c

    r637 r670  
    22 * sys_mkfifo.c - creates a named FIFO file.
    33 *
    4  * Author    Alain Greiner (2016,2017,2018,2019)
     4 * Author    Alain Greiner (2016,2017,2018,2019,2020)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    3131////////////////////////////////////
    3232int sys_mkfifo ( char    * pathname,
    33                  uint32_t  mode __attribute__((unused)) )
     33                 uint32_t  mode )
    3434{
    35     char           kbuf[CONFIG_VFS_MAX_PATH_LENGTH];
     35    vseg_t      * vseg;
     36    error_t       error;
     37    xptr_t        root_inode_xp;           
     38    char          kbuf[CONFIG_VFS_MAX_PATH_LENGTH];
    3639
    37     thread_t  * this    = CURRENT_THREAD;
    38     process_t * process = this->process;
     40    thread_t    * this    = CURRENT_THREAD;
     41    process_t   * process = this->process;
    3942
    40 #if (DEBUG_SYS_MKFIFO || CONFIG_INSTRUMENTATION_SYSCALLS)
     43#if DEBUG_SYS_MKFIFO || DEBUG_SYSCALLS_ERROR || CONFIG_INSTRUMENTATION_SYSCALLS
    4144uint64_t     tm_start = hal_get_cycles();
    4245#endif
     
    4548if( DEBUG_SYS_MKFIFO < tm_end )
    4649printk("\n[%s] thread[%x,%x] enter for <%s> / cycle %d\n",
    47 __FUNCTION__, process->pid, this->trdid, pathname, (uint32_t)tm_end );
     50__FUNCTION__, process->pid, this->trdid, pathname, (uint32_t)tm_start );
    4851#endif
    4952 
    50     // check fd_array not full
    51     if( process_fd_array_full() )
    52     {
     53    // check pathname in user space
     54    if( vmm_get_vseg( process, (intptr_t)pathname , &vseg ) )
     55        {
    5356
    5457#if DEBUG_SYSCALLS_ERROR
    55 printk("\n[ERROR] in %s : file descriptor array full for process %x\n",
    56 __FUNCTION__ , process->pid );
     58if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     59printk("\n[ERROR] in %s : user buffer unmapped %x for thread[%x,%x]\n",
     60__FUNCTION__ , (intptr_t)pathname , process->pid, this->trdid );
    5761#endif
    58         this->errno = ENFILE;
     62                this->errno = EINVAL;
    5963        return -1;
    60     }
     64        }
    6165
    6266    // check pathname length
     
    6569
    6670#if DEBUG_SYSCALLS_ERROR
    67 printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ );
     71if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     72printk("\n[ERROR] in %s : pathname too long for thread[%x,%x]\n",
     73__FUNCTION__ , process->pid , this->trdid );
    6874#endif
    6975        this->errno = ENFILE;
     
    7682                            CONFIG_VFS_MAX_PATH_LENGTH );
    7783
    78     printk("\n[ERROR] in %s : not implemented yet\n", __FUNCTION__ );
    79     return -1;
     84#if DEBUG_SYS_MKFIFO
     85if( DEBUG_SYS_MKFIFO < tm_end )
     86printk("\n[%s] thread[%x,%x] enter for <%s> / cycle %d\n",
     87__FUNCTION__, process->pid, this->trdid, kbuf, (uint32_t)tm_start );
     88#endif
     89 
     90    // get cluster and local pointer on reference process
     91    xptr_t      ref_xp  = process->ref_xp;
     92    process_t * ref_ptr = GET_PTR( ref_xp );
     93    cxy_t       ref_cxy = GET_CXY( ref_xp );
     94
     95    // get extended pointer on root inode in path
     96    if( kbuf[0] == '/' )                            // absolute path
     97    {
     98        // use extended pointer on VFS root inode
     99        root_inode_xp = process->vfs_root_xp;
     100    }
     101    else                                            // relative path
     102    {
     103        // use extended pointer on CWD inode
     104        root_inode_xp = hal_remote_l64( XPTR( ref_cxy , &ref_ptr->cwd_xp ) );
     105    }
     106
     107    // call the relevant VFS function
     108    error = vfs_mkfifo( root_inode_xp,
     109                        kbuf,
     110                        mode );
     111    if( error )
     112    {
     113
     114#if DEBUG_SYSCALLS_ERROR
     115if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     116printk("\n[ERROR] in %s : thread[%x,%x] cannot create node in VFS for <%s> path\n",
     117__FUNCTION__ , process->pid , this->trdid , kbuf );
     118#endif
     119        this->errno = ENFILE;
     120        return -1;
     121    }
    80122
    81123#if (DEBUG_SYS_MKFIFO || CONFIG_INSTRUMENTATION_SYSCALLS)
     
    94136#endif
    95137
     138    return 0;
     139
    96140} // end sys_mkfifo()
  • trunk/kernel/syscalls/sys_mmap.c

    r664 r670  
    193193*/
    194194
    195                 // increment file refcount
    196                 vfs_file_count_up( file_xp );
    197 
    198195        mapper_xp = XPTR( file_cxy , mapper_ptr );
    199196        vseg_type = VSEG_TYPE_FILE;
  • trunk/kernel/syscalls/sys_mutex.c

    r635 r670  
    216216        default:
    217217        {
    218             assert ( false, "illegal operation type <%x>", operation );
     218            assert( __FUNCTION__, false, "illegal operation type <%x>", operation );
    219219        }
    220220        }
  • trunk/kernel/syscalls/sys_open.c

    r637 r670  
    3939               uint32_t   mode )
    4040{
     41    vseg_t       * vseg;
    4142    error_t        error;
    4243    xptr_t         file_xp;                 // extended pointer on vfs_file_t
    4344    uint32_t       file_id;                 // file descriptor index
    44     xptr_t         root_inode_xp;           // extended pointer on path root inode
     45    xptr_t         root_inode_xp;           // extended pointer on root inode
    4546
    4647    char           kbuf[CONFIG_VFS_MAX_PATH_LENGTH];
     
    4950    process_t    * process  = this->process;
    5051
    51 #if (DEBUG_SYS_OPEN || CONFIG_INSTRUMENTATION_SYSCALLS)
     52#if DEBUG_SYS_OPEN || DEBUG_SYSCALLS_ERROR || CONFIG_INSTRUMENTATION_SYSCALLS
    5253uint64_t     tm_start = hal_get_cycles();
    5354#endif
     
    5859
    5960#if DEBUG_SYSCALLS_ERROR
    60 printk("\n[ERROR] in %s : file descriptor array full for process %x\n",
    61 __FUNCTION__ , process->pid );
     61if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     62printk("\n[ERROR] in %s : file descriptor array full for thread[%x,%x]\n",
     63__FUNCTION__ , process->pid , this->trdid );
    6264#endif
    6365        this->errno = ENFILE;
    6466        return -1;
    6567    }
     68
     69    // check pathname in user space
     70    if( vmm_get_vseg( process, (intptr_t)pathname , &vseg ) )
     71        {
     72
     73#if DEBUG_SYSCALLS_ERROR
     74if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     75printk("\n[ERROR] in %s : user buffer unmapped %x for thread[%x,%x]\n",
     76__FUNCTION__ , (intptr_t)pathname , process->pid, this->trdid );
     77#endif
     78                this->errno = EINVAL;
     79        return -1;
     80        }
    6681
    6782    // check pathname length
     
    7085
    7186#if DEBUG_SYSCALLS_ERROR
    72 printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ );
     87if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     88printk("\n[ERROR] in %s : pathname too long for thread[%x,%x]\n",
     89__FUNCTION__ , process->pid , this->trdid );
    7390#endif
    7491        this->errno = ENFILE;
     
    7794
    7895    // copy pathname in kernel space
    79     hal_strcpy_from_uspace( XPTR( local_cxy , kbuf ) , pathname , CONFIG_VFS_MAX_PATH_LENGTH );
    80 
     96    hal_strcpy_from_uspace( XPTR( local_cxy , kbuf ),
     97                            pathname,
     98                            CONFIG_VFS_MAX_PATH_LENGTH );
    8199#if DEBUG_SYS_OPEN
    82100if( DEBUG_SYS_OPEN < tm_start )
     
    86104 
    87105    // get cluster and local pointer on reference process
    88     xptr_t      ref_xp  = process->ref_xp;
    89     process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
    90     cxy_t       ref_cxy = GET_CXY( ref_xp );
     106    xptr_t      owner_xp  = process->owner_xp;
     107    process_t * owner_ptr = GET_PTR( owner_xp );
     108    cxy_t       owner_cxy = GET_CXY( owner_xp );
    91109
    92     // compute root inode for path
    93     if( kbuf[0] == '/' )                        // absolute path
     110    // get extended pointer on root inode in path
     111    if( kbuf[0] == '/' )                            // absolute path
    94112    {
    95113        // use extended pointer on VFS root inode
    96114        root_inode_xp = process->vfs_root_xp;
    97115    }
    98     else                                        // relative path
     116    else                                            // relative path
    99117    {
    100118        // use extended pointer on CWD inode
    101         root_inode_xp = hal_remote_l64( XPTR( ref_cxy , &ref_ptr->cwd_xp ) );
     119        root_inode_xp = hal_remote_l64( XPTR( owner_cxy , &owner_ptr->cwd_xp ) );
    102120    }
    103121
     
    105123    error = vfs_open( root_inode_xp,
    106124                      kbuf,
    107                       ref_xp,
     125                      owner_xp,
    108126                      flags,
    109127                      mode,
     
    113131    if( error )
    114132    {
    115         printk("\n[ERROR] in %s : cannot create file descriptor for %s\n",
    116         __FUNCTION__ , kbuf );
     133
     134#if DEBUG_SYSCALLS_ERROR
     135if( DEBUG_SYSCALLS_ERROR < tm_start )
     136printk("\n[ERROR] in %s : thread[%x,%x] cannot create file descriptor for %s\n",
     137__FUNCTION__ , process->pid , this->trdid , kbuf );
     138#endif
    117139        this->errno = ENFILE;
    118140        return -1;
  • trunk/kernel/syscalls/sys_opendir.c

    r637 r670  
    22 * sys_opendir.c - Open an user accessible VFS directory.
    33 *
    4  * Author        Alain Greiner (2016,2017,2018,2019)
     4 * Author        Alain Greiner (2016,2017,2018,2019,2020)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    5454        process_t    * process = this->process;   // client process
    5555
    56 #if (DEBUG_SYS_OPENDIR || CONFIG_INSTRUMENTATION_SYSCALLS)
     56#if DEBUG_SYS_OPENDIR || DEBUG_SYSCALLS_ERROR || CONFIG_INSTRUMENTATION_SYSCALLS
    5757uint64_t     tm_start = hal_get_cycles();
    5858#endif
     
    6565
    6666#if DEBUG_SYSCALLS_ERROR
    67 printk("\n[ERROR] in %s / thread[%x,%x] : DIR buffer %x unmapped\n",
     67if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     68printk("\n[ERROR] in %s : thread[%x,%x] / DIR buffer %x unmapped\n",
    6869__FUNCTION__ , process->pid , this->trdid, dirp );
    6970#endif
     
    7273        }       
    7374
     75    // check pathname in user space
     76    error = vmm_get_vseg( process , (intptr_t)pathname, &vseg );
     77
     78        if( error )
     79        {
     80
     81#if DEBUG_SYSCALLS_ERROR
     82if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     83printk("\n[ERROR] in %s : thread[%x,%x] / pathname %x unmapped\n",
     84__FUNCTION__ , process->pid , this->trdid, pathname );
     85#endif
     86                this->errno = EINVAL;
     87                return -1;
     88        }       
    7489    // check pathname length
    7590    if( hal_strlen_from_uspace( pathname ) >= CONFIG_VFS_MAX_PATH_LENGTH )
     
    7792
    7893#if DEBUG_SYSCALLS_ERROR
     94if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
    7995printk("\n[ERROR] in %s / thread[%x,%x] : pathname too long\n",
    8096 __FUNCTION__ , process->pid , this->trdid );
     
    90106
    91107#if DEBUG_SYS_OPENDIR
    92 if( DEBUG_SYS_OPENDIR < tm_start )
     108if( DEBUG_SYS_OPENDIR < (uint32_t)tm_start )
    93109printk("\n[%s] thread[%x,%x] enter for directory <%s> / cycle %d\n",
    94110__FUNCTION__, process->pid, this->trdid, kbuf, (uint32_t)tm_start );
     
    122138
    123139#if DEBUG_SYSCALLS_ERROR
    124 printk("\n[ERROR] in %s / thread[%x,%x] : cannot found directory <%s>\n",
     140if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     141printk("\n[ERROR] in %s : thread[%x,%x] / cannot found directory <%s>\n",
    125142__FUNCTION__ , process->pid , this->trdid , kbuf );
    126143#endif
     
    134151    inode_type = hal_remote_l32( XPTR( inode_cxy , &inode_ptr->type ) );
    135152
    136     if( inode_type != INODE_TYPE_DIR )
    137         {
    138 
    139 #if DEBUG_SYSCALLS_ERROR
    140 printk("\n[ERROR] in %s / thread[%x,%x] : cannot found directory <%s>\n",
     153    if( inode_type != FILE_TYPE_DIR )
     154        {
     155
     156#if DEBUG_SYSCALLS_ERROR
     157if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     158printk("\n[ERROR] in %s : thread[%x,%x] / <%s> is not a directory\n",
    141159__FUNCTION__ , process->pid , this->trdid , kbuf );
    142160#endif
     
    165183
    166184#if DEBUG_SYSCALLS_ERROR
    167 printk("\n[ERROR] in %s / thread[%x,%x] : cannot create user_dir for <%s>\n",
     185if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     186printk("\n[ERROR] in %s : thread[%x,%x] / cannot create user_dir for <%s>\n",
    168187__FUNCTION__ , process->pid , this->trdid , kbuf );
    169188#endif
  • trunk/kernel/syscalls/sys_pipe.c

    r506 r670  
    22 * sys_pipe.c - open a pipe communication channel
    33 *
    4  * Author    Alain Greiner  (2016,1017)
     4 * Author    Alain Greiner  (2016,1017,2018,2019,2020)
    55 *
    66 * Copyright (c)  UPMC Sorbonne Universites
     
    2424#include <hal_kernel_types.h>
    2525#include <vfs.h>
     26#include <hal_uspace.h>
    2627#include <process.h>
    2728#include <thread.h>
    2829#include <printk.h>
     30#include <pipe.h>
    2931
    3032#include <syscalls.h>
    3133
    32 //////////////////////////////////////
    33 int sys_pipe ( uint32_t file_fd[2] )
     34////////////////////////////
     35int sys_pipe ( fdid_t * fd )
    3436{
    35     printk("\n[ERROR] in %d : not implemented yet\n", __FUNCTION__, file_fd );
    36     return ENOSYS;
    37 }
     37    vseg_t       * vseg;
     38    kmem_req_t     req;
     39    pipe_t       * pipe;
     40    vfs_file_t   * file_0;
     41    vfs_file_t   * file_1;
     42    fdid_t         fdid_0;
     43    fdid_t         fdid_1;
     44    error_t        error;
     45
     46    thread_t     * this    = CURRENT_THREAD;
     47    process_t    * process = this->process;
     48
     49#if DEBUG_SYS_PIPE || DEBUG_SYSCALLS_ERROR || CONFIG_INSTRUMENTATION_SYSCALLS
     50uint64_t   tm_start = hal_get_cycles();
     51#endif
     52
     53#if DEBUG_SYS_PIPE
     54if( DEBUG_SYS_PIPE < tm_end )
     55printk("\n[%s] thread[%x,%x] enter for <%s> / cycle %d\n",
     56__FUNCTION__, process->pid, this->trdid, pathname, (uint32_t)tm_end );
     57#endif
     58
     59    // check user buffer is mapped
     60    if( vmm_get_vseg( process , (intptr_t)fd , &vseg ) )
     61    {
     62
     63#if DEBUG_SYSCALLS_ERROR
     64if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     65printk("\n[ERROR] in %s : thread[%x,%x] / output user buffer unmapped %x\n",
     66__FUNCTION__ , process->pid, this->trdid, (intptr_t)fd );
     67#endif
     68                this->errno = EINVAL;
     69                return -1;
     70    }
     71
     72    // 1. allocate memory in local cluster for pipe descriptor,
     73    //    remote buf_descriptor, and associated data buffer
     74    pipe = pipe_create( local_cxy,
     75                        CONFIG_PIPE_BUF_SIZE );
     76
     77    if( pipe == NULL )
     78    {
     79
     80#if DEBUG_SYSCALLS_ERROR
     81if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     82printk("\n[ERROR] in %s : thread[%x,%x] / no memory for pipe\n",
     83__FUNCTION__ , process->pid, this->trdid );
     84#endif
     85        goto error_1;
     86    }
     87
     88    // 2. allocate memory for fd[0] file descriptor in local cluster
     89    // we don't use the vfs_file_create function because there is no inode.
     90        req.type  = KMEM_KCM;
     91        req.order = bits_log2( sizeof(vfs_file_t) );
     92    req.flags = AF_ZERO;
     93        file_0    = kmem_alloc( &req );
     94
     95    if( file_0 == NULL )
     96    {
     97
     98#if DEBUG_SYSCALLS_ERROR
     99if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     100printk("\n[ERROR] in %s : thread[%x,%x] / no memory for file descriptor\n",
     101__FUNCTION__, process->pid, this->trdid );
     102#endif
     103        goto error_2;
     104    }
     105   
     106    // 3. get fd[0] fdid value and register it in owner process fd_array[]
     107    error = process_fd_register( process->owner_xp,
     108                                 XPTR( local_cxy , file_0 ),
     109                                 &fdid_0 );
     110    if ( error )
     111    {
     112
     113#if DEBUG_SYSCALLS_ERROR
     114if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     115printk("\n[ERROR] in %s : thread[%x,%x] / cannot register file descriptor \n",
     116__FUNCTION__, process->pid, this->trdid );
     117#endif
     118        goto error_3;
     119    }
     120
     121    // 4. allocate memory for fd[1] file descriptor in local cluster
     122        req.type  = KMEM_KCM;
     123        req.order = bits_log2( sizeof(vfs_file_t) );
     124    req.flags = AF_ZERO;
     125        file_1    = kmem_alloc( &req );
     126
     127    if( file_1 == NULL )
     128    {
     129
     130#if DEBUG_SYSCALLS_ERROR
     131if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     132printk("\n[ERROR] in %s : thread[%x,%x] / no memory for file descriptor\n",
     133__FUNCTION__, process->pid, this->trdid );
     134#endif
     135        goto error_4;
     136    }
     137
     138    // 5. get fd[1] fdid value and register it in owner process fd_array[]
     139    error = process_fd_register( process->owner_xp,
     140                                 XPTR( local_cxy , file_1 ),
     141                                 &fdid_1 );
     142    if ( error )
     143    {
     144
     145#if DEBUG_SYSCALLS_ERROR
     146if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     147printk("\n[ERROR] in %s : thread[%x,%x] / cannot register file descriptor \n",
     148__FUNCTION__, process->pid, this->trdid );
     149#endif
     150        goto error_5;
     151    }
     152
     153    // link the two file descriptors to the pipe
     154    file_0->pipe = pipe;
     155    file_1->pipe = pipe;
     156
     157    // copy fdid_0 & fdid_1 values to user buffer
     158    hal_copy_to_uspace( &fd[0] , XPTR( local_cxy , &fdid_0 ) , sizeof(fdid_t) );
     159    hal_copy_to_uspace( &fd[1] , XPTR( local_cxy , &fdid_1 ) , sizeof(fdid_t) );
     160
     161#if (DEBUG_SYS_PIPE || CONFIG_INSTRUMENTATION_SYSCALLS)
     162uint64_t     tm_end = hal_get_cycles();
     163#endif
     164
     165#if DEBUG_SYS_PIPE
     166if( DEBUG_SYS_PIPE < tm_end )
     167printk("\n[%s] thread[%x,%x] exit for <%s> / cycle %d\n",
     168__FUNCTION__, this->process->pid, this->trdid, pathname, (uint32_t)tm_end );
     169#endif
     170 
     171#if CONFIG_INSTRUMENTATION_SYSCALLS
     172hal_atomic_add( &syscalls_cumul_cost[SYS_PIPE] , tm_end - tm_start );
     173hal_atomic_add( &syscalls_occurences[SYS_PIPE] , 1 );
     174#endif
     175
     176    return 0;
     177
     178error_5:    // release memory allocated for fd[1] file descriptor
     179
     180    req.ptr = file_1;
     181    kmem_free( &req );
     182
     183error_4:    // release fdid_0 from fd_array[]
     184
     185    process_fd_remove( process->ref_xp , fdid_0 );
     186
     187error_3:    // release memory allocated for fd[0] file descriptor
     188
     189    req.ptr = file_0;
     190    kmem_free( &req );
     191
     192error_2:    // release memory allocated for the pipe
     193
     194    pipe_destroy( XPTR( local_cxy , pipe ) );
     195
     196error_1:   // set errno and return error
     197
     198    this->errno = ENOMEM;
     199    return -1;
     200
     201}  // end sys_pipe()
  • trunk/kernel/syscalls/sys_place_fork.c

    r637 r670  
    3838{
    3939    thread_t  * this    = CURRENT_THREAD;
    40     process_t * process = this->process;
    4140
    42 #if (DEBUG_SYS_PLACE_FORK || CONFIG_INSTRUMENTATION_SYSCALLS)
    43 uint64_t     tm_start = hal_get_cycles();
     41#if DEBUG_SYS_PLACE_FORK || DEBUG_SYSCALLS_ERROR || CONFIG_INSTRUMENTATION_SYSCALLS
     42uint64_t    tm_start = hal_get_cycles();
     43process_t * process  = this->process;
    4444#endif
    4545
     
    5555       
    5656#if DEBUG_SYSCALLS_ERROR
     57if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start );
    5758printk("\n[ERROR] in %s : thread[%x,‰x] / illegal cxy argument %x\n",
    5859__FUNCTION__ , process->pid , this->trdid , cxy );
  • trunk/kernel/syscalls/sys_read.c

    r664 r670  
    22 * sys_read.c - Kernel function implementing the "read" system call.
    33 *
    4  * Author     Alain Greiner (2016,2017,2018,2019)
     4 * Author     Alain Greiner (2016,2017,2018,2019,2020)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    3333#include <thread.h>
    3434#include <printk.h>
     35#include <pipe.h>
    3536#include <process.h>
    3637
     
    7374    xptr_t        process_owner_xp = process->owner_xp;
    7475 
    75 #if (DEBUG_SYS_READ || CONFIG_INSTRUMENTATION_SYSCALLS)
     76#if DEBUG_SYS_READ || DEBUG_SYSCALLS_ERROR || CONFIG_INSTRUMENTATION_SYSCALLS
    7677uint64_t     tm_start = hal_get_cycles();
    7778#endif
     
    9293
    9394#if DEBUG_SYSCALLS_ERROR
    94 printk("\n[ERROR] in %s : thread[%x,%x] illegal file descriptor index %d\n",
     95if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     96printk("\n[ERROR] in %s : thread[%x,%x] / illegal file descriptor index %d\n",
    9597__FUNCTION__ , process->pid, this->trdid, file_id );
    9698#endif
     
    106108
    107109#if DEBUG_SYSCALLS_ERROR
    108 printk("\n[ERROR] in %s : thread[%x,%x] user buffer unmapped %x\n",
     110if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     111printk("\n[ERROR] in %s : thread[%x,%x] / user buffer unmapped %x\n",
    109112__FUNCTION__ , process->pid, this->trdid, (intptr_t)vaddr );
    110113#endif
     
    120123
    121124#if DEBUG_SYSCALLS_ERROR
    122 printk("\n[ERROR] in %s : thread[%x,%x] undefined fd_id %d\n",
     125if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     126printk("\n[ERROR] in %s : thread[%x,%x] / undefined fd_id %d\n",
    123127__FUNCTION__, process->pid, this->trdid, file_id );
    124128#endif
     
    140144    hal_enable_irq( &save_sr );
    141145
     146    // check file readable
     147    if( (file_attr & FD_ATTR_READ_ENABLE) == 0 )
     148    {
     149
     150#if DEBUG_SYSCALLS_ERROR
     151if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     152printk("\n[ERROR] in %s : thread[%x,%x] / file %d not readable\n",
     153__FUNCTION__, process->pid, this->trdid, file_id );
     154#endif
     155        hal_restore_irq( save_sr );
     156        this->errno = EBADFD;
     157        return -1;
     158    }
     159
    142160    // action depend on file type:
    143 
    144     if( file_type == INODE_TYPE_FILE )      // read from file mapper
    145     {
    146         // check file readable
    147         if( (file_attr & FD_ATTR_READ_ENABLE) == 0 )
    148             {
    149 
    150 #if DEBUG_SYSCALLS_ERROR
    151 printk("\n[ERROR] in %s : thread[%x,%x] file %d not readable\n",
    152 __FUNCTION__, process->pid, this->trdid, file_id );
    153 #endif
    154             hal_restore_irq( save_sr );
    155                     this->errno = EBADFD;
    156                     return -1;
    157             }
    158 
     161    if( file_type == FILE_TYPE_REG )                           // read from mapper
     162    {
    159163        // try to move count bytes from mapper
    160         nbytes = vfs_user_move( true,               // from mapper to buffer
     164        nbytes = vfs_user_move( true,   //  from mapper
    161165                                file_xp,
    162166                                vaddr,
    163167                                count );
    164168    }
    165     else if( file_type == INODE_TYPE_DEV )  // read from TXT device
     169    else if( file_type == FILE_TYPE_DEV )                      // read from TXT device
    166170    {
    167171        // get cluster and pointers on TXT_RX chdev
     
    176180        {
    177181            // extended pointer on TXT owner process
    178             txt_owner_xp  = hal_remote_l64( XPTR( chdev_cxy , &chdev_ptr->ext.txt.owner_xp ) );
    179 
     182            txt_owner_xp  = hal_remote_l64( XPTR( chdev_cxy ,
     183                                                  &chdev_ptr->ext.txt.owner_xp ) );
    180184            // wait for TXT_RX ownership
    181185            if ( process_owner_xp != txt_owner_xp )
     
    197201
    198202        // try to move count bytes from TXT device
    199         nbytes = devfs_user_move( true,             // from device to buffer
     203        nbytes = devfs_user_move( true,    // from device
    200204                                  file_xp,
    201205                                  vaddr,
    202206                                  count );
    203207    }
    204     else    // not FILE and not DEV
    205     {
    206 
    207 #if DEBUG_SYSCALLS_ERROR
    208 printk("\n[ERROR] in %s : thread[%x,%x] / illegal inode type %\n",
     208    else if( (file_type == FILE_TYPE_PIPE) ||
     209             (file_type == FILE_TYPE_FIFO) )                  // read from pipe
     210    {
     211        // try to move count bytes from pipe
     212        nbytes = pipe_user_move( true,    // from pipe
     213                                 file_xp,
     214                                 vaddr,
     215                                 count );
     216    }   
     217    else                                                      // unsupported type
     218    {
     219
     220#if DEBUG_SYSCALLS_ERROR
     221if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     222printk("\n[ERROR] in %s : thread[%x,%x] / unsupported inode type %d\n",
    209223__FUNCTION__, vfs_inode_type_str( file_type ) );
    210224#endif
     
    219233
    220234#if DEBUG_SYSCALLS_ERROR
     235if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
    221236printk("\n[ERROR] in %s : thread[%x,‰x] cannot read data from file %d\n",
    222237__FUNCTION__, process->pid, this->trdid, file_id );
  • trunk/kernel/syscalls/sys_readdir.c

    r637 r670  
    22 * sys_readdir.c - Copy one entry from an open VFS directory to an user buffer.
    33 *
    4  * Author    Alain Greiner (2016,2017,2018,2019)
     4 * Author    Alain Greiner (2016,2017,2018,2019,2020)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    5151        process_t * process = this->process;   // client process
    5252
    53 #if (DEBUG_SYS_READDIR || CONFIG_INSTRUMENTATION_SYSCALLS)
     53#if (DEBUG_SYS_READDIR || DEBUG_SYSCALLS_ERROR || CONFIG_INSTRUMENTATION_SYSCALLS)
    5454uint64_t     tm_start = hal_get_cycles();
    5555#endif
     
    6161#endif
    6262 
    63     // check buffer in user space
     63    // check dirent buffer in user space
    6464    error = vmm_get_vseg( process , (intptr_t)buffer, &vseg );
    6565
     
    6868
    6969#if DEBUG_SYSCALLS_ERROR
    70 printk("\n[ERROR] in %s / thread[%x,%x] : user buffer %x unmapped\n",
     70if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     71printk("\n[ERROR] in %s : thread[%x,%x] / dirent user buffer %x unmapped\n",
    7172__FUNCTION__ , process->pid , this->trdid, buffer );
    7273#endif
     
    8485
    8586#if DEBUG_SYSCALLS_ERROR
    86 printk("\n[ERROR] in %s / thread[%x,%x] : dirp %x not registered\n",
     87if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     88printk("\n[ERROR] in %s : thread[%x,%x] / dirp %x not registered\n",
    8789__FUNCTION__ , process->pid , this->trdid, dirp );
    8890#endif
     
    106108
    107109#if (DEBUG_SYS_READDIR & 1)
    108 if( DEBUG_SYS_READDIR < tm_start )
     110if( DEBUG_SYS_READDIR < (uint32_t)tm_start )
    109111printk("\n[%s] entries = %d / current = %d / direntp = %x\n",
    110112__FUNCTION__, entries, current, direntp );
     
    126128
    127129#if DEBUG_SYS_READDIR
    128 if( DEBUG_SYS_READDIR < tm_end )
     130if( DEBUG_SYS_READDIR < (uint32_t)tm_end )
    129131printk("\n[%s] thread[%x,%x] exit / cycle %d\n",
    130132__FUNCTION__, process->pid, this->trdid, (uint32_t)tm_end );
  • trunk/kernel/syscalls/sys_socket.c

    r664 r670  
    5353    else if( type == SOCK_ACCEPT      ) return "ACCEPT";
    5454    else if( type == SOCK_SEND        ) return "SEND";
    55     else if( type == SOCK_SENDTO      ) return "SENDTO";
    5655    else if( type == SOCK_RECV        ) return "RECV";
    57     else if( type == SOCK_RECVFROM    ) return "RECVFROM";
    5856    else                                return "undefined";
    5957}
     
    6664                reg_t  arg3 )
    6765{
    68 
    69     int32_t         ret;
     66    int             ret;
    7067    vseg_t        * vseg;
    7168
     
    7774    uint32_t        cmd = arg0;
    7875
    79 #if (DEBUG_SYS_SOCKET || CONFIG_INSTRUMENTATION_SYSCALLS)
     76#if DEBUG_SYS_SOCKET || DEBUG_SYSCALLS_ERROR || CONFIG_INSTRUMENTATION_SYSCALLS
    8077uint64_t     tm_start = hal_get_cycles();
    8178#endif
    8279
    8380#if DEBUG_SYS_SOCKET
    84 tm_start = hal_get_cycles();
    85 if( DEBUG_SYS_SOCKET < tm_start )
     81if( DEBUG_SYS_SOCKET < (uint32_t)tm_start )
    8682printk("\n[%s] thread[%x,%x] enter / %s / a1 %x / a2 %x / a3 %x / cycle %d\n",
    8783__FUNCTION__, process->pid, this->trdid, socket_cmd_type_str(cmd),
     
    10197
    10298#if DEBUG_SYSCALLS_ERROR
    103 printk("\n[ERROR] in %s for CREATE domain %d =! AF_INET\n",
    104 __FUNCTION__ , domain );
     99if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     100printk("\n[ERROR] in %s : thread[%x,%x] / CREATE / domain %d =! AF_INET\n",
     101__FUNCTION__ , process->pid , this->trdid , domain );
    105102#endif
    106103                this->errno = EINVAL;
     
    113110
    114111#if DEBUG_SYSCALLS_ERROR
    115 printk("\n[ERROR] in %s for CREATE : socket must be SOCK_STREAM(TCP) or SOCK_DGRAM(UDP)\n",
    116 __FUNCTION__ );
     112if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     113printk("\n[ERROR] in %s : thread[%x,%x] / CREATE / illegal socket type\n",
     114__FUNCTION__ , process->pid , this->trdid );
    117115#endif
    118116                this->errno = EINVAL;
     
    124122            ret = socket_build( domain , type );
    125123
    126             if( ret == -1 )
    127             {
    128 
    129 #if DEBUG_SYSCALLS_ERROR
    130 printk("\n[ERROR] in %s for CREATE : cannot create socket\n",
    131 __FUNCTION__ );
    132 #endif
    133                 this->errno = EINVAL;
    134             }
     124            if( ret < 0 )
     125            {
     126
     127#if DEBUG_SYSCALLS_ERROR
     128if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     129printk("\n[ERROR] in %s : thread[%x,%x] / CREATE / cannot create socket\n",
     130__FUNCTION__ , process->pid , this->trdid );
     131#endif
     132                this->errno = EINVAL;
     133                ret = -1;
     134                break;
     135            }
     136
    135137            break;
    136138        }
     
    146148
    147149#if DEBUG_SYSCALLS_ERROR
    148 printk("\n[ERROR] in %s for BIND : address %x unmapped\n",
    149 __FUNCTION__ , (intptr_t)arg2 );
     150if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     151printk("\n[ERROR] in %s : thread[%x,%x] / BIND / socket address %x unmapped\n",
     152__FUNCTION__ , process->pid , this->trdid , (intptr_t)arg2 );
    150153#endif
    151154                this->errno = EINVAL;
     
    164167                               k_sockaddr.sin_port );
    165168
    166             if( ret )
    167             {
    168 
    169 #if DEBUG_SYSCALLS_ERROR
    170 printk("\n[ERROR] in %s for BIND : cannot access socket[%x,%d]\n",
    171 __FUNCTION__ , process->pid, fdid );
    172 #endif
    173                 this->errno = EINVAL;
    174             }
     169            if( ret < 0 )
     170            {
     171
     172#if DEBUG_SYSCALLS_ERROR
     173if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     174printk("\n[ERROR] in %s : thread[%x,%x] / BIND / cannot access socket[%x,%d]\n",
     175__FUNCTION__ , process->pid , this->trdid ,  process->pid, fdid );
     176#endif
     177                this->errno = EINVAL;
     178                ret = -1;
     179                break;
     180            }
     181
    175182            break;
    176183        }
     
    184191                ret = socket_listen( fdid , max_pending );
    185192
    186             if( ret )
    187             {
    188 
    189 #if DEBUG_SYSCALLS_ERROR
    190 printk("\n[ERROR] in %s for LISTEN : cannot access socket[%x,%d]\n",
    191 __FUNCTION__ , process->pid, fdid );
    192 #endif
    193                 this->errno = EINVAL;
    194             }
     193            if( ret < 0 )
     194            {
     195
     196#if DEBUG_SYSCALLS_ERROR
     197if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     198printk("\n[ERROR] in %s : thread[%x,%x] / LISTEN / cannot access socket[%x,%d]\n",
     199__FUNCTION__ , process->pid , this->trdid ,  process->pid, fdid );
     200#endif
     201                this->errno = EINVAL;
     202                ret = -1;
     203                break;
     204            }
     205
    195206            break;
    196207        }
     
    206217
    207218#if DEBUG_SYSCALLS_ERROR
    208 printk("\n[ERROR] in %s for CONNECT : server address %x unmapped\n",
    209 __FUNCTION__ , (intptr_t)arg2 );
     219if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     220printk("\n[ERROR] in %s : thread[%x,%x] / CONNECT / server address %x unmapped\n",
     221__FUNCTION__ , process->pid , this->trdid , (intptr_t)arg2 );
    210222#endif
    211223                this->errno = EINVAL;
     
    223235                                  k_sockaddr.sin_addr,
    224236                                  k_sockaddr.sin_port );
    225 
    226             if( ret )
    227             {
    228 
    229 #if DEBUG_SYSCALLS_ERROR
    230 printk("\n[ERROR] in %s for CONNECT : cannot access socket[%x,%d]\n",
    231 __FUNCTION__ , process->pid, fdid );
    232 #endif
    233                 this->errno = EINVAL;
    234             }
     237            if( ret < 0 )
     238            {
     239
     240#if DEBUG_SYSCALLS_ERROR
     241if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     242printk("\n[ERROR] in %s : thread[%x,%x] / LISTEN / cannot access socket[%x,%d]\n",
     243__FUNCTION__ , process->pid , this->trdid ,  process->pid, fdid );
     244#endif
     245                this->errno = EINVAL;
     246                ret = -1;
     247                break;
     248            }
     249
    235250            break;
    236251        }
     
    246261
    247262#if DEBUG_SYSCALLS_ERROR
    248 printk("\n[ERROR] in %s for CONNECT : server address %x unmapped\n",
    249 __FUNCTION__ , (intptr_t)arg2 );
     263if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     264printk("\n[ERROR] in %s : thread[%x,%x] / CONNECT / server address %x unmapped\n",
     265__FUNCTION__ , process->pid , this->trdid , (intptr_t)arg2 );
    250266#endif
    251267                this->errno = EINVAL;
     
    259275                                 &k_sockaddr.sin_port );
    260276
    261             if( ret < 0 )
    262             {
    263 
    264 #if DEBUG_SYSCALLS_ERROR
    265 printk("\n[ERROR] in %s for ACCEPT : cannot access socket[%x,%d]\n",
    266 __FUNCTION__ , process->pid, fdid );
     277            if( ret )
     278            {
     279
     280#if DEBUG_SYSCALLS_ERROR
     281if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     282printk("\n[ERROR] in %s : thread[%x,%x] / ACCEPT / cannot access socket[%x,%d]\n",
     283__FUNCTION__ , process->pid , this->trdid , process->pid, fdid );
    267284#endif
    268285                this->errno = EINVAL;
     
    288305
    289306#if DEBUG_SYSCALLS_ERROR
    290 printk("\n[ERROR] in %s for SEND : buffer %x unmapped\n",
    291 __FUNCTION__ , (intptr_t)arg2 );
     307if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     308printk("\n[ERROR] in %s : thread[%x,%x] / SEND / buffer %x unmapped\n",
     309__FUNCTION__ , process->pid , this->trdid , (intptr_t)arg2 );
    292310#endif
    293311                this->errno = EINVAL;
     
    301319
    302320#if DEBUG_SYSCALLS_ERROR
    303 printk("\n[ERROR] in %s for SEND : buffer length is 0\n",
    304 __FUNCTION__ , (intptr_t)arg2 );
     321if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     322printk("\n[ERROR] in %s : thread[%x,%x] / SEND / buffer length is 0\n",
     323__FUNCTION__ , process->pid , this->trdid , (intptr_t)arg2 );
    305324#endif
    306325                this->errno = EINVAL;
     
    316335
    317336#if DEBUG_SYSCALLS_ERROR
    318 printk("\n[ERROR] in %s for SEND : cannot access socket[%x,%d] \n",
    319 __FUNCTION__ , process->pid, fdid );
     337if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     338printk("\n[ERROR] in %s : thread[%x,%x] / SEND / cannot access socket[%x,%d] \n",
     339__FUNCTION__ , process->pid , this->trdid , process->pid, fdid );
    320340#endif
    321341                this->errno = EINVAL;
     
    335355
    336356#if DEBUG_SYSCALLS_ERROR
    337 printk("\n[ERROR] in %s for SEND : buffer %x unmapped\n",
    338 __FUNCTION__ , (intptr_t)arg2 );
     357if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     358printk("\n[ERROR] in %s : thread[%x,%x] / RECV / buffer %x unmapped\n",
     359__FUNCTION__ , process->pid , this->trdid , (intptr_t)arg2 );
    339360#endif
    340361                this->errno = EINVAL;
     
    348369
    349370#if DEBUG_SYSCALLS_ERROR
    350 printk("\n[ERROR] in %s for SEND : buffer length is 0\n",
    351 __FUNCTION__ , (intptr_t)arg2 );
     371if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     372printk("\n[ERROR] in %s : thread[%x,%x] / RECV / buffer length is 0\n",
     373__FUNCTION__ , process->pid , this->trdid , (intptr_t)arg2 );
    352374#endif
    353375                this->errno = EINVAL;
     
    363385
    364386#if DEBUG_SYSCALLS_ERROR
    365 printk("\n[ERROR] in %s for RECV : cannot access socket[%x,%d] \n",
    366 __FUNCTION__ , process->pid, fdid );
     387if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     388printk("\n[ERROR] in %s : thread[%x,%x] / RECV / cannot access socket[%x,%d] \n",
     389__FUNCTION__ , process->pid , this->trdid , process->pid, fdid );
    367390#endif
    368391                this->errno = EINVAL;
     
    375398
    376399#if DEBUG_SYSCALLS_ERROR
    377 printk("\n[ERROR] in %s : undefined socket operation %d\n",
    378         __FUNCTION__ , cmd );
     400if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     401printk("\n[ERROR] in %s : thread[%x,%x] / undefined socket operation %d\n",
     402__FUNCTION__ , process->pid , this->trdid , cmd );
    379403#endif
    380404            this->errno = EINVAL;
  • trunk/kernel/syscalls/sys_thread_cancel.c

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

    r651 r670  
    105105
    106106        // block calling thread and mark it for delete,
    107         thread_delete( XPTR( local_cxy , this ) , false );   // not forced
     107        thread_delete_request( XPTR( local_cxy , this ) , false );   // not forced
    108108
    109109        // deschedule
  • trunk/kernel/syscalls/sys_trace.c

    r637 r670  
    3838
    3939    thread_t  * this    = CURRENT_THREAD;
    40     process_t * process = this->process;
    4140
    42 #if (DEBUG_SYS_TRACE || CONFIG_INSTRUMENTATION_SYSCALLS)
    43 uint64_t     tm_start = hal_get_cycles();
     41#if DEBUG_SYS_TRACE || DEBUG_SYSCALLS_ERROR || CONFIG_INSTRUMENTATION_SYSCALLS
     42process_t * process  = this->process;
     43uint64_t    tm_start = hal_get_cycles();
    4444#endif
    4545
     
    5555
    5656#if DEBUG_SYSCALLS_ERROR
    57 printk("\n[ERROR] in %s : illegal cxy argument %x / thread %x / process %x\n",
    58 __FUNCTION__ , cxy , this->trdid , process->pid );
     57if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     58printk("\n[ERROR] in %s : thread[%x,%x] / illegal cxy argument %x\n",
     59__FUNCTION__ , this->trdid , process->pid , cxy );
    5960#endif
    6061        this->errno = EINVAL;
     
    6869
    6970#if DEBUG_SYSCALLS_ERROR
    70 printk("\n[ERROR] in %s : illegal lid argument %x / thread %x / process %x\n",
    71 __FUNCTION__ , lid , this->trdid , process->pid );
     71if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     72printk("\n[ERROR] in %s : thread[%x,%x] / illegal lid argument %x\n",
     73__FUNCTION__ , this->trdid , process->pid , lid );
    7274#endif
    7375        this->errno = EINVAL;
     
    100102hal_atomic_add( &syscalls_occurences[SYS_TRACE] , 1 );
    101103#endif
     104
    102105    return 0;
    103106
  • trunk/kernel/syscalls/sys_write.c

    r664 r670  
    22 * sys_write.c - Kernel function implementing the "write" system call.
    33 *
    4  * Author        Alain Greiner (2016,2017,2018,2019)
     4 * Author        Alain Greiner (2016,2017,2018,2019,2020)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    3333#include <thread.h>
    3434#include <printk.h>
     35#include <pipe.h>
    3536#include <process.h>
    3637
     
    7172        process_t   * process = this->process;
    7273
    73 #if (DEBUG_SYS_WRITE || CONFIG_INSTRUMENTATION_SYSCALLS)
     74#if DEBUG_SYS_WRITE || DEBUG_SYSCALLS_ERROR || CONFIG_INSTRUMENTATION_SYSCALLS
    7475uint64_t     tm_start = hal_get_cycles();
    7576#endif
     
    9192
    9293#if DEBUG_SYSCALLS_ERROR
    93 printk("\n[ERROR] in %s : thread[%x,%x] illegal file descriptor index %d\n",
     94if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     95printk("\n[ERROR] in %s : thread[%x,%x] / illegal file descriptor index %d\n",
    9496__FUNCTION__, process->pid, this->trdid, file_id );
    9597#endif
     
    105107
    106108#if DEBUG_SYSCALLS_ERROR
    107 printk("\n[ERROR] in %s : thread[%x,%x] user buffer unmapped %x\n",
     109if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     110printk("\n[ERROR] in %s : thread[%x,%x] / user buffer unmapped %x\n",
    108111__FUNCTION__ , process->pid, this->trdid, (intptr_t)vaddr );
    109112#endif
     
    119122
    120123#if DEBUG_SYSCALLS_ERROR
    121 printk("\n[ERROR] in %s : thread[%x,%x] undefined file descriptor = %d\n",
     124if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     125printk("\n[ERROR] in %s : thread[%x,%x] / undefined file descriptor = %d\n",
    122126__FUNCTION__, process->pid, this->trdid, file_id );
    123127#endif
     
    139143    hal_enable_irq( &save_sr );
    140144
    141     // action depend on file type:
    142 
    143     if( file_type == INODE_TYPE_FILE )  // write to a file mapper
    144     {
    145         // check file writable
    146         if( (file_attr & FD_ATTR_WRITE_ENABLE) == 0 )
    147             {
    148 
    149 #if DEBUG_SYSCALLS_ERROR
    150 printk("\n[ERROR] in %s : thread[%x,%x] file %d not writable\n",
     145    // check file writable
     146    if( (file_attr & FD_ATTR_WRITE_ENABLE) == 0 )
     147    {
     148
     149#if DEBUG_SYSCALLS_ERROR
     150if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
     151printk("\n[ERROR] in %s : thread[%x,%x] / file %d not writable\n",
    151152__FUNCTION__ , process->pid, this->trdid, file_id );
    152153#endif
     
    154155                    this->errno = EBADFD;
    155156                    return -1;
    156             }
    157 
     157    }
     158
     159    // action depend on file type:
     160    if( file_type == FILE_TYPE_REG )                         // write to mapper
     161    {
    158162        // move count bytes to mapper
    159         nbytes = vfs_user_move( false,               // from buffer to mapper
     163        nbytes = vfs_user_move( false,    // to mapper
    160164                                file_xp,
    161165                                vaddr,
    162166                                count );
    163167    }
    164     else if( file_type == INODE_TYPE_DEV )  // write to TXT device
     168    else if( file_type == FILE_TYPE_DEV )                     // write to TXT device
    165169    {
    166170        // move count bytes to device
    167         nbytes = devfs_user_move( false,             // from buffer to device
     171        nbytes = devfs_user_move( false,  // to device
    168172                                  file_xp,
    169173                                  vaddr,
    170174                                  count );
    171175    }
    172     else  // not FILE and not DEV
    173     {
    174 
    175 #if DEBUG_SYSCALLS_ERROR
     176    else if( (file_type == FILE_TYPE_PIPE) ||
     177             (file_type == FILE_TYPE_FIFO) )                  // write to pipe
     178    {
     179        // move count bytes to pipe
     180        nbytes = pipe_user_move( false,   // to pipe
     181                                 file_xp,
     182                                 vaddr,
     183                                 count );
     184    }
     185    else                                                       // unsupported type
     186    {
     187
     188#if DEBUG_SYSCALLS_ERROR
     189if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
    176190printk("\n[ERROR] in %s : thread[%x,%x] / illegal inode type %\n",
    177191__FUNCTION__, vfs_inode_type_str( file_type ) );
     
    187201
    188202#if DEBUG_SYSCALLS_ERROR
     203if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
    189204printk("\n[ERROR] in %s : thread[%x,‰x] cannot write data to file %d\n",
    190205__FUNCTION__ , process->pid, this->trdid, file_id );
  • trunk/kernel/syscalls/syscalls.h

    r664 r670  
    3636struct mmap_attr_s;               // defined in vmm.h
    3737
    38 /******************************************************************************************
    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
    41  * terminating thread.
    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.
    52  * @ return 0 if success / return -1 if all locks not released or illegal argument.
    53  *****************************************************************************************/
    54 int sys_thread_exit( void * exit_status );
    55 
    56 /******************************************************************************************
    57  * [1] This function calls the scheduler for the core running the calling thread.
    58  ******************************************************************************************
    59  * @ x_size   : [out] number of clusters in a row.
    60  * @ y_size   : [out] number of clusters in a column.
    61  * @ ncores   : [out] number of cores per cluster.
    62  * @ return always 0.
    63  *****************************************************************************************/
    64 int sys_thread_yield( void );
    65 
    66 /******************************************************************************************
    67  * [2] This function creates a new user thread. The <user_attr> argument is a pointer
    68  * on astructure containing the thread attributes, defined in thread.h file.
    69  ******************************************************************************************
    70  * @ trdid_ptr   : [out] pointer on buffer for created thread trdid.
    71  * @ user_attr   : [in]  pointer on thread attributes structure.
    72  * @ start_func  : [in]  pointer on start function.
    73  * @ start_args  : [in]  pointer on start function arguments.
    74  * @ return 0 if success / return -1 if failure.
    75  *****************************************************************************************/
    76 int sys_thread_create( trdid_t               * trdid_ptr,
    77                        struct pthread_attr_s * user_attr,
    78                        void                  * start_func,
    79                        void                  * start_args );
    80 
    81 /******************************************************************************************
    82  * [3] This blocking function suspend execution of the calling thread until completion
    83  * of another target thread identified by the <trdid> argument.
    84  * The target thread must be joinable (running in ATTACHED mode), and must be different
    85  * from the calling thread.
    86  * If the <exit_value> argument is not NULL, the value passed to pthread_exit() by the
    87  * target thread is stored in the location referenced by exit_value.
    88  ******************************************************************************************
    89  * @ trdid     : [in]  target thread identifier.
    90  * @ thread    : [out] buffer for exit_value returned by target thread.
    91  * @ return 0 if success / return -1 if failure.
    92  *****************************************************************************************/
    93 int sys_thread_join( trdid_t    trdid,
    94                      void    ** exit_value );
    95 
    96 /******************************************************************************************
    97  * [4] This function detach a joinable thread.
    98  ******************************************************************************************
    99  * @ trdid   : thread identifier.
    100  * @ return 0 if success / return -1 if failure.
    101  *****************************************************************************************/
    102 int sys_thread_detach( trdid_t  trdid );
    103 
    104 /******************************************************************************************
    105  * [5] This function requests a target thread identified by its <trdid> argument
    106  * to be cancelled. It calls the thread_kill() function to block the target thread
    107  * on the THREAD_BLOCKED_GLOBAL condition, and to set the THREAD_FLAG_REQ_DELETE.
    108  * The thread will be detached from its process, and the memory allocated to the thread
    109  * descriptor will be released by the scheduler at the next scheduling point.
    110  ******************************************************************************************
    111  * @ trdid   : thread identifier.
    112  * @ return 0 if success / return -1 if illegal argument.
    113  *****************************************************************************************/
    114 int sys_thread_cancel( trdid_t  trdid );
    115 
    116 /******************************************************************************************
    117  * [6] This function implement all operations on a POSIX unnamed semaphore,
    118  * that can be shared by threads running in different clusters.
    119  * The kernel structure representing a remote semaphore is in the remote_sem.h file,
    120  * and the code implementing the operations is in the remore_sem.c file.
    121  ******************************************************************************************
    122  * @ vaddr         : semaphore virtual address in user space == identifier.
    123  * @ operation     : SEM_INIT / SEM_DESTROY / SEM_GETVALUE / SEM_POST / SEM_WAIT.
    124  * @ init_value    : initial semaphore value.
    125  * @ current_value : pointer on buffer for current semaphore value.
    126  * @ return 0 if success / return -1 if failure.
    127  *****************************************************************************************/
    128 int sys_sem( void       * vaddr,
    129              uint32_t     operation,
    130              uint32_t     init_value,
    131              uint32_t   * current_value );
    132 
    133 /******************************************************************************************
    134  * [7] This function implement all operations on a POSIX condition variable.
    135  * The kernel structure representing a condvar is defined in the remote_condvar.h file,
    136  * The code implementing the operations is defined in the remote_condvar.c file.
    137  ******************************************************************************************
    138  * @ vaddr     : condvar virtual address in user space == identifier.
    139  * @ operation : operation type (see below).
    140  * @ attr      : mutex virtual address in user space == identifier.
    141  * @ return 0 if success / return -1 if failure.
    142  *****************************************************************************************/
    143 int sys_condvar( void     * condvar,
    144                  uint32_t   operation,
    145                  void     * mutex );
    146 
    147 /******************************************************************************************
    148  * [8] This function implement all operations on a POSIX barrier.
     38
     39/******************************************************************************************
     40 * This function forces the calling thread to sleep, for a fixed number of cycles.
     41 ******************************************************************************************
     42 * cycles   : number of cycles.
     43 *****************************************************************************************/
     44int sys_alarm( uint32_t cycles );
     45
     46/******************************************************************************************
     47 * This function implement all operations on a POSIX barrier.
    14948 * The kernel structure representing a barrier is defined in the remote_barrier.h file.
    15049 * The code implementting the operations is defined in the remote_barrier.c file.
     
    16261
    16362/******************************************************************************************
    164  * [9] This function implement all operations on a POSIX mutex.
    165  * The kernel structure representing a barrier is defined in the remote_barrier.h file.
    166  * The code implementting the operations is defined in the remote_barrier.c file.
    167  ******************************************************************************************
    168  * @ vaddr     : mutex virtual address in user space == identifier.
    169  * @ operation : MUTEX_INIT / MUTEX_DESTROY / MUTEX_LOCK / MUTEX_UNLOCK
    170  * @ attr      : mutex attributes (non supported yet => must be 0).
    171  * @ return 0 if success / return -1 if failure.
    172  *****************************************************************************************/
    173 int sys_mutex( void     * vaddr,
    174                uint32_t   operation,
    175                uint32_t   count );
    176 
    177 /******************************************************************************************
    178  * [10] This function causes the file named <old> to be renamed as <new>.
    179  * If new exists, it is first removed.  Both old and new must be of the same type (both
    180  * must be either directories or non-directories) and must reside on the same file system.
    181  * It guarantees that an instance of <new> will always exist, even if the system should
    182  * crash in the middle of the operation.
    183  ******************************************************************************************
    184  * @ old      : old file name.
    185  * @ new      : new file name.
    186  * @ return 0 if success / return -1 if failure.
    187  *****************************************************************************************/
    188 int sys_rename( char *old,
    189                 char *new );
    190 
    191 /******************************************************************************************
    192  * [11] This function remove an existing mapping defined by the <addr> and <size>
    193  * arguments in user space. This can modify the number of vsegs:
    194  * (a) if the region is not entirely mapped in one existing vseg, it's an error.
    195  * (b) if the region has same base and size as an existing vseg, the vseg is removed.
    196  * (c) if the removed region cut the exiting vseg in two parts, it is resized.
    197  * (d) if the removed region cut the vseg in three parts, it is modified, and a new
    198  *     vseg is created with same type.
    199  * All existing VSL copies are updated.
    200 ******************************************************************************************
    201  * @ addr  : base address in user space.
    202  * @ size  : number of bytes.
    203  * @ return 0 if success / return -1 if failure.
    204  *****************************************************************************************/
    205 int sys_munmap( void     * addr,
    206                 uint32_t   size );
    207 
    208 /******************************************************************************************
    209  * [12] This function open or create an open file descriptor.
     63 * This function change the current working directory in reference process descriptor.
    21064 ******************************************************************************************
    21165 * @ pathname   : pathname (can be relative or absolute).
    212  * @ flags      : bit vector attributes (see in shared_fcntl.h file)
    213  * @ mode       : access rights.
    214  * @ return file descriptor index in fd_array if success / return -1 if failure.
    215  *****************************************************************************************/
    216 int sys_open( char       * pathname,
    217               uint32_t     flags,
    218               uint32_t     mode );
    219 
    220 /******************************************************************************************
    221  * [13] This function map physical memory (or a file) in the calling thread virtual space.
    222  * The <attr> argument is a pointer on a structure for arguments (see shared_mman.h).
    223  * The user defined virtual address (MAP_FIXED flag) is not supported.
    224  * TODO : the access rights checking is not implemented yet [AG]
    225  * TODO : the Copy on Write for MAP_PRIVATE is not implemented yet [AG]
    226  ******************************************************************************************
    227  * @ attr       : pointer on attributes structure.
    228  * @ returns 0 if success / returns -1 if failure.
    229  *****************************************************************************************/
    230 int sys_mmap( mmap_attr_t * attr );
    231 
    232 /******************************************************************************************
    233  * [14] This function read bytes from an open file identified by its file descriptor.
    234  * The file can be a regular file or character oriented device.
    235  * IRQs are enabled during this system call.
    236  ******************************************************************************************
    237  * @ file_id  : open file index in fd_array.
    238  * @ buf      : buffer virtual address in user space.
    239  * @ count    : number of bytes.
    240  * @ returns number of bytes actually read if success / returns -1 if failure.
    241  *****************************************************************************************/
    242 int sys_read( uint32_t   file_id,
    243               void     * buf,
    244               uint32_t   count );
    245 
    246 /******************************************************************************************
    247  * [15] This function writes bytes to an open file identified by its file descriptor.
    248  * The file can be a regular file or character oriented device. For a regular file,
    249  * the target inode "size" field is updated if (offset + count) is larger than the
    250  * current "size" value. The size value registered in the mappers of the parent(s)
    251  * directory are not modified and will be asynchronously updated when the file is closed.
    252  * IRQs are enabled during this system call.
    253  ******************************************************************************************
    254  * @ file_id  : open file index in fd_array.
    255  * @ buf      : buffer virtual address in user space.
    256  * @ count    : number of bytes.
    257  * @ returns number of bytes actually written if success / returns -1 if failure.
    258  *****************************************************************************************/
    259 int sys_write( uint32_t   file_id,
    260                void     * buf,
    261                uint32_t   count );
    262 
    263 /******************************************************************************************
    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.
    266  ******************************************************************************************
    267  * @ file_id  : open file index in fd_array.
    268  * @ offset   : used to compute new offset value.
    269  * @ whence   : operation type (see below).
    270  * @ returns new offset value if success / returns -1 if failure.
    271  *****************************************************************************************/
    272 int sys_lseek( xptr_t    file_id,
    273                uint32_t  offset,
    274                uint32_t  whence );
    275 
    276 /******************************************************************************************
    277  * [17] This function release the memory allocated for the file descriptor identified by
     66 * @ return 0 if success / returns -1 if failure.
     67 *****************************************************************************************/
     68int sys_chdir( char * pathname );
     69
     70/******************************************************************************************
     71 * This function change the acces rights for the file/directory inode identified by the
     72 * <pathname> argument, as specified by the <mode> argument.
     73 ******************************************************************************************
     74 * @ pathname : pathname (can be relative or absolute).
     75 * @ mode     : acces rights.
     76 * @ return 0 if success / returns -1 if failure.
     77 *****************************************************************************************/
     78int sys_chmod( char       * pathname,
     79               uint32_t     mode );
     80
     81/******************************************************************************************
     82 * This function release the memory allocated for the file descriptor identified by
    27883 * the <file_id> argument, and remove the fd array_entry in all copies of the process
    27984 * descriptor.
     
    28590
    28691/******************************************************************************************
    287  * [18] This function removes a directory entry identified by the <pathname> from the
    288  * directory, and decrement the link count of the file referenced by the link.
    289  * If the link count reduces to zero, and no process has the file open, then all resources
    290  * associated with the file are reclaimed.  If one or more process have the file open when
    291  * the last link is removed, the link is removed, but the removal of the file is delayed
    292  * until all references to it have been closed.
    293  ******************************************************************************************
    294  * @ pathname   : pathname (can be relative or absolute).
    295  * @ returns 0 if success / returns -1 if failure.
    296  *****************************************************************************************/
    297 int sys_unlink( char * pathname );
    298 
    299 /******************************************************************************************
    300  * [19] This function creates in the calling thread cluster an unnamed pipe, and two
    301  * (read and write) file descriptors.
    302  * TODO not implemented yet [AG]
    303  ******************************************************************************************
    304  * @ file_id[0] : [out] read only file descriptor index.
    305  * @ file_id[1] : [out] write only file descriptor index.
    306  * @ return 0 if success / return -1 if failure.
    307  *****************************************************************************************/
    308 int sys_pipe( uint32_t file_id[2] );
    309 
    310 /******************************************************************************************
    311  * [20] This function change the current working directory in reference process descriptor.
    312  ******************************************************************************************
    313  * @ pathname   : pathname (can be relative or absolute).
    314  * @ return 0 if success / returns -1 if failure.
    315  *****************************************************************************************/
    316 int sys_chdir( char * pathname );
    317 
    318 /******************************************************************************************
    319  * [21] This function implements the "mkdir" system call, creating a new directory in
    320  * the file system, as defined by the <pathname> argument, with the access permission
    321  * defined by the <rights> argument. All nodes but the last in the pathname must exist.
     92 * This function closes the directory identified by the <dirp> argument, and releases
     93 * all structures associated with the <dirp> pointer.
     94 ******************************************************************************************
     95 * @ dirp     : [in] user pointer on dirent array identifying the open directory.
     96 * @ return 0 if success / returns -1 if failure.
     97 *****************************************************************************************/
     98int sys_closedir( DIR * dirp );
     99
     100/******************************************************************************************
     101 * This function implement all operations on a POSIX condition variable.
     102 * The kernel structure representing a condvar is defined in the remote_condvar.h file,
     103 * The code implementing the operations is defined in the remote_condvar.c file.
     104 ******************************************************************************************
     105 * @ vaddr     : condvar virtual address in user space == identifier.
     106 * @ operation : operation type (see below).
     107 * @ attr      : mutex virtual address in user space == identifier.
     108 * @ return 0 if success / return -1 if failure.
     109 *****************************************************************************************/
     110int sys_condvar( void     * condvar,
     111                 uint32_t   operation,
     112                 void     * mutex );
     113
     114/******************************************************************************************
     115 * This debug function displays on the kernel terminal TXT0 an user defined string,
     116 * or the current state of a kernel structure, identified by the <type> argument.
     117 * The <arg0>, <arg1>, and <arg2> arguments depends on the structure type.
     118 ******************************************************************************************
     119 * type      : [in] type of display
     120 * arg0      : [in] type dependant argument.
     121 * arg1      : [in] type dependant argument.
     122 * arg2      : [in] type dependant argument.
     123 * @ return 0 if success / return -1 if illegal arguments
     124 *****************************************************************************************/
     125int sys_display( reg_t  type,
     126                 reg_t  arg0,
     127                 reg_t  arg1,
     128                 reg_t  arg2 );
     129
     130/******************************************************************************************
     131 * This function implement the "exec" system call on the kernel side.
     132 * It creates, in the same cluster as the calling thread, a new process descriptor,
     133 * and a new associated main thread descriptor, executing a new memory image defined
     134 * by the <filename> argument. This new process inherit from the old process the PID
     135 * and the PPID, as well as all open files registered in fd_array, including the TXT.
     136 * The old process descriptor, and all its threads are blocked, and marked for deletion.
     137 * Therefore the exec syscall does not return to the calling thread in case of success.
     138 * This function must be called by the main thread (thread 0 in owner cluster), of the
     139 * calling process, to destroy all process copies, and all other threads in all clusters.
     140 ******************************************************************************************
     141 * Implementation note:
     142 * It fill the calling process "exec_info" structure containing all informations required
     143 * to initialize the new process descriptor and the associated main thread. This includes:
     144 * - pathname to the new process .elf> file in VFS.
     145 * - array of string pointers defining the process arguments, and the associated strings.
     146 * - array of string pointers defining environment variables, and the associated strings.
     147 * To do this, it calls the process_exec_get_strings function, that copies all relevant
     148 * information from user space to kernel space, using functions defined in <hal_uspace.h>.
     149 * Then it calls the process_make_exec() function that returns only in case of failure.
     150 *
     151 * TODO : the <envs> argument is not supported yet and must be NULL.
     152 ******************************************************************************************
     153 * @ filename      : string pointer on .elf filename (pointer in user space)
     154 * @ user_args     : array of strings on process arguments (pointers in user space)
     155 * @ user_envs     : array of strings on environment variables (pointers in user space)
     156 * @ does not return if success / returns -1 if failure.
     157 *****************************************************************************************/
     158int sys_exec( char  * filename,
     159              char ** user_args,
     160              char ** user_envs );
     161
     162/******************************************************************************************
     163 * This function implements the "exit" system call terminating a POSIX process.
    322164 * It can be called by any thread running in any cluster.
    323  ******************************************************************************************
    324  * @ pathname  : pathname defining the new directory location in file system.
    325  * @ rights    : access rights (non used yet).
    326  * @ return 0 if success / return -1 if failure.
    327  *****************************************************************************************/
    328 int sys_mkdir( char     * pathname,
    329                uint32_t   rights );
    330 
    331 /******************************************************************************************
    332  * [22] This function creates a named FIFO file in the calling thread cluster.
    333  * The associated read and write file descriptors mut be be  explicitely created
    334  * using the sys_open() function.
    335  ******************************************************************************************
    336  * @ pathname   : pathname (can be relative or absolute).
    337  * @ mode       : access rights (as defined in chmod).
    338  * @ return 0 if success / returns -1 if failure.
    339  *****************************************************************************************/
    340 int sys_mkfifo( char     * pathname,
    341                 uint32_t   mode );
    342 
    343 /******************************************************************************************
    344  * [23] This function creates an user level directory descriptor (including the associated
    345  * array of user level dirents), and intialise it from the kernel directory mapper, that
    346  * contains all entries in this directory). The directory is identified by the <pathname>
    347  * argument. If the corresponding inode is missing in the Inode Tree, the inode is created,
    348  * but the directory must exist in the file system.
    349  * It returns a DIR pointer <dirp> on the dirent array in user space.
    350  * The calling process fd_array is NOT modified.
    351  ******************************************************************************************
    352  * @ pathname   : [in]  pathname (can be relative or absolute).
    353  * @ dirp       : [out] buffer for pointer on user directory (DIR).
    354  * @ return 0 if success / returns -1 if failure.
    355  *****************************************************************************************/
    356 int sys_opendir( char * pathname,
    357                  DIR ** dirp );
    358 
    359 /******************************************************************************************
    360  * [24] This function returns an user pointer on the dirent structure describing the
    361  * next directory entry in the directory identified by the <dirp> argument.
    362  ******************************************************************************************
    363  * @ dirp     : [in]  user pointer on dirent array identifying the open directory.
    364  * @ buffer   : [out] pointer on user buffer for a pointer on dirent in user space.
    365  * @ return O if success / returns -1 if failure.
    366  *****************************************************************************************/
    367 int sys_readdir( DIR            * dirp,
    368                  struct dirent ** buffer );
    369 
    370 /******************************************************************************************
    371  * [25] This function closes the directory identified by the <dirp> argument, and releases
    372  * all structures associated with the <dirp> pointer.
    373  ******************************************************************************************
    374  * @ dirp     : [in] user pointer on dirent array identifying the open directory.
    375  * @ return 0 if success / returns -1 if failure.
    376  *****************************************************************************************/
    377 int sys_closedir( DIR * dirp );
    378 
    379 /******************************************************************************************
    380  * [26] This function returns the pathname of the current working directory.
     165 * It uses both remote accesses to access the owner process descriptor, and the
     166 * RPC_PROCESS_SIGACTION to delete remote process copies and thread descriptors.
     167 * In the present implementation, this function implements actually the _exit():
     168 * - it does not flush open output streams.
     169 * - it does not close open streams.
     170 ******************************************************************************************
     171 * @ status   : terminaison status returned to parent process.
     172 * @ return 0 if success / return -1 if failure.
     173 *****************************************************************************************/
     174int sys_exit( uint32_t status );
     175
     176/******************************************************************************************
     177 * This generic function implements the non-standard FBF related syscalls.
     178 * The operation types mnemonics are defined in the <shared_fbf> file.
     179 * The supported operations are defined in the <almosmkh.h> & <almosmkh.c> files.
     180 * This function ckecks the syscall arguments, and call the relevant kernel function.
     181 ******************************************************************************************
     182 * @ arg0       : operation type (mnemonics defined in shared_fbf.h)
     183 * @ arg1       : depends on operation type
     184 * @ arg2       : depends on operation type
     185 * @ arg3       : depends on operation type
     186 * @ return 0 if success / return -1 if illegal argument.
     187 *****************************************************************************************/
     188int sys_fbf( reg_t   arg0,
     189             reg_t   arg1,
     190             reg_t   arg2,
     191             reg_t   arg3 );
     192
     193/******************************************************************************************
     194 * This function gives the process identified by the <pid> argument
     195 * the exclusive ownership of its TXT_TX terminal (put it in foreground).
     196 ******************************************************************************************
     197 * @ pid    : process identifier.
     198 * @ return 0 if success / return -1 if failure.
     199 *****************************************************************************************/
     200int sys_fg( pid_t   pid );
     201
     202/******************************************************************************************
     203 * This function implements the "fsync" system call.
     204 * It forces all modified pages of the file mapper identified by the <fd> argument
     205 * to be copied to the IOC device.
     206 * It can be called by any thread running in any cluster.
     207 * TODO not implemented yet.
     208 ******************************************************************************************
     209 * @ file_id   : file descriptor index in fd_array.
     210 * @ return 0 if success / return -1 if failure.
     211 *****************************************************************************************/
     212int sys_fsync( uint32_t file_id );
     213
     214/******************************************************************************************
     215 * This function implement the "fork" system call on the kernel side.
     216 * The calling process descriptor (parent process), and the associated thread descriptor
     217 * are replicated in a - likely - remote cluster, that becomes the child process owner.
     218 * The child process get a new PID, and is linked to the parent PID. The child process
     219 * inherit from its parent the memory image, and all open files (including the TXT).
     220 * The child process becomes the TXT terminal owner.
     221 * The target cluster depends on the "fork_user" flag and "fork_cxy" variable that can be
     222 * stored in the calling thread descriptor by the specific fork_place() system call.
     223 * If not, the kernel function makes a query to the DQDT to select the target cluster.
     224 ******************************************************************************************
     225 * @ if success, returns child process PID to parent, and return O to child.
     226 * @ if failure, returns -1 to parent / no child process is created.
     227 *****************************************************************************************/
     228int sys_fork( void );
     229
     230/******************************************************************************************
     231 * This function implements the non-standard "get_best_core" syscall.
     232 * It selects, in a macro-cluster specified by the <base_cxy> and <level> arguments,
     233 * the core that has the lowest load.
     234 * When an active core has been found in the target macro-cluster, it writes into the
     235 * <cxy> and <lid> buffers the cluster identifier and the core local index, and return 0.
     236 * It returns -1 in case of illegal arguments (level / cxy / lid).
     237 * It returns +1 if there is no active core in specified macro-cluster.
     238 ******************************************************************************************
     239 * @ base_cxy : [in]  any cluster identifier in macro-cluster.
     240 * @ level    : [in]  macro-cluster level in [1,2,3,4,5].
     241 * @ cxy      : [out] selected core cluster identifier.
     242 * @ lid      : [out] selected core local index in cluster.
     243 * @ return 0 if success / -1 if illegal arguments / +1 if no core in macro-clusters.
     244 *****************************************************************************************/
     245int sys_get_best_core( uint32_t   base_cxy,
     246                       uint32_t   level,
     247                       uint32_t * cxy,
     248                       uint32_t * lid );
     249
     250/******************************************************************************************
     251 * This function implement the non-standard get_config() syscall.
     252 * It returns the global hardware platform parameters in the <config> shared structure,
     253 * that is defined in the shared_almos.h file.
     254 ******************************************************************************************
     255 * @ config   : [out] pointer on the hard_config_t structure in user space.
     256 * @ return 0 if success / return -1 if illegal argument
     257 *****************************************************************************************/
     258int sys_get_config( struct hard_config_s * config );
     259
     260/******************************************************************************************
     261 * This function implements the non-standard get_core_id() syscall.
     262 * It returns in <cxy> and <lid> the calling core cluster and local index.
     263 ******************************************************************************************
     264 * @ cxy      : [out] cluster identifier (fixed format)
     265 * @ lid      : [out] core local index in cluster.
     266 * @ return 0 if success / return -1 if illegal arguments
     267 *****************************************************************************************/
     268int sys_get_core_id( uint32_t * cxy,
     269                     uint32_t * lid );
     270
     271/******************************************************************************************
     272 * This function implements the non-standard get_cycle() syscall.
     273 * It returns in a 64 bits user buffer the calling core cycles count.
     274 * It uses both the hardware register and the core descriptor cycles count to take
     275 * into account a possible harware register overflow  in 32 bits architectures.
     276 ******************************************************************************************
     277 * cycle    : [out] address of buffer in user space.
     278 * @ return 0 if success / return -1 if illegal arguments
     279 *****************************************************************************************/
     280int sys_get_cycle( uint64_t * cycle );
     281
     282/******************************************************************************************
     283 * This function returns the pathname of the current working directory.
    381284 ******************************************************************************************
    382285 * buf     : buffer addres in user space.
     
    388291
    389292/******************************************************************************************
    390  * [27] This function tests whether a given file descriptor dentified by the <file_id>
     293 * This function implements the non-standard "get_nb_cores" syscall.
     294 * It writes in the <ncores> buffer the number of cores in the target cluster <cxy>.
     295 ******************************************************************************************
     296 * @ cxy      : [in]  target cluster identifier.
     297 * @ ncores   : [out] number of cores / 0 if cluster cxy undefined in architecture.
     298 * @ return 0 if success / return -1 if illegal "ncores" arguments.
     299 *****************************************************************************************/
     300int sys_get_nb_cores( uint32_t   cxy,
     301                      uint32_t * ncores );
     302
     303/******************************************************************************************
     304 * This function implements the "getpid" system call on the kernel side.
     305 ******************************************************************************************
     306 * @ returns the process PID for the calling thread.
     307 *****************************************************************************************/
     308int sys_getpid( void );
     309
     310/******************************************************************************************
     311 * This function implements the non-standard "get_thread_info" syscall.
     312 * It copies in the user structure defined by the <info> argument the values registered
     313 * in the calling thread "thread_info_t" kernel structure.
     314 ******************************************************************************************
     315 * @ info      : [out] pointer on thread_info_t structure in user space.
     316 * @ return 0 if success / return -1 if illegal argument.
     317 *****************************************************************************************/
     318int sys_get_thread_info( thread_info_t * info );
     319
     320/******************************************************************************************
     321 * This function tests whether a given file descriptor dentified by the <file_id>
    391322 * argument is an open file descriptor referring to a terminal.
    392323 ******************************************************************************************
     
    397328
    398329/******************************************************************************************
    399  * [28] This function forces the calling thread to sleep, for a fixed number of cycles.
    400  ******************************************************************************************
    401  * cycles   : number of cycles.
    402  *****************************************************************************************/
    403 int sys_alarm( uint32_t cycles );
    404 
    405 /******************************************************************************************
    406  * [29] This function removes a directory file whose name is given by <pathname>.
    407  * The directory must not have any entries other than `.' and `..'.
    408  ******************************************************************************************
    409  * @ pathname   : pathname (can be relative or absolute).
    410  * @ return 0 if success / returns -1 if failure.
    411  *****************************************************************************************/
    412 int sys_rmdir( char * pathname );
    413 
    414 /******************************************************************************************
    415  * [30] This function implement the operations related to User Thread Local Storage.
    416  * It is actually implemented as an uint32_t variable in the thread descriptor.
    417  ******************************************************************************************
    418  * @ operation  : UTLS operation type as defined below.
    419  * @ value      : argument value for the UTLS_SET operation.
    420  * @ return value for the UTLS_GET and UTLS_GET_ERRNO / return -1 if failure.
    421  *****************************************************************************************/
    422 int sys_utls( uint32_t operation,
    423               uint32_t value );
    424 
    425 /******************************************************************************************
    426  * [31] This function change the acces rights for the file/dir identified by the
    427  * pathname argument.
    428  ******************************************************************************************
    429  * @ pathname   : pathname (can be relative or absolute).
    430  * @ rights     : acces rights.
    431  * @ return 0 if success / returns -1 if failure.
    432  *****************************************************************************************/
    433 int sys_chmod( char       * pathname,
    434                uint32_t     rights );
    435 
    436 /******************************************************************************************
    437  * [32] This function associate a specific signal handler to a given signal type.
    438  * The handlers for the SIGKILL and SIGSTOP signals cannot be redefined.
    439  ******************************************************************************************
    440  * @ sig_id    : index defining signal type (from 1 to 31).
    441  * @ handler   : pointer on fonction implementing the specific handler.
    442  * @ return 0 if success / returns -1 if failure.
    443  *****************************************************************************************/
    444 int sys_signal( uint32_t   sig_id,
    445                 void     * handler );
    446 
    447 /******************************************************************************************
    448  * [33] This function returns in the structure <tv>, defined in the time.h file,
    449  * the current time (in seconds & micro-seconds).
    450  * It is computed from the calling core descriptor.
    451  * The timezone is not supported.
    452  ******************************************************************************************
    453  * @ tv      : pointer on the timeval structure.
    454  * @ tz      : pointer on the timezone structure : must be NULL.       
    455  * @ return 0 if success / returns -1 if failure.
    456  *****************************************************************************************/
    457 int sys_timeofday( struct timeval  * tv,
    458                    struct timezone * tz );
    459 
    460 /******************************************************************************************
    461  * [34] This function implements the "kill" system call on the kernel side.
     330 * This function returns a non-zero value in the <is_fg> buffer when the process
     331 * identified by the <pid> argument is the current TXT owner.
     332 ******************************************************************************************
     333 * @ pid      : process identifier.
     334 * @ is_fg    : pointer on buffer.
     335 * @ return 0 if success / return -1 if failure.
     336 *****************************************************************************************/
     337int sys_is_fg( pid_t      pid,
     338               uint32_t * is_fg );
     339
     340/******************************************************************************************
     341 * This function implements the "kill" system call on the kernel side.
    462342 * It register the signal defined by the <sig_id> argument in all thread descriptors
    463343 * of a target process identified by the <pid> argument. This is done in all clusters
     
    477357
    478358/******************************************************************************************
    479  * [35] This function implements the "getpid" system call on the kernel side.
     359 * This function repositions the offset of the file descriptor identified by the
     360 * <file_id> argument, according to the operation type defined by the <whence> argument.
     361 ******************************************************************************************
     362 * @ file_id  : open file index in fd_array.
     363 * @ offset   : used to compute new offset value.
     364 * @ whence   : operation type (see below).
     365 * @ returns new offset value if success / returns -1 if failure.
     366 *****************************************************************************************/
     367int sys_lseek( xptr_t    file_id,
     368               uint32_t  offset,
     369               uint32_t  whence );
     370
     371/******************************************************************************************
     372 * This function implements the "mkdir" system call, creating a new directory in
     373 * the file system, as defined by the <pathname> argument, with the access permission
     374 * defined by the <rights> argument. All nodes but the last in the pathname must exist.
     375 * It can be called by any thread running in any cluster.
     376 ******************************************************************************************
     377 * @ pathname  : pathname defining the new directory location in file system.
     378 * @ rights    : access rights (non used yet).
     379 * @ return 0 if success / return -1 if failure.
     380 *****************************************************************************************/
     381int sys_mkdir( char     * pathname,
     382               uint32_t   rights );
     383
     384/******************************************************************************************
     385 * This function creates a new inode/dentry couple of type FIFO, and registers it in
     386 * the Inode-Tree, as specified by the <pathname> and <mode> arguments.
     387 * The associated file descriptors are created later, using the sys_open() function.
     388 ******************************************************************************************
     389 * @ pathname   : pathname (can be relative or absolute).
     390 * @ mode       : access rights (as defined in chmod).
     391 * @ return 0 if success / returns -1 if failure.
     392 *****************************************************************************************/
     393int sys_mkfifo( char     * pathname,
     394                uint32_t   mode );
     395
     396/******************************************************************************************
     397 * This function map physical memory (or a file) in the calling thread virtual space.
     398 * The <attr> argument is a pointer on a structure for arguments (see shared_mman.h).
     399 * The user defined virtual address (MAP_FIXED flag) is not supported.
     400 * TODO : the access rights checking is not implemented yet [AG]
     401 * TODO : the Copy on Write for MAP_PRIVATE is not implemented yet [AG]
     402 ******************************************************************************************
     403 * @ attr       : pointer on attributes structure.
     404 * @ returns 0 if success / returns -1 if failure.
     405 *****************************************************************************************/
     406int sys_mmap( mmap_attr_t * attr );
     407
     408/******************************************************************************************
     409 * This function remove an existing mapping defined by the <addr> and <size>
     410 * arguments in user space. This can modify the number of vsegs:
     411 * (a) if the region is not entirely mapped in one existing vseg, it's an error.
     412 * (b) if the region has same base and size as an existing vseg, the vseg is removed.
     413 * (c) if the removed region cut the exiting vseg in two parts, it is resized.
     414 * (d) if the removed region cut the vseg in three parts, it is modified, and a new
     415 *     vseg is created with same type.
     416 * All existing VSL copies are updated.
     417******************************************************************************************
     418 * @ addr  : base address in user space.
     419 * @ size  : number of bytes.
     420 * @ return 0 if success / return -1 if failure.
     421 *****************************************************************************************/
     422int sys_munmap( void     * addr,
     423                uint32_t   size );
     424
     425/******************************************************************************************
     426 * This function implement all operations on a POSIX mutex.
     427 * The kernel structure representing a barrier is defined in the remote_barrier.h file.
     428 * The code implementting the operations is defined in the remote_barrier.c file.
     429 ******************************************************************************************
     430 * @ vaddr     : mutex virtual address in user space == identifier.
     431 * @ operation : MUTEX_INIT / MUTEX_DESTROY / MUTEX_LOCK / MUTEX_UNLOCK
     432 * @ attr      : mutex attributes (non supported yet => must be 0).
     433 * @ return 0 if success / return -1 if failure.
     434 *****************************************************************************************/
     435int sys_mutex( void     * vaddr,
     436               uint32_t   operation,
     437               uint32_t   count );
     438
     439/******************************************************************************************
     440 * This function creates a new file descriptor for an existing inode.
     441 * It creates a new inode if required by the flags.
     442 ******************************************************************************************
     443 * @ pathname   : pathname in the inode tree (can be relative or absolute).
     444 * @ flags      : bit vector attributes (see in shared_fcntl.h file)
     445 * @ mode       : access rights.
     446 * @ return file descriptor index in fd_array if success / return -1 if failure.
     447 *****************************************************************************************/
     448int sys_open( char       * pathname,
     449              uint32_t     flags,
     450              uint32_t     mode );
     451
     452/******************************************************************************************
     453 * This function creates an user level directory descriptor (including the associated
     454 * array of user level dirents), and intialise it from the kernel directory mapper, that
     455 * contains all entries in this directory). The directory is identified by the <pathname>
     456 * argument. If the corresponding inode is missing in the Inode Tree, the inode is created,
     457 * but the directory must exist in the file system.
     458 * It returns a DIR pointer <dirp> on the dirent array in user space.
     459 * The calling process fd_array is NOT modified.
     460 ******************************************************************************************
     461 * @ pathname   : [in]  pathname (can be relative or absolute).
     462 * @ dirp       : [out] buffer for pointer on user directory (DIR).
     463 * @ return 0 if success / returns -1 if failure.
     464 *****************************************************************************************/
     465int sys_opendir( char * pathname,
     466                 DIR ** dirp );
     467
     468/******************************************************************************************
     469 * This function creates in the calling thread cluster an unnamed pipe, implemented
     470 * as a remote_buffer_t, creates two (read and write) file descriptors, and links these
     471 * two file descriptors to the pipe.
     472 * TODO : the dynamic memory allocation in case of buffer full is not implemented.
     473 ******************************************************************************************
     474 * @ fd   : pointeur on a 2 slots array of fdid : fd[0] read / fd[1] write.
     475 * @ return 0 if success / return -1 if failure.
     476 *****************************************************************************************/
     477int sys_pipe( fdid_t * fd );
     478
     479/******************************************************************************************
     480 * This function implements the non-standard place_fork() syscall.
     481 * It can be used to specify the target cluster <cxy> for a new process created
     482 * by a subsequent fork() syscall.
     483 * WARNING: it must be called before each fork() syscall, as the placement specification
     484 *          is reset by the fork syscall.
     485 ******************************************************************************************
     486 * @ cxy    : cluster identifier.
     487 * @ return 0 if success / return -1 if failure.
     488 *****************************************************************************************/
     489int sys_place_fork( uint32_t cxy );
     490
     491/******************************************************************************************
     492 * This function read bytes from an open file identified by its file descriptor.
     493 * The file can be a regular file or character oriented device.
     494 * IRQs are enabled during this system call.
     495 ******************************************************************************************
     496 * @ file_id  : open file index in fd_array.
     497 * @ buf      : buffer virtual address in user space.
     498 * @ count    : number of bytes.
     499 * @ returns number of bytes actually read if success / returns -1 if failure.
     500 *****************************************************************************************/
     501int sys_read( uint32_t   file_id,
     502              void     * buf,
     503              uint32_t   count );
     504
     505/******************************************************************************************
     506 * This function returns an user pointer on the dirent structure describing the
     507 * next directory entry in the directory identified by the <dirp> argument.
     508 ******************************************************************************************
     509 * @ dirp     : [in]  user pointer on dirent array identifying the open directory.
     510 * @ buffer   : [out] pointer on user buffer for a pointer on dirent in user space.
     511 * @ return O if success / returns -1 if failure.
     512 *****************************************************************************************/
     513int sys_readdir( DIR            * dirp,
     514                 struct dirent ** buffer );
     515
     516/******************************************************************************************
     517 * This function causes the file named <old> to be renamed as <new>.
     518 * If new exists, it is first removed.  Both old and new must be of the same type (both
     519 * must be either directories or non-directories) and must reside on the same file system.
     520 * It guarantees that an instance of <new> will always exist, even if the system should
     521 * crash in the middle of the operation.
     522 ******************************************************************************************
     523 * @ old      : old file name.
     524 * @ new      : new file name.
     525 * @ return 0 if success / return -1 if failure.
     526 *****************************************************************************************/
     527int sys_rename( char *old,
     528                char *new );
     529
     530/******************************************************************************************
     531 * This function removes a directory file whose name is given by <pathname>.
     532 * The directory must not have any entries other than `.' and `..'.
     533 ******************************************************************************************
     534 * @ pathname   : pathname (can be relative or absolute).
     535 * @ return 0 if success / returns -1 if failure.
     536 *****************************************************************************************/
     537int sys_rmdir( char * pathname );
     538
     539/******************************************************************************************
     540 * This function implement all operations on a POSIX unnamed semaphore,
     541 * that can be shared by threads running in different clusters.
     542 * The kernel structure representing a remote semaphore is in the remote_sem.h file,
     543 * and the code implementing the operations is in the remore_sem.c file.
     544 ******************************************************************************************
     545 * @ vaddr         : semaphore virtual address in user space == identifier.
     546 * @ operation     : SEM_INIT / SEM_DESTROY / SEM_GETVALUE / SEM_POST / SEM_WAIT.
     547 * @ init_value    : initial semaphore value.
     548 * @ current_value : pointer on buffer for current semaphore value.
     549 * @ return 0 if success / return -1 if failure.
     550 *****************************************************************************************/
     551int sys_sem( void       * vaddr,
     552             uint32_t     operation,
     553             uint32_t     init_value,
     554             uint32_t   * current_value );
     555
     556/******************************************************************************************
     557 * This function associate a specific signal handler to a given signal type.
     558 * The handlers for the SIGKILL and SIGSTOP signals cannot be redefined.
    480559 ******************************************************************************************
    481  * @ returns the process PID for the calling thread.
    482  *****************************************************************************************/
    483 int sys_getpid( void );
    484 
    485 /******************************************************************************************
    486  * [36] This function implement the "fork" system call on the kernel side.
    487  * The calling process descriptor (parent process), and the associated thread descriptor
    488  * are replicated in a - likely - remote cluster, that becomes the child process owner.
    489  * The child process get a new PID, and is linked to the parent PID. The child process
    490  * inherit from its parent the memory image, and all open files (including the TXT).
    491  * The child process becomes the TXT terminal owner.
    492  * The target cluster depends on the "fork_user" flag and "fork_cxy" variable that can be
    493  * stored in the calling thread descriptor by the specific fork_place() system call.
    494  * If not, the kernel function makes a query to the DQDT to select the target cluster.
    495  ******************************************************************************************
    496  * @ if success, returns child process PID to parent, and return O to child.
    497  * @ if failure, returns -1 to parent / no child process is created.
    498  *****************************************************************************************/
    499 int sys_fork( void );
    500 
    501 /******************************************************************************************
    502  * [37] This function implement the "exec" system call on the kernel side.
    503  * It creates, in the same cluster as the calling thread, a new process descriptor,
    504  * and a new associated main thread descriptor, executing a new memory image defined
    505  * by the <filename> argument. This new process inherit from the old process the PID
    506  * and the PPID, as well as all open files (including the TXT).
    507  * The old process descriptor, and all its threads are blocked, and marked for deletion.
    508  * Therefore the exec syscall does not return to the calling thread in case of success.
    509  * This function build an exec_info_t structure containing the new process arguments,
    510  * as defined by the <arv> argument, and the new process environment variables,
    511  * as defined by the <envp>  argument.
    512  * TODO : the <argv> and <envp> arguments are not supported yet (both must be NULL).
    513  ******************************************************************************************
    514  * @ filename : string pointer on .elf filename (pointer in user space)
    515  * @ argv     : array of strings on process arguments (pointers in user space)
    516  * @ envp     : array of strings on environment variables (pointers in user space)
    517  * @ does not return if success / returns -1 if failure.
    518  *****************************************************************************************/
    519 int sys_exec( char  * filename,
    520               char ** argv,
    521               char ** envp );
    522 
    523 /******************************************************************************************
    524  * [38] This function  returns in the <stat> structure, defined in the "shared_syscalls.h"
     560 * @ sig_id    : index defining signal type (from 1 to 31).
     561 * @ handler   : pointer on fonction implementing the specific handler.
     562 * @ return 0 if success / returns -1 if failure.
     563 *****************************************************************************************/
     564int sys_signal( uint32_t   sig_id,
     565                void     * handler );
     566
     567/******************************************************************************************
     568 * This generic function implements the socket related syscalls.
     569 * The operation types mnemonics are defined in the <shared_socket> file.
     570 * The supported operations are defined in the <socket.h> & <socket.c> files.
     571 * This function ckecks the syscall arguments, and call the relevant kernel function.
     572 ******************************************************************************************
     573 * @ arg0       : operation type (mnemonics defined in shared_socket.h)
     574 * @ arg1       : depends on operation type
     575 * @ arg2       : depends on operation type
     576 * @ arg3       : depends on operation type
     577 * @ return 0 if success / return -1 if illegal argument.
     578 *****************************************************************************************/
     579int sys_socket( reg_t   arg0,
     580                reg_t   arg1,
     581                reg_t   arg2,
     582                reg_t   arg3 );
     583
     584/******************************************************************************************
     585 * This function  returns in the <stat> structure, defined in the "shared_syscalls.h"
    525586 * file, various informations on the file/directory identified by the <pathname> argument.
    526587 * TODO only the <st_ino>, <st_mode>,<st_uid>,<st_gid>,<st_size> are set.
     
    534595
    535596/******************************************************************************************
    536  * [39] This blocking function waits a change of a child process state, that can be:
     597 * This function implements the "sync" system call.
     598 * It forces all modified pages in all kernel mappers to be copied to the IOC device.
     599 * It can be called by any thread running in any cluster.
     600 * TODO not implemented yet.
     601 ******************************************************************************************
     602 * @ return 0 if success / return -1 if failure.
     603 *****************************************************************************************/
     604int sys_sync( void );
     605
     606/******************************************************************************************
     607 * This function returns in the structure <tv>, defined in the time.h file,
     608 * the current time (in seconds & micro-seconds).
     609 * It is computed from the calling core descriptor.
     610 * The timezone is not supported.
     611 ******************************************************************************************
     612 * @ tv      : pointer on the timeval structure.
     613 * @ tz      : pointer on the timezone structure : must be NULL.       
     614 * @ return 0 if success / returns -1 if failure.
     615 *****************************************************************************************/
     616int sys_timeofday( struct timeval  * tv,
     617                   struct timezone * tz );
     618
     619/******************************************************************************************
     620 * This function requests a target thread identified by its <trdid> argument
     621 * to be cancelled. It calls the thread_kill() function to block the target thread
     622 * on the THREAD_BLOCKED_GLOBAL condition, and to set the THREAD_FLAG_REQ_DELETE.
     623 * The thread will be detached from its process, and the memory allocated to the thread
     624 * descriptor will be released by the scheduler at the next scheduling point.
     625 ******************************************************************************************
     626 * @ trdid   : thread identifier.
     627 * @ return 0 if success / return -1 if illegal argument.
     628 *****************************************************************************************/
     629int sys_thread_cancel( trdid_t  trdid );
     630
     631/******************************************************************************************
     632 * This function creates a new user thread. The <user_attr> argument is a pointer
     633 * on astructure containing the thread attributes, defined in thread.h file.
     634 ******************************************************************************************
     635 * @ trdid_ptr   : [out] pointer on buffer for created thread trdid.
     636 * @ user_attr   : [in]  pointer on thread attributes structure.
     637 * @ start_func  : [in]  pointer on start function.
     638 * @ start_args  : [in]  pointer on start function arguments.
     639 * @ return 0 if success / return -1 if failure.
     640 *****************************************************************************************/
     641int sys_thread_create( trdid_t               * trdid_ptr,
     642                       struct pthread_attr_s * user_attr,
     643                       void                  * start_func,
     644                       void                  * start_args );
     645
     646/******************************************************************************************
     647 * This function detach a joinable thread.
     648 ******************************************************************************************
     649 * @ trdid   : thread identifier.
     650 * @ return 0 if success / return -1 if failure.
     651 *****************************************************************************************/
     652int sys_thread_detach( trdid_t  trdid );
     653
     654/******************************************************************************************
     655 * This function terminates the execution of the calling user thread, and makes
     656 * the <exit_status> pointer available to any successful pthread_join() with the
     657 * terminating thread.
     658 * - If the calling thread is the main thread, it calls the sys_exit() function to delete
     659 *   completely the user process. 
     660 * - if the calling thread is not the main thread, it registers the <exit_status> pointer
     661 *   in the thread descriptor, and calls the thread_delete() function, that will set the
     662 *   THREAD_SIG_EXIT signal, set the THREAD_BLOCKED_GLOBAL bit in thread descriptor, and
     663 *   deschedules. All memory allocated to the thread is released later by the scheduler.
     664 *   If the thread is in "detached" mode, the thread_delete() function implements
     665 *   the synchonisation with the joining thread.
     666 ******************************************************************************************
     667 * @ exit_status  : [out] pointer to be returned to joining thread if thread is attached.
     668 * @ return 0 if success / return -1 if all locks not released or illegal argument.
     669 *****************************************************************************************/
     670int sys_thread_exit( void * exit_status );
     671
     672/******************************************************************************************
     673 * This blocking function suspend execution of the calling thread until completion
     674 * of another target thread identified by the <trdid> argument.
     675 * The target thread must be joinable (running in ATTACHED mode), and must be different
     676 * from the calling thread.
     677 * If the <exit_value> argument is not NULL, the value passed to pthread_exit() by the
     678 * target thread is stored in the location referenced by exit_value.
     679 ******************************************************************************************
     680 * @ trdid     : [in]  target thread identifier.
     681 * @ thread    : [out] buffer for exit_value returned by target thread.
     682 * @ return 0 if success / return -1 if failure.
     683 *****************************************************************************************/
     684int sys_thread_join( trdid_t    trdid,
     685                     void    ** exit_value );
     686
     687/******************************************************************************************
     688 * This function block the calling thread on the THREAD_BLOCKED_GLOBAL condition,
     689 * and deschedule.
     690 ******************************************************************************************
     691 * @ return 0 if success / returns -1 if failure.
     692 *****************************************************************************************/
     693int sys_thread_sleep( void );
     694
     695/******************************************************************************************
     696 * This function unblock the thread identified by its <trdid> from the
     697 * THREAD_BLOCKED_GLOBAL condition.
     698 ******************************************************************************************
     699 * @ trdid  : target thread identifier.
     700 * @ return 0 if success / return -1 if failure.
     701 *****************************************************************************************/
     702int sys_thread_wakeup( trdid_t trdid );
     703
     704/******************************************************************************************
     705 * This function calls the scheduler for the core running the calling thread.
     706 ******************************************************************************************
     707 * @ x_size   : [out] number of clusters in a row.
     708 * @ y_size   : [out] number of clusters in a column.
     709 * @ ncores   : [out] number of cores per cluster.
     710 * @ return always 0.
     711 *****************************************************************************************/
     712int sys_thread_yield( void );
     713
     714/******************************************************************************************
     715 * This debug function is used to activate / desactivate the context switches trace
     716 * for a core identified by the <cxy> and <lid> arguments.
     717 * It can be called by any other thread in the same process.
     718 ******************************************************************************************
     719 * @ active     : activate trace if true / desactivate trace if false.
     720 * @ cxy        : cluster identifier.
     721 * @ lid        : core local index.
     722 * @ returns O if success / returns -1 if failure.
     723 *****************************************************************************************/
     724int sys_trace( bool_t   active,
     725               cxy_t    cxy,
     726               lid_t    lid );
     727
     728/******************************************************************************************
     729 * This function implement the operations related to User Thread Local Storage.
     730 * It is actually implemented as an uint32_t variable in the thread descriptor.
     731 ******************************************************************************************
     732 * @ operation  : UTLS operation type as defined below.
     733 * @ value      : argument value for the UTLS_SET operation.
     734 * @ return value for the UTLS_GET and UTLS_GET_ERRNO / return -1 if failure.
     735 *****************************************************************************************/
     736int sys_utls( uint32_t operation,
     737              uint32_t value );
     738
     739/******************************************************************************************
     740 * This function removes a directory entry identified by the <pathname> from the
     741 * directory, and decrement the link count of the file referenced by the link.
     742 * If the link count reduces to zero, and no process has the file open, then all resources
     743 * associated with the file are reclaimed.  If one or more process have the file open when
     744 * the last link is removed, the link is removed, but the removal of the file is delayed
     745 * until all references to it have been closed.
     746 ******************************************************************************************
     747 * @ pathname   : pathname (can be relative or absolute).
     748 * @ returns 0 if success / returns -1 if failure.
     749 *****************************************************************************************/
     750int sys_unlink( char * pathname );
     751
     752/******************************************************************************************
     753 * This blocking function waits a change of a child process state, that can be:
    537754 * - a termination of child following a process_make_exit().
    538755 * - a termination of child following a process_make_kill().
     
    558775
    559776/******************************************************************************************
    560  * [40] This function implement the non-standard get_config() syscall.
    561  * It returns the global hardware platform parameters in the <config> shared structure,
    562  * that is defined in the shared_almos.h file.
    563  ******************************************************************************************
    564  * @ config   : [out] pointer on the hard_config_t structure in user space.
    565  * @ return 0 if success / return -1 if illegal argument
    566  *****************************************************************************************/
    567 int sys_get_config( struct hard_config_s * config );
    568 
    569 /******************************************************************************************
    570  * [41] This function implements the non-standard get_core_id() syscall.
    571  * It returns in <cxy> and <lid> the calling core cluster and local index.
    572  ******************************************************************************************
    573  * @ cxy      : [out] cluster identifier (fixed format)
    574  * @ lid      : [out] core local index in cluster.
    575  * @ return 0 if success / return -1 if illegal arguments
    576  *****************************************************************************************/
    577 int sys_get_core_id( uint32_t * cxy,
    578                      uint32_t * lid );
    579 
    580 /******************************************************************************************
    581  * [42] This function implements the non-standard get_cycle() syscall.
    582  * It returns in a 64 bits user buffer the calling core cycles count.
    583  * It uses both the hardware register and the core descriptor cycles count to take
    584  * into account a possible harware register overflow  in 32 bits architectures.
    585  ******************************************************************************************
    586  * cycle    : [out] address of buffer in user space.
    587  * @ return 0 if success / return -1 if illegal arguments
    588  *****************************************************************************************/
    589 int sys_get_cycle( uint64_t * cycle );
    590 
    591 /******************************************************************************************
    592  * [43] This debug function displays on the kernel terminal TXT0 an user defined string,
    593  * or the current state of a kernel structure, identified by the <type> argument.
    594  * The <arg0>, <arg1>, and <arg2> arguments depends on the structure type.
    595  ******************************************************************************************
    596  * type      : [in] type of display
    597  * arg0      : [in] type dependant argument.
    598  * arg1      : [in] type dependant argument.
    599  * arg2      : [in] type dependant argument.
    600  * @ return 0 if success / return -1 if illegal arguments
    601  *****************************************************************************************/
    602 int sys_display( reg_t  type,
    603                  reg_t  arg0,
    604                  reg_t  arg1,
    605                  reg_t  arg2 );
    606 
    607 /******************************************************************************************
    608  * [44] This function implements the non-standard place_fork() syscall.
    609  * It can be used to specify the target cluster <cxy> for a new process created
    610  * by a subsequent fork() syscall.
    611  * WARNING: it must be called before each fork() syscall, as the placement specification
    612  *          is reset by the fork syscall.
    613  ******************************************************************************************
    614  * @ cxy    : cluster identifier.
    615  * @ return 0 if success / return -1 if failure.
    616  *****************************************************************************************/
    617 int sys_place_fork( uint32_t cxy );
    618 
    619 /******************************************************************************************
    620  * [45] This function block the calling thread on the THREAD_BLOCKED_GLOBAL condition,
    621  * and deschedule.
    622  ******************************************************************************************
    623  * @ return 0 if success / returns -1 if failure.
    624  *****************************************************************************************/
    625 int sys_thread_sleep( void );
    626 
    627 /******************************************************************************************
    628  * [46] This function unblock the thread identified by its <trdid> from the
    629  * THREAD_BLOCKED_GLOBAL condition.
    630  ******************************************************************************************
    631  * @ trdid  : target thread identifier.
    632  * @ return 0 if success / return -1 if failure.
    633  *****************************************************************************************/
    634 int sys_thread_wakeup( trdid_t trdid );
    635 
    636 /******************************************************************************************
    637  * [47] This debug function is used to activate / desactivate the context switches trace
    638  * for a core identified by the <cxy> and <lid> arguments.
    639  * It can be called by any other thread in the same process.
    640  ******************************************************************************************
    641  * @ active     : activate trace if true / desactivate trace if false.
    642  * @ cxy        : cluster identifier.
    643  * @ lid        : core local index.
    644  * @ returns O if success / returns -1 if failure.
    645  *****************************************************************************************/
    646 int sys_trace( bool_t   active,
    647                cxy_t    cxy,
    648                lid_t    lid );
    649 
    650 /******************************************************************************************
    651  * [48] This function gives the process identified by the <pid> argument
    652  * the exclusive ownership of its TXT_TX terminal (put it in foreground).
    653  ******************************************************************************************
    654  * @ pid    : process identifier.
    655  * @ return 0 if success / return -1 if failure.
    656  *****************************************************************************************/
    657 int sys_fg( pid_t   pid );
    658 
    659 /******************************************************************************************
    660  * [49] This function returns a non-zero value in the <is_fg> buffer when the process
    661  * identified by the <pid> argument is the current TXT owner.
    662  ******************************************************************************************
    663  * @ pid      : process identifier.
    664  * @ is_fg    : pointer on buffer.
    665  * @ return 0 if success / return -1 if failure.
    666  *****************************************************************************************/
    667 int sys_is_fg( pid_t      pid,
    668                uint32_t * is_fg );
    669 
    670 /******************************************************************************************
    671  * [50] This function implements the "exit" system call terminating a POSIX process.
    672  * It can be called by any thread running in any cluster.
    673  * It uses both remote accesses to access the owner process descriptor, and the
    674  * RPC_PROCESS_SIGACTION to delete remote process copies and thread descriptors.
    675  * In the present implementation, this function implements actually the _exit():
    676  * - it does not flush open output streams.
    677  * - it does not close open streams.
    678  ******************************************************************************************
    679  * @ status   : terminaison status returned to parent process.
    680  * @ return 0 if success / return -1 if failure.
    681  *****************************************************************************************/
    682 int sys_exit( uint32_t status );
    683 
    684 /******************************************************************************************
    685  * [51] This function implements the "sync" system call.
    686  * It forces all modified pages in all kernel mappers to be copied to the IOC device.
    687  * It can be called by any thread running in any cluster.
    688  * TODO not implemented yet.
    689  ******************************************************************************************
    690  * @ return 0 if success / return -1 if failure.
    691  *****************************************************************************************/
    692 int sys_sync( void );
    693 
    694 /******************************************************************************************
    695  * [52] This function implements the "fsync" system call.
    696  * It forces all modified pages of the file mapper identified by the <fd> argument
    697  * to be copied to the IOC device.
    698  * It can be called by any thread running in any cluster.
    699  * TODO not implemented yet.
    700  ******************************************************************************************
    701  * @ file_id   : file descriptor index in fd_array.
    702  * @ return 0 if success / return -1 if failure.
    703  *****************************************************************************************/
    704 int sys_fsync( uint32_t file_id );
    705 
    706 /******************************************************************************************
    707  * [53] This function implements the non-standard "get_best_core" syscall.
    708  * It selects, in a macro-cluster specified by the <base_cxy> and <level> arguments,
    709  * the core that has the lowest load.
    710  * When an active core has been found in the target macro-cluster, it writes into the
    711  * <cxy> and <lid> buffers the cluster identifier and the core local index, and return 0.
    712  * It returns -1 in case of illegal arguments (level / cxy / lid).
    713  * It returns +1 if there is no active core in specified macro-cluster.
    714  ******************************************************************************************
    715  * @ base_cxy : [in]  any cluster identifier in macro-cluster.
    716  * @ level    : [in]  macro-cluster level in [1,2,3,4,5].
    717  * @ cxy      : [out] selected core cluster identifier.
    718  * @ lid      : [out] selected core local index in cluster.
    719  * @ return 0 if success / -1 if illegal arguments / +1 if no core in macro-clusters.
    720  *****************************************************************************************/
    721 int sys_get_best_core( uint32_t   base_cxy,
    722                        uint32_t   level,
    723                        uint32_t * cxy,
    724                        uint32_t * lid );
    725 
    726 /******************************************************************************************
    727  * [54] This function implements the non-standard "get_nb_cores" syscall.
    728  * It writes in the <ncores> buffer the number of cores in the target cluster <cxy>.
    729  ******************************************************************************************
    730  * @ cxy      : [in]  target cluster identifier.
    731  * @ ncores   : [out] number of cores / 0 if cluster cxy undefined in architecture.
    732  * @ return 0 if success / return -1 if illegal "ncores" arguments.
    733  *****************************************************************************************/
    734 int sys_get_nb_cores( uint32_t   cxy,
    735                       uint32_t * ncores );
    736 
    737 /******************************************************************************************
    738  * [55] This function implements the non-standard "get_thread_info" syscall.
    739  * It copies in the user structure defined by the <info> argument the values registered
    740  * in the calling thread "thread_info_t" kernel structure.
    741  ******************************************************************************************
    742  * @ info      : [out] pointer on thread_info_t structure in user space.
    743  * @ return 0 if success / return -1 if illegal argument.
    744  *****************************************************************************************/
    745 int sys_get_thread_info( thread_info_t * info );
    746 
    747 /******************************************************************************************
    748  * [56] This generic function implements the non-standard FBF related syscalls.
    749  * The operation types mnemonics are defined in the <shared_fbf> file.
    750  * The supported operations are defined in the <almosmkh.h> & <almosmkh.c> files.
    751  * This function ckecks the syscall arguments, and call the relevant kernel function.
    752  ******************************************************************************************
    753  * @ arg0       : operation type (mnemonics defined in shared_fbf.h)
    754  * @ arg1       : depends on operation type
    755  * @ arg2       : depends on operation type
    756  * @ arg3       : depends on operation type
    757  * @ return 0 if success / return -1 if illegal argument.
    758  *****************************************************************************************/
    759 int sys_fbf( reg_t   arg0,
    760              reg_t   arg1,
    761              reg_t   arg2,
    762              reg_t   arg3 );
    763 
    764 /******************************************************************************************
    765  * [57] This generic function implements the socket related syscalls.
    766  * The operation types mnemonics are defined in the <shared_socket> file.
    767  * The supported operations are defined in the <socket.h> & <socket.c> files.
    768  * This function ckecks the syscall arguments, and call the relevant kernel function.
    769  ******************************************************************************************
    770  * @ arg0       : operation type (mnemonics defined in shared_socket.h)
    771  * @ arg1       : depends on operation type
    772  * @ arg2       : depends on operation type
    773  * @ arg3       : depends on operation type
    774  * @ return 0 if success / return -1 if illegal argument.
    775  *****************************************************************************************/
    776 int sys_socket( reg_t   arg0,
    777                 reg_t   arg1,
    778                 reg_t   arg2,
    779                 reg_t   arg3 );
     777 * This function writes bytes to an open file identified by its file descriptor.
     778 * The file can be a regular file or character oriented device. For a regular file,
     779 * the target inode "size" field is updated if (offset + count) is larger than the
     780 * current "size" value. The size value registered in the mappers of the parent(s)
     781 * directory are not modified and will be asynchronously updated when the file is closed.
     782 * IRQs are enabled during this system call.
     783 ******************************************************************************************
     784 * @ file_id  : open file index in fd_array.
     785 * @ buf      : buffer virtual address in user space.
     786 * @ count    : number of bytes.
     787 * @ returns number of bytes actually written if success / returns -1 if failure.
     788 *****************************************************************************************/
     789int sys_write( uint32_t   file_id,
     790               void     * buf,
     791               uint32_t   count );
     792
    780793
    781794#endif  // _SYSCALLS_H_
Note: See TracChangeset for help on using the changeset viewer.