Changeset 23 for trunk/kernel/kern


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

Introduce syscalls.

Location:
trunk/kernel/kern
Files:
2 added
19 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/kern/chdev.c

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

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

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

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

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

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

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

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

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

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

    r14 r23  
    44 * Authors  Ghassan Almaless (2008,2009,2010,2011,2012)
    55 *          Mohamed Lamine Karaoui (2015)
    6  *          Alain Greiner (2016)
     6 *          Alain Greiner (2016,2017)
    77 *
    88 * Copyright (c) UPMC Sorbonne Universites
     
    4747#include <process.h>
    4848#include <elf.h>
     49#include <syscalls.h>
    4950
    5051//////////////////////////////////////////////////////////////////////////////////////////
     
    103104                             pid_t       ppid )
    104105{
    105     // reset signal manager  TODO [AG]
    106 
    107     // reset the file descriptors array
     106    // reset reference process vmm
     107    vmm_init( process );
     108
     109    // reset reference process file descriptors array
    108110        process_fd_init( process );
    109111
    110     // reset the process files structures and cd_lock
     112    // reset reference process files structures and cd_lock
    111113        process->vfs_root_xp     = XPTR_NULL;
     114        process->vfs_bin_xp      = XPTR_NULL;
    112115        process->vfs_cwd_xp      = XPTR_NULL;
    113         process->vfs_bin_xp      = XPTR_NULL;
    114 
    115     spinlock_init( &process->cd_lock );
     116    remote_rwlock_init( XPTR( local_cxy , &process->cwd_lock ) );
    116117
    117118    // reset children list root
     
    119120        process->children_nr     = 0;
    120121
    121     // reset semaphore list root
     122    // reset semaphore / mutex / barrier / condvar list roots
    122123    xlist_root_init( XPTR( local_cxy , &process->sem_root ) );
    123         process->sem_nr          = 0;
     124    xlist_root_init( XPTR( local_cxy , &process->mutex_root ) );
     125    xlist_root_init( XPTR( local_cxy , &process->barrier_root ) );
     126    xlist_root_init( XPTR( local_cxy , &process->condvar_root ) );
     127    remote_spinlock_init( XPTR( local_cxy , &process->sync_lock ) );
    124128
    125129    // register new process in the parent children list
     
    128132    xlist_add_first( root , entry );
    129133   
    130     // reset th_tbl[] array
     134    // reset th_tbl[] array as empty
    131135    uint32_t i;
    132136    for( i = 0 ; i < CONFIG_THREAD_MAX_PER_CLUSTER ; i++ )
     
    137141    spinlock_init( &process->th_lock );
    138142
    139     // reset process VMM
    140         memset( &process->vmm , 0 , sizeof(vmm_t) );
    141 
    142143    // initialize PID and PPID
    143144        process->pid   = pid;
    144145    process->ppid  = ppid;
    145146
    146     // set ref_xp field and is_ref flag
    147     process->is_ref = true;
     147    // set ref_xp field
    148148    process->ref_xp = XPTR( local_cxy , process );
    149149
     
    153153    // register new process descriptor in owner cluster manager copies_list
    154154    cluster_process_copies_link( process );
     155
     156    // initalise signal manager TODO [AG]
    155157
    156158        hal_wbflush();
     
    162164                           xptr_t      reference_process_xp )
    163165{
    164     // replicate the remote process descriptor in new process descriptor
    165     xptr_t local_process_xp = XPTR( local_cxy , local_process );
    166     hal_remote_memcpy( local_process_xp , reference_process_xp , sizeof(process_t) );
    167 
    168     // initalise signal manager TODO [AG]
    169 
    170     // initialise file descriptors array TODO [AG]
    171 
    172     // initialise process files structures TODO [AG]
    173 
    174     // set the ref_xp field and clear the is_ref flag
     166    // get reference process cluster and local pointer
     167    cxy_t       ref_cxy = GET_CXY( reference_process_xp );
     168    process_t * ref_ptr = (process_t *)GET_PTR( reference_process_xp );
     169
     170    // reset local process vmm
     171    vmm_init( local_process );
     172
     173    // reset process file descriptors array
     174        process_fd_init( local_process );
     175
     176    // reset vfs_root_xp / vfs_bin_xp / vfs_cwd_xp fields
     177    local_process->vfs_root_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->vfs_root_xp ) );
     178    local_process->vfs_bin_xp  = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->vfs_bin_xp ) );
     179    local_process->vfs_cwd_xp  = XPTR_NULL;
     180
     181    // set the pid, ppid, ref_xp fields
     182    local_process->pid    = hal_remote_lw( XPTR( ref_cxy , &ref_ptr->pid ) );
     183    local_process->ppid   = hal_remote_lw( XPTR( ref_cxy , &ref_ptr->ppid ) );
    175184    local_process->ref_xp = reference_process_xp;
    176     local_process->is_ref = false;
    177185
    178186    // reset children list root (not used in a process descriptor copy)
     
    185193    // reset semaphores list root (not used in a process descriptor copy)
    186194    xlist_root_init( XPTR( local_cxy , &local_process->sem_root ) );
    187     local_process->sem_nr        = 0;           
    188 
    189     // initialize th_tbl[] array as empty
     195    xlist_root_init( XPTR( local_cxy , &local_process->mutex_root ) );
     196    xlist_root_init( XPTR( local_cxy , &local_process->barrier_root ) );
     197    xlist_root_init( XPTR( local_cxy , &local_process->condvar_root ) );
     198
     199    // reset th_tbl[] array as empty
    190200    uint32_t i;
    191201    for( i = 0 ; i < CONFIG_THREAD_MAX_PER_CLUSTER ; i++ )
     
    196206    spinlock_init( &local_process->th_lock );
    197207
    198     // initialise  process VMM TODO [AG]
    199 
    200208    // register new process descriptor in local cluster manager local_list
    201209    cluster_process_local_link( local_process );
     
    203211    // register new process descriptor in owner cluster manager copies_list
    204212    cluster_process_copies_link( local_process );
     213
     214    // initalise signal manager TODO [AG]
    205215
    206216        hal_wbflush();
     
    223233    pmgr_t * pmgr = &LOCAL_CLUSTER->pmgr;
    224234
     235    // get the lock protecting the list of local process descriptors
     236    remote_spinlock_lock( XPTR( local_cxy , &pmgr->local_lock ) );
     237
    225238    // remove the process descriptor from local_list in local cluster manager
    226     spinlock_lock( &pmgr->local_lock );
    227239    xlist_unlink( XPTR( local_cxy , &process->local_list ) );
    228     spinlock_unlock( &pmgr->local_lock );
     240
     241    // release the lock protecting the list of local process descriptors
     242    remote_spinlock_unlock( XPTR( local_cxy , &pmgr->local_lock ) );
    229243
    230244    // get extended pointer on copies_lock in owner cluster manager
     
    243257    // From this point, the process descriptor is unreachable
    244258
     259    // close all open files and update dirty TODO [AG]
     260
    245261    // release signal manager TODO [AG]
    246262
    247     // delete all open file descriptors
    248     process_fd_destroy( process );
    249 
    250     // Close bin file and decrease refcount for root and cwd
    251         if( process->vfs_bin_xp != XPTR_NULL ) vfs_close( process->vfs_bin_xp , NULL );
     263    // Decrease refcount for bin file, root file and cwd file
     264        vfs_file_count_down( process->vfs_bin_xp );
    252265    vfs_file_count_down( process->vfs_root_xp );
    253266    vfs_file_count_down( process->vfs_cwd_xp );
     
    325338
    326339
    327 
    328 
    329 
    330340///////////////////////////////////////////////
    331341process_t * process_get_local_copy( pid_t pid )
    332342{
    333343    error_t        error;
    334     bool_t         found;
    335     list_entry_t * iter;
    336     process_t    * process;     // pointer on local copy
     344    process_t    * process_ptr;   // local pointer on process
     345    xptr_t         process_xp;    // extended pointer on process
     346    pid_t          process_pid;   // process identifier
    337347
    338348    cluster_t * cluster = LOCAL_CLUSTER;
    339349
    340350    // get lock protecting local list of processes
    341     spinlock_lock( &cluster->pmgr.local_lock );
     351    remote_spinlock_lock( XPTR( local_cxy , &cluster->pmgr.local_lock ) );
    342352
    343353    // scan the local list of process descriptors to find the process
    344     found = false;
    345     LIST_FOREACH( &cluster->pmgr.local_root , iter )
    346     {
    347         process = LIST_ELEMENT( iter , process_t , local_list );
    348         if( process->pid == pid )
     354    xptr_t  iter;
     355    bool_t  found = false;
     356    XLIST_FOREACH( XPTR( local_cxy , &cluster->pmgr.local_root ) , iter )
     357    {
     358        process_xp  = XLIST_ELEMENT( iter , process_t , local_list );
     359        process_ptr = (process_t *)GET_PTR( process_xp );
     360        process_pid = hal_remote_lw( XPTR( local_cxy , &process_ptr->pid ) );
     361        if( process_ptr->pid == pid )
    349362        {
    350363            found = true;
     
    354367
    355368    // release lock protecting local list of processes
    356     spinlock_unlock( &cluster->pmgr.local_lock );
    357 
    358     // allocate memory for a local process descriptor
    359     // and initialise it from reference if required
     369    remote_spinlock_unlock( XPTR( local_cxy , &cluster->pmgr.local_lock ) );
     370
     371    // allocate memory for a new local process descriptor
     372    // and initialise it from reference cluster if required
    360373    if( !found )
    361374    {
    362375        // get extended pointer on reference process descriptor
    363         xptr_t reference = cluster_get_reference_process_from_pid( pid );
     376        xptr_t ref_xp = cluster_get_reference_process_from_pid( pid );
     377
     378        assert( (ref_xp != XPTR_NULL) , __FUNCTION__ , "illegal pid\n" );
    364379
    365380        // allocate memory for local process descriptor
    366         process = process_alloc();
    367         if( process == NULL )  return NULL;
     381        process_ptr = process_alloc();
     382        if( process_ptr == NULL )  return NULL;
    368383
    369384        // initialize local process descriptor copy
    370         error = process_copy_init( process, reference );
     385        error = process_copy_init( process_ptr , ref_xp );
    371386        if( error ) return NULL;
    372 
    373        
    374         // register process in global copies_list
    375     }
    376 
    377     return process;
     387    }
     388
     389    return process_ptr;
    378390} // end process_get_local_copy()
    379391
     
    389401
    390402    remote_spinlock_init( XPTR( local_cxy , &process->fd_array.lock ) );
    391     process->fd_array.max       = CONFIG_PROCESS_FILE_MAX_NR;
    392     process->fd_array.current   = 0;
     403
     404    process->fd_array.current = 0;
    393405
    394406    // initialize array
    395     for ( fd = 0 ; fd < process->fd_array.max ; fd++ )
     407    for ( fd = 0 ; fd < CONFIG_PROCESS_FILE_MAX_NR ; fd++ )
    396408    {
    397409        process->fd_array.array[fd] = XPTR_NULL;
     
    399411}
    400412
    401 //////////////////////////////////////////////
    402 void process_fd_destroy( process_t * process )
    403 {
    404     uint32_t fd;
    405 
    406     // loop on all open file descriptors to close all open files
    407     for( fd = 0 ; fd < process->fd_array.max ; fd++ )
    408     {
    409         xptr_t file_xp = process->fd_array.array[fd];
    410         if ( file_xp != XPTR_NULL ) vfs_close( file_xp , NULL );
    411     }
     413
     414//////////////////////////////
     415bool_t process_fd_array_full()
     416{
     417    // get extended pointer on reference process
     418    xptr_t ref_xp = CURRENT_THREAD->process->ref_xp;
     419
     420    // get reference process cluster and local pointer
     421    process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
     422    cxy_t       ref_cxy = GET_CXY( ref_xp );
     423
     424    // get number of open file descriptors from reference fd_array
     425    uint32_t current = hal_remote_lw( XPTR( ref_cxy , &ref_ptr->fd_array.current ) );
     426
     427        return ( current >= CONFIG_PROCESS_FILE_MAX_NR ); 
    412428}
    413429
    414 ///////////////////////////////////////////////////
    415 bool_t process_fd_array_full( process_t * process )
    416 {
    417         return ( process->fd_array.current >= process->fd_array.max); 
    418 }
    419 
    420430/////////////////////////////////////////////////
    421 error_t process_fd_allocate( process_t * process,
    422                              xptr_t      file_xp,
    423                              uint32_t   * ret_fd )
     431error_t process_fd_register(  xptr_t     file_xp,
     432                              uint32_t * file_id )
    424433{
    425434    bool_t    found;
    426     uint32_t  fd;
    427 
    428         remote_spinlock_lock( XPTR( local_cxy , &process->fd_array.lock ) );
     435    uint32_t  id;
     436    xptr_t    xp;
     437
     438    // get extended pointer on reference process
     439    xptr_t ref_xp = CURRENT_THREAD->process->ref_xp;
     440
     441    // get reference process cluster and local pointer
     442    process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
     443    cxy_t       ref_cxy = GET_CXY( ref_xp );
     444
     445    // take lock protecting reference fd_array
     446        remote_spinlock_lock( XPTR( ref_cxy , &ref_ptr->fd_array.lock ) );
    429447
    430448    found   = false;
    431449
    432     for ( fd = 0; fd < process->fd_array.max; fd++ )
    433     {
    434         if ( process->fd_array.array[fd] == XPTR_NULL )
     450    for ( id = 0; id < CONFIG_PROCESS_FILE_MAX_NR ; id++ )
     451    {
     452        xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->fd_array.array[id] ) );
     453        if ( xp == XPTR_NULL )
    435454        {
    436455            found = true;
    437             process->fd_array.array[fd] = file_xp;
    438                 process->fd_array.current++;
    439                         *ret_fd = fd;
     456            hal_remote_swd( XPTR( ref_cxy , &ref_ptr->fd_array.array[id] ) , file_xp );
     457                hal_remote_atomic_add( XPTR( ref_cxy , &ref_ptr->fd_array.current ) , 1 );
     458                        *file_id = id;
    440459            break;
    441460        }
    442461    }
    443462
    444         remote_spinlock_unlock( XPTR( local_cxy , &process->fd_array.lock ) );
     463    // release lock protecting reference fd_array
     464        remote_spinlock_unlock( XPTR( ref_cxy , &ref_ptr->fd_array.lock ) );
    445465
    446466    if ( !found ) return EMFILE;
    447467    else          return 0;
    448 }
    449 
    450 ////////////////////////////////////////////////
    451 error_t process_fd_release( process_t * process,
    452                             uint32_t    fd )
    453 {
    454     if ( (fd < 0) || (fd > process->fd_array.max) ) return EBADF;
    455 
    456     remote_spinlock_lock( XPTR( local_cxy , &process->fd_array.lock ) );
    457 
    458     process->fd_array.array[fd] = XPTR_NULL;
    459         process->fd_array.current--;
    460 
    461         remote_spinlock_unlock( XPTR( local_cxy , &process->fd_array.lock ) );
    462 
    463     return 0;
    464 }
    465 
    466 ///////////////////////////////////////
    467 void process_fd_copy( fd_array_t * dst,
    468                       fd_array_t * src )
    469 {
    470     uint32_t fd;
    471     xptr_t   entry;
    472 
    473     remote_spinlock_lock( XPTR( local_cxy , &src->lock ) );
    474 
    475     // loop on all entries in source process fd_array       
    476     for( fd = 0 ; fd < src->max ; fd++ )
    477         {
    478                 entry = src->array[fd];
    479 
    480                 if( entry != XPTR_NULL )
    481                 {
    482             // increment file descriptor ref count
    483             vfs_file_count_up( entry );
    484 
    485                         // copy entry in destination process fd_array
    486                         dst->array[fd] = entry;
    487                 }
    488         }
    489 
    490     // release lock on source process fd_array
    491         remote_spinlock_unlock( XPTR( local_cxy , &src->lock ) );
    492 }
     468
     469}  // end process_fd_register()
     470
     471////////////////////////////////////////////////
     472xptr_t process_fd_get_xptr( process_t * process,
     473                            uint32_t    file_id )
     474{
     475    xptr_t  file_xp;
     476
     477    // access local copy of process descriptor
     478    file_xp = process->fd_array.array[file_id];
     479
     480    if( file_xp == XPTR_NULL )
     481    {
     482        // get reference process cluster and local pointer
     483        xptr_t      ref_xp  = process->ref_xp;
     484        cxy_t       ref_cxy = GET_CXY( ref_xp );
     485        process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
     486
     487        // access reference process descriptor
     488        file_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->fd_array.array[file_id] ) );
     489
     490        // update local fd_array if found
     491        if( file_xp != XPTR_NULL )
     492        {
     493            process->fd_array.array[file_id] = file_xp;
     494        }
     495    }
     496
     497    return file_xp;
     498
     499}  // end process_fd_get_xptr()
    493500
    494501///////////////////////////////////////////
     
    510517        remote_spinlock_lock( XPTR( src_cxy , &src_ptr->lock ) );
    511518
    512     // get number of entries in fd_array
    513     uint32_t max = hal_remote_lw( XPTR( src_cxy , &src_ptr->max ) );
    514 
    515519    // loop on all entries in source process fd_array       
    516     for( fd = 0 ; fd < max ; fd++ )
     520    for( fd = 0 ; fd < CONFIG_PROCESS_FILE_MAX_NR ; fd++ )
    517521        {
    518522                entry = (xptr_t)hal_remote_lwd( XPTR( src_cxy , &src_ptr->array[fd] ) );
     
    609613    pid   = exec_info->pid;
    610614   
    611     if( CXY_FROM_PID( pid ) != local_cxy )
    612     {
    613         printk("\n[PANIC] in %s : illegal process PID %x in cluster %x\n",
    614                __FUNCTION__ , pid , local_cxy );
    615         hal_core_sleep();
    616     }
     615    assert( (CXY_FROM_PID( pid ) == local_cxy) , __FUNCTION__ , "illegal PID\n" );
    617616
    618617    exec_dmsg("\n[INFO] %s enters in cluster %x for process %x / path = %s\n",
     
    677676        }
    678677
    679     // create "stack" vseg descriptor for associated main thread
    680     vseg_t * stack_vseg = vmm_create_vseg( process,
    681                                            0,             // base defined by VMM
    682                                            0,             // size defined by VMM
    683                                            VSEG_TYPE_STACK );
    684     if( stack_vseg == NULL )
    685         {
    686                 printk("\n[ERROR] in %s : cannot create stack vseg for process %x / path = %s\n",
    687                        __FUNCTION__, pid , path );
    688         process_destroy( process );
    689         return error;
    690         }
    691 
    692678    // select a core in cluster
    693679    lid  = cluster_select_local_core();
     
    695681
    696682    // initialize pthread attributes for main thread
    697     attr.pid          = pid;
    698     attr.entry_func   = (void*)process->vmm.entry_point;
    699     attr.entry_args   = exec_info->args_pointers;
    700     attr.flags        = PT_FLAG_DETACH;             // main thread always detached
    701     attr.cxy          = local_cxy;
    702     attr.lid          = lid;
    703 
    704     // create and initialise thread descriptor, link thread & process
    705         error = thread_user_create( &thread,
     683    attr.attributes = PT_ATTR_DETACH | PT_ATTR_CLUSTER_DEFINED | PT_ATTR_CORE_DEFINED;
     684    attr.cxy        = local_cxy;
     685    attr.lid        = lid;
     686
     687    // create and initialise thread descriptor
     688        error = thread_user_create( pid,
     689                                (void *)process->vmm.entry_point,
     690                                exec_info->args_pointers,
    706691                                &attr,
    707                                 stack_vseg->min,
    708                                 stack_vseg->max - stack_vseg->min );
     692                                &thread );
    709693        if( error )
    710694        {
     
    732716{
    733717        process_t   * process_init;  // process_init descriptor
    734         thread_t    * thread_init;   // process_init main thread descriptor
    735718    pid_t         init_pid;      // process_init pid
    736719    exec_info_t   exec_info;     // structure to be passed to process_make_exec()
     
    779762        process_zero.children_nr = 1;
    780763
    781     // TODO open stdin / stdout / stderr pseudo-files
    782     xptr_t  stdin_xp;
    783     xptr_t  stdout_xp;
    784     xptr_t  stderr_xp;
    785 
    786         // error1 = vfs_open( process_init->vfs_cwd_xp, NULL, VFS_O_RDONLY, &stdin_xp );
    787         // error2 = vfs_open( process_init->vfs_cwd_xp, NULL, VFS_O_WRONLY, &stdout_xp );
    788         // error3 = vfs_open( process_init->vfs_cwd_xp, NULL, VFS_O_WRONLY, &stderr_xp );
     764    // TODO create inodes for stdin / stdout / stderr pseudo-files
     765    // these inodes should be created in the cluster containing the relevant TXT chdev
     766
     767    // open stdin / stdout / stderr pseudo-files
     768    xptr_t    stdin_xp;
     769    xptr_t    stdout_xp;
     770    xptr_t    stderr_xp;
     771    uint32_t  stdin_id;
     772    uint32_t  stdout_id;
     773    uint32_t  stderr_id;
     774
     775        error1 = vfs_open( XPTR_NULL, CONFIG_DEV_STDIN , O_RDONLY, 0, &stdin_xp , &stdin_id  );
     776        error2 = vfs_open( XPTR_NULL, CONFIG_DEV_STDOUT, O_WRONLY, 0, &stdout_xp, &stdout_id );
     777        error3 = vfs_open( XPTR_NULL, CONFIG_DEV_STDERR, O_WRONLY, 0, &stderr_xp, &stderr_id );
    789778
    790779        if( error1 || error2 || error3 )
    791780        {
    792                 if( !error1 ) vfs_close( stdin_xp  , NULL );
    793                 if( !error2 ) vfs_close( stdout_xp , NULL );
    794                 if( !error3 ) vfs_close( stderr_xp , NULL );
     781                if( !error1 ) vfs_close( stdin_xp  , stdin_id );
     782                if( !error2 ) vfs_close( stdout_xp , stdout_id );
     783                if( !error3 ) vfs_close( stderr_xp , stderr_id );
    795784   
    796785                printk("\n[PANIC] in %s : cannot open stdin/stdout/stderr in cluster %x\n",
     
    799788        }
    800789
    801     // register stdin / stdout / stderr in the fd_array 3 first slots
    802         process_init->fd_array.array[0] = stdin_xp;
    803         process_init->fd_array.array[1] = stdout_xp;
    804         process_init->fd_array.array[2] = stderr_xp;
    805     process_init->fd_array.current  = 3;
     790    // check stdin / stdout / stderr indexes
     791    if( (stdin_id != 0) || (stdout_id != 1) || (stderr_id != 2) )
     792    {
     793                printk("\n[PANIC] in %s : bad indexes for stdin/stdout/stderr in cluster %x\n",
     794            __FUNCTION__ , local_cxy );
     795        hal_core_sleep();
     796    }
    806797
    807798    // initialize the exec_info structure
  • trunk/kernel/kern/process.h

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

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

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

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

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

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

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

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