Changeset 440 for trunk/kernel/syscalls


Ignore:
Timestamp:
May 3, 2018, 5:51:22 PM (7 years ago)
Author:
alain
Message:

1/ Fix a bug in the Multithreaded "sort" applicationr:
The pthread_create() arguments must be declared as global variables.
2/ The exit syscall can be called by any thread of a process..

Location:
trunk/kernel/syscalls
Files:
22 edited

Legend:

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

    r23 r440  
    22 * sys_barrier.c - Access a POSIX barrier.
    33 *
    4  * authors       Alain Greiner (2016,2017)
     4 * authors       Alain Greiner (2016,2017,2018)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    3737{
    3838        error_t      error;
    39     paddr_t      paddr;
     39    vseg_t     * vseg;
    4040 
    41     thread_t   * this = CURRENT_THREAD;
     41    thread_t   * this    = CURRENT_THREAD;
     42    process_t  * process = this->process;
    4243
    4344    // check vaddr in user vspace
    44         error = vmm_v2p_translate( false , vaddr , &paddr );
     45        error = vmm_get_vseg( process , (intptr_t)vaddr , &vseg );
     46
    4547        if( error )
    4648    {
    47         printk("\n[ERROR] in %s : illegal barrier virtual address = %x\n",
    48                __FUNCTION__ , (intptr_t)vaddr );
     49
     50#if DEBUG_SYSCALLS_ERROR
     51printk("\n[ERROR] in %s : unmapped barrier %x / thread %x / process %x\n",
     52__FUNCTION__ , (intptr_t)vaddr , this->trdid , process->pid );
     53vmm_display( process , false );
     54#endif
    4955        this->errno = error;
    5056        return -1;
     
    6167                    if( error )
    6268            {
    63                 printk("\n[ERROR] in %s : cannot create barrier = %x\n",
    64                        __FUNCTION__ , (intptr_t)vaddr );
     69
     70#if DEBUG_SYSCALLS_ERROR
     71printk("\n[ERROR] in %s : cannot create barrier %x / thread %x / process %x\n",
     72__FUNCTION__ , (intptr_t)vaddr , this->trdid , process->pid );
     73#endif
    6574                this->errno = error;
    6675                return -1;
     
    7584            if( barrier_xp == XPTR_NULL )     // user error
    7685            {
    77                 printk("\n[ERROR] in %s : barrier %x not registered\n",
    78                        __FUNCTION__ , (intptr_t)vaddr );
     86
     87#if DEBUG_SYSCALLS_ERROR
     88printk("\n[ERROR] in %s : barrier %x not registered / thread %x / process %x\n",
     89__FUNCTION__ , (intptr_t)vaddr , this->trdid , process->pid );
     90#endif
    7991                this->errno = EINVAL;
    8092                return -1;
     
    93105            if( barrier_xp == XPTR_NULL )     // user error
    94106            {
    95                 printk("\n[ERROR] in %s : barrier %x not registered\n",
    96                        __FUNCTION__ , (intptr_t)vaddr );
     107
     108#if DEBUG_SYSCALLS_ERROR
     109printk("\n[ERROR] in %s : barrier %x not registered / thread %x / process %x\n",
     110__FUNCTION__ , (intptr_t)vaddr , this->trdid , process->pid );
     111#endif
    97112                this->errno = EINVAL;
    98113                return -1;
  • trunk/kernel/syscalls/sys_condvar.c

    r23 r440  
    22 * sys_condvar.c - Access a POSIX condvar.
    33 *
    4  * Author    Alain Greiner  (2016,2017)
     4 * Author    Alain Greiner  (2016,2017,2018)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    3030#include <syscalls.h>
    3131#include <remote_condvar.h>
     32#include <remote_mutex.h>
    3233
    3334////////////////////////////////////////
     
    3637                 void         * mutex )
    3738{
    38         error_t    error;
    39     paddr_t    paddr;
     39        error_t     error;
     40    vseg_t    * vseg;
    4041 
    41     thread_t * this = CURRENT_THREAD;
     42    thread_t  * this    = CURRENT_THREAD;
     43    process_t * process = this->process;
    4244
    4345    // check condvar in user vspace
    44         error = vmm_v2p_translate( false , condvar , &paddr );
     46        error = vmm_get_vseg( process , (intptr_t)condvar , &vseg );
     47
    4548        if( error )
    4649    {
    47         printk("\n[ERROR] in %s : illegal condvar virtual address = %x\n",
    48                __FUNCTION__ , (intptr_t)condvar );
     50
     51#if DEBUG_SYSCALLS_ERROR
     52printk("\n[ERROR] in %s : unmapped condvar %x / thread %x / process %x\n",
     53__FUNCTION__ , (intptr_t)condvar , this->trdid , process->pid );
     54vmm_display( process , false );
     55#endif
    4956        this->errno = error;
    5057        return -1;
     
    6168                    if( error )
    6269            {
    63                 printk("\n[ERROR] in %s : cannot create condvar = %x\n",
    64                        __FUNCTION__ , (intptr_t)condvar );
     70
     71#if DEBUG_SYSCALLS_ERROR
     72printk("\n[ERROR] in %s : cannot create condvar %x / thread %x / process %x\n",
     73__FUNCTION__ , (intptr_t)condvar , this->trdid , process->pid );
     74#endif
    6575                this->errno = error;
    6676                return -1;
     
    7282        {
    7383            // check mutex in user vspace
    74                 error = vmm_v2p_translate( false , mutex , &paddr );
     84                error = vmm_get_vseg( process , (intptr_t)mutex , &vseg );
    7585
    7686                if( error )
    7787            {
    78                 printk("\n[ERROR] in %s : illegal condvar virtual address = %x\n",
    79                        __FUNCTION__ , (intptr_t)condvar );
     88
     89#if DEBUG_SYSCALLS_ERROR
     90printk("\n[ERROR] in %s : unmapped mutex %x / thread %x / process %x\n",
     91__FUNCTION__ , (intptr_t)mutex , this->trdid , process->pid );
     92#endif
    8093                this->errno = error;
    8194                return -1;
     
    8699            if( condvar_xp == XPTR_NULL )     // user error
    87100            {
    88                 printk("\n[ERROR] in %s : condvar %x not registered\n",
    89                        __FUNCTION__ , (intptr_t)condvar );
     101
     102#if DEBUG_SYSCALLS_ERROR
     103printk("\n[ERROR] in %s : condvar %x not registered / thread %x / process %x\n",
     104__FUNCTION__ , (intptr_t)condvar , this->trdid , process->pid );
     105#endif
    90106                this->errno = EINVAL;
    91107                return -1;
    92108            }
    93109   
    94             xptr_t mutex_xp = remote_condvar_from_ident( (intptr_t)condvar );
     110            xptr_t mutex_xp = remote_mutex_from_ident( (intptr_t)mutex );
     111
    95112            if( mutex_xp == XPTR_NULL )     // user error
    96113            {
    97                 printk("\n[ERROR] in %s : mutex %x not registered\n",
    98                        __FUNCTION__ , (intptr_t)condvar );
     114
     115#if DEBUG_SYSCALLS_ERROR
     116printk("\n[ERROR] in %s : mutex %x not registered / thread %x / process %x\n",
     117__FUNCTION__ , (intptr_t)mutex , this->trdid , process->pid );
     118#endif
    99119                this->errno = EINVAL;
    100120                return -1;
     
    112132            if( condvar_xp == XPTR_NULL )     // user error
    113133            {
    114                 printk("\n[ERROR] in %s : condvar %x not registered\n",
    115                        __FUNCTION__ , (intptr_t)condvar );
     134
     135#if DEBUG_SYSCALLS_ERROR
     136printk("\n[ERROR] in %s : condvar %x not registered / thread %x / process %x\n",
     137__FUNCTION__ , (intptr_t)condvar , this->trdid , process->pid );
     138#endif
    116139                this->errno = EINVAL;
    117140                return -1;
     
    129152            if( condvar_xp == XPTR_NULL )     // user error
    130153            {
    131                 printk("\n[ERROR] in %s : condvar %x not registered\n",
    132                        __FUNCTION__ , (intptr_t)condvar );
     154
     155#if DEBUG_SYSCALLS_ERROR
     156printk("\n[ERROR] in %s : condvar %x not registered / thread %x / process %x\n",
     157__FUNCTION__ , (intptr_t)condvar , this->trdid , process->pid );
     158#endif
    133159                this->errno = EINVAL;
    134160                return -1;
     
    146172            if( condvar_xp == XPTR_NULL )     // user error
    147173            {
    148                 printk("\n[ERROR] in %s : condvar %x not registered\n",
    149                        __FUNCTION__ , (intptr_t)condvar );
     174
     175#if DEBUG_SYSCALLS_ERROR
     176printk("\n[ERROR] in %s : condvar %x not registered / thread %x / process %x\n",
     177__FUNCTION__ , (intptr_t)condvar , this->trdid , process->pid );
     178#endif
    150179                this->errno = EINVAL;
    151180                return -1;
  • trunk/kernel/syscalls/sys_display.c

    r438 r440  
    22 * sys_display.c - display the current state of a kernel structure on TXT0
    33 *
    4  * Author    Alain Greiner (2016,2017)
     4 * Author    Alain Greiner (2016,2017,2018)
    55 * 
    66 * Copyright (c) UPMC Sorbonne Universites
     
    3838{
    3939
     40    error_t     error;
     41    vseg_t    * vseg;
     42
     43    thread_t  * this    = CURRENT_THREAD;
     44    process_t * process = this->process;
     45
    4046#if DEBUG_SYS_DISPLAY
    4147uint64_t    tm_start;
    4248uint64_t    tm_end;
    43 thread_t  * this;
    44 this     = CURRENT_THREAD;
    4549tm_start = hal_get_cycles();
    4650if( DEBUG_SYS_DISPLAY < tm_start )
     
    4953#endif
    5054
     55    ////////////////////////////
    5156    if( type == DISPLAY_STRING )
    5257    {
    53         paddr_t   paddr;
    5458        char      kbuf[256];
    5559        uint32_t  length;
    5660
    5761        char    * string = (char *)arg0;
    58  
     62
    5963        // check string in user space
    60         if( vmm_v2p_translate( false , string , &paddr ) )
    61         {
    62             printk("\n[ERROR] in %s : string buffer %x unmapped\n",
    63             __FUNCTION__ , string );
     64        error = vmm_get_vseg( process , (intptr_t)arg0 , &vseg );
     65
     66        if( error )
     67        {
     68
     69#if DEBUG_SYSCALLS_ERROR
     70printk("\n[ERROR] in %s : string buffer %x unmapped / thread %x / process %x\n",
     71__FUNCTION__ , (intptr_t)arg0 , this->trdid , process->pid );
     72#endif
     73            this->errno = EINVAL;
    6474            return -1;
    6575        }
     
    6777        // ckeck string length
    6878        length = hal_strlen_from_uspace( string );
     79
    6980        if( length >= 256 )
    7081        {
    71             printk("\n[ERROR] in %s : string length %d too large\n",
    72             __FUNCTION__ , length );
    73             return -1;
    74         }
    75 
    76         // copy string in kernel space
     82
     83#if DEBUG_SYSCALLS_ERROR
     84printk("\n[ERROR] in %s : string length %d too large / thread %x / process %x\n",
     85__FUNCTION__ , length , this->trdid , process->pid );
     86#endif
     87            this->errno = EINVAL;
     88            return -1;
     89        }
     90
     91        // copy string to kernel space
    7792        hal_strcpy_from_uspace( kbuf , string , 256 );
    7893
    7994        // print message on TXT0 kernel terminal
    80         printk("\n[USER] %s / cycle %d\n", kbuf, (uint32_t)hal_get_cycles() );
    81     }
     95        printk("\n%s / cycle %d\n", kbuf, (uint32_t)hal_get_cycles() );
     96    }
     97    //////////////////////////////
    8298    else if( type == DISPLAY_VMM )
    8399    {
     
    89105            if( process_xp == XPTR_NULL )
    90106        {
    91             printk("\n[ERROR] in %s : undefined PID %x\n",
    92             __FUNCTION__ , pid );
     107
     108#if DEBUG_SYSCALLS_ERROR
     109printk("\n[ERROR] in %s : undefined pid argument %d / thread %x / process %x\n",
     110__FUNCTION__ , pid , this->trdid , process->pid );
     111#endif
     112            this->errno = EINVAL;
    93113            return -1;
    94114        }
     
    108128        }
    109129    }
     130    ////////////////////////////////
    110131    else if( type == DISPLAY_SCHED )
    111132    {
     
    113134        lid_t lid = (lid_t)arg1;
    114135
    115         // check cluster argument
     136        // check cxy argument
    116137            if( cluster_is_undefined( cxy ) )
    117138        {
    118             printk("\n[ERROR] in %s : undefined cluster identifier %x\n",
    119             __FUNCTION__ , cxy );
    120             return -1;
    121         }
    122 
    123         // check core argument
     139
     140#if DEBUG_SYSCALLS_ERROR
     141printk("\n[ERROR] in %s : illegal cxy argument %x / thread %x / process %x\n",
     142__FUNCTION__ , cxy , this->trdid , process->pid );
     143#endif
     144            this->errno = EINVAL;
     145            return -1;
     146        }
     147
     148        // check lid argument
    124149        if( lid >= LOCAL_CLUSTER->cores_nr )
    125150        {
    126             printk("\n[ERROR] in %s : undefined local index %d\n",
    127             __FUNCTION__ , lid );
     151
     152#if DEBUG_SYSCALLS_ERROR
     153printk("\n[ERROR] in %s : illegal lid argument %x / thread %x / process %x\n",
     154__FUNCTION__ , lid , this->trdid , process->pid );
     155#endif
     156            this->errno = EINVAL;
    128157            return -1;
    129158        }
     
    138167        }
    139168    }
     169    ////////////////////////////////////////////
    140170    else if( type == DISPLAY_CLUSTER_PROCESSES )
    141171    {
    142172        cxy_t cxy = (cxy_t)arg0;
    143173
    144         // check cluster argument
     174        // check cxy argument
    145175            if( cluster_is_undefined( cxy ) )
    146176        {
    147             printk("\n[ERROR] in %s : undefined cluster identifier %x\n",
    148             __FUNCTION__ , cxy );
     177
     178#if DEBUG_SYSCALLS_ERROR
     179printk("\n[ERROR] in %s : illegal cxy argument %x / thread %x / process %x\n",
     180__FUNCTION__ , cxy , this->trdid , process->pid );
     181#endif
     182            this->errno = EINVAL;
    149183            return -1;
    150184        }
     
    152186        cluster_processes_display( cxy );
    153187    }
     188    ////////////////////////////////////////
    154189    else if( type == DISPLAY_TXT_PROCESSES )
    155190    {
     
    159194            if( txt_id >= LOCAL_CLUSTER->nb_txt_channels )
    160195        {
    161             printk("\n[ERROR] in %s : undefined TXT channel %x\n",
    162             __FUNCTION__ , txt_id );
     196
     197#if DEBUG_SYSCALLS_ERROR
     198printk("\n[ERROR] in %s : illegal txt_id argument %d / thread %x / process %x\n",
     199__FUNCTION__ , txt_id , this->trdid , process->pid );
     200#endif
     201            this->errno = EINVAL;
    163202            return -1;
    164203        }
     
    166205        process_txt_display( txt_id );
    167206    }
     207    //////////////////////////////
    168208    else if( type == DISPLAY_VFS )
    169209    {
    170         // call kernel function
    171         process_t * process = CURRENT_THREAD->process;
    172210        vfs_display( process->vfs_root_xp );
    173211    }
     212    ////////////////////////////////
    174213    else if( type == DISPLAY_CHDEV )
    175214    {
    176215        chdev_dir_display();
    177216    }
     217    ////
    178218    else
    179219    {
    180         printk("\n[ERROR] in %s : undefined display type %x\n",
    181         __FUNCTION__ , type );
     220
     221#if DEBUG_SYSCALLS_ERROR
     222printk("\n[ERROR] in %s : undefined display type %x / thread %x / process %x\n",
     223        __FUNCTION__ , type , this->trdid , process->pid );
     224#endif
     225        this->errno = EINVAL;
    182226        return -1;
    183227    }
  • trunk/kernel/syscalls/sys_exit.c

    r438 r440  
    22 * sys_exit.c - Kernel function implementing the "exit" system call.
    33 *
    4  * Author    Alain Greiner (2016,2017)
     4 * Author    Alain Greiner (2016,2017,2018)
    55 *
    66 * Copyright (c)  UPMC Sorbonne Universites
     
    4141    process_t * process = this->process;
    4242    pid_t       pid     = process->pid;
    43     trdid_t     trdid   = this->trdid;
    4443
    4544#if DEBUG_SYS_EXIT
     
    5251#endif
    5352
    54     // get owner cluster
    55     cxy_t  owner_cxy = CXY_FROM_PID( pid );
     53    // get owner process descriptor pointers an cluster
     54    xptr_t      owner_xp  = cluster_get_owner_process_from_pid( pid );
     55    cxy_t       owner_cxy = GET_CXY( owner_xp );
     56    process_t * owner_ptr = GET_PTR( owner_xp );
    5657
    57     // exit must be called by the main thread
    58     if( (owner_cxy != local_cxy) || (LTID_FROM_TRDID( trdid ) != 0) )
    59     {
    60 
    61 #if DEBUG_SYSCALLS_ERROR
    62 printk("\n[ERROR] in %s : calling thread %x is not thread 0 in owner cluster %x\n",
    63 __FUNCTION__, trdid, owner_cxy );
    64 #endif
    65          this->errno = EINVAL;
    66          return -1;
    67     }
     58    // get pointers on the process main thread
     59    thread_t * main    = hal_remote_lpt( XPTR( owner_cxy , &owner_ptr->th_tbl[0] ) );
    6860
    6961    // enable IRQs
    7062    hal_enable_irq( &save_sr );
    7163
    72     // register exit_status in owner process descriptor
    73     process->term_state = status;
     64    // mark for delete all process threads in all clusters
     65    // (but the main thread and this calling thread)
     66    process_sigaction( pid , DELETE_ALL_THREADS );
     67
     68    // disable IRQs
     69    hal_restore_irq( save_sr );
    7470
    7571#if( DEBUG_SYS_EXIT & 1)
    76 printk("\n[DBG] %s : set exit status in process term_state\n", __FUNCTION__);
     72if( tm_start > DEBUG_SYS_EXIT )
     73printk("\n[DBG] %s : thread %x deleted threads / process %x\n",
     74__FUNCTION__ , this, pid );
    7775#endif
    7876
    79     // remove process from TXT list
    80     process_txt_detach( XPTR( local_cxy , process ) );
     77    // mark for delete this calling thread when it is not the main
     78    if( (owner_cxy != local_cxy) || (main != this) )
     79    {
    8180
    8281#if( DEBUG_SYS_EXIT & 1)
    83 printk("\n[DBG] %s : removed from TXT list\n", __FUNCTION__);
     82if( tm_start > DEBUG_SYS_EXIT )
     83printk("\n[DBG] %s : calling thread %x deleted itself / process %x\n",
     84__FUNCTION__ , this, pid );
     85#endif
     86        thread_delete( XPTR( local_cxy , this ) , pid , true );
     87    }
     88         
     89    // remove process from TXT list
     90    process_txt_detach( owner_xp );
     91
     92#if( DEBUG_SYS_EXIT & 1)
     93if( tm_start > DEBUG_SYS_EXIT )
     94printk("\n[DBG] %s : thread %x removed process %x from TXT list\n",
     95__FUNCTION__ , this, pid );
    8496#endif
    8597
    86     // mark for delete all process threads in all clusters (but the main)
    87     process_sigaction( pid , DELETE_ALL_THREADS );
     98    // block the main thread
     99    thread_block( XPTR( owner_cxy , main ) , THREAD_BLOCKED_GLOBAL );
    88100
    89101#if( DEBUG_SYS_EXIT & 1)
    90 printk("\n[DBG] %s : deleted all other threads than main\n", __FUNCTION__);
    91 #endif
    92 
    93     // restore IRQs
    94     hal_restore_irq( save_sr );
    95 
    96     // block the main thread itself
    97     thread_block( XPTR( local_cxy , this ) , THREAD_BLOCKED_GLOBAL );
    98 
    99 #if( DEBUG_SYS_EXIT & 1)
    100 printk("\n[DBG] %s : blocked the main thread\n", __FUNCTION__);
     102if( tm_start > DEBUG_SYS_EXIT )
     103printk("\n[DBG] %s : thread %x blocked main thread for process %x\n",
     104__FUNCTION__, this , pid );
    101105#endif
    102106
    103107    // atomically update owner process descriptor term_state to ask
    104     // the parent process sys_wait() function to delete this main thread
    105     hal_remote_atomic_or( XPTR( local_cxy , &process->term_state ) ,
    106                           PROCESS_TERM_EXIT );
     108    // the parent process sys_wait() function to delete the main thread
     109    hal_remote_atomic_or( XPTR( owner_cxy , &process->term_state ) ,
     110                          PROCESS_TERM_EXIT | (status & 0xFF) );
    107111
    108112#if( DEBUG_SYS_EXIT & 1)
    109 printk("\n[DBG] %s : set EXIT flag in process term_state\n", __FUNCTION__);
     113if( tm_start > DEBUG_SYS_EXIT )
     114printk("\n[DBG] %s : thread %x set exit status in process %x term_state\n",
     115__FUNCTION__ , this, pid );
    110116#endif
    111117
     
    119125#endif
    120126
    121     // main thread deschedule
     127    // this thread deschedule
    122128    sched_yield( "process exit" );
    123129
  • trunk/kernel/syscalls/sys_fork.c

    r438 r440  
    7777    ref_process_xp  = parent_process_ptr->ref_xp;
    7878    ref_process_cxy = GET_CXY( ref_process_xp );
    79     ref_process_ptr = (process_t *)GET_PTR( ref_process_xp );
     79    ref_process_ptr = GET_PTR( ref_process_xp );
    8080
    8181    // check parent process children number from reference
     
    104104        }
    105105
    106 #if( DEBUG_SYS_FORK & 1)
    107 
    108 // dqdt_display();
    109 
    110 if( local_cxy == 0 )
    111 {
    112     sched_display( 0 );
    113     rpc_sched_display_client( 1 , 0 );
    114 }
    115 else
    116 {
    117     sched_display( 0 );
    118     rpc_sched_display_client( 0 , 0 );
    119 }
    120 
     106#if (DEBUG_SYS_FORK & 1 )
    121107if( DEBUG_SYS_FORK < tm_start )
    122108printk("\n[DBG] %s : parent_thread %x selected cluster %x\n",
  • trunk/kernel/syscalls/sys_get_config.c

    r438 r440  
    22 * sys_get_config.c - get hardware platform parameters.
    33 *
    4  * Author    Alain Greiner (2016,2017)
     4 * Author    Alain Greiner (2016,2017,2018)
    55 * 
    66 * Copyright (c) UPMC Sorbonne Universites
     
    3737                    uint32_t * ncores )
    3838{
    39     paddr_t   paddr;
    40     uint32_t  k_x_size;
    41     uint32_t  k_y_size;
    42     uint32_t  k_ncores;
    43 
    44         error_t   error = 0;
     39        error_t    error;
     40    vseg_t   * vseg;
     41    uint32_t   k_x_size;
     42    uint32_t   k_y_size;
     43    uint32_t   k_ncores;
    4544
    4645    thread_t  * this    = CURRENT_THREAD;
     
    5655#endif
    5756
    58     // check buffer in user space
    59     error |= vmm_v2p_translate( false , x_size  , &paddr );
    60     error |= vmm_v2p_translate( false , y_size  , &paddr );
    61     error |= vmm_v2p_translate( false , ncores  , &paddr );
     57    // check x_size buffer in user space
     58    error = vmm_get_vseg( process , (intptr_t)x_size  , &vseg );
    6259
    6360        if( error )
     
    6562
    6663#if DEBUG_SYSCALLS_ERROR
    67 printk("\n[ERROR] in %s : user buffer unmapped for thread %x in process %x\n",
    68 __FUNCTION__ , this->trdid , process->pid );
     64printk("\n[ERROR] in %s : x_size buffer unmapped / thread %x / process %x\n",
     65__FUNCTION__ , (intptr_t)x_size , this->trdid , process->pid );
     66vmm_display( process , false );
    6967#endif
    70         this->errno = EFAULT;
     68        this->errno = EINVAL;
     69                return -1;
     70        }
     71
     72    // check y_size buffer in user space
     73    error = vmm_get_vseg( process , (intptr_t)y_size  , &vseg );
     74
     75        if( error )
     76        {
     77
     78#if DEBUG_SYSCALLS_ERROR
     79printk("\n[ERROR] in %s : y_size buffer unmapped / thread %x / process %x\n",
     80__FUNCTION__ , (intptr_t)y_size , this->trdid , process->pid );
     81vmm_display( process , false );
     82#endif
     83        this->errno = EINVAL;
     84                return -1;
     85        }
     86
     87    // check ncores buffer in user space
     88    error = vmm_get_vseg( process , (intptr_t)ncores  , &vseg );
     89
     90        if( error )
     91        {
     92
     93#if DEBUG_SYSCALLS_ERROR
     94printk("\n[ERROR] in %s : ncores buffer unmapped / thread %x / process %x\n",
     95__FUNCTION__ , (intptr_t)ncores , this->trdid , process->pid );
     96vmm_display( process , false );
     97#endif
     98        this->errno = EINVAL;
    7199                return -1;
    72100        }
  • trunk/kernel/syscalls/sys_get_core.c

    r410 r440  
    3737                  uint32_t * lid )
    3838{
    39     paddr_t   paddr;
     39        error_t   error;
     40    vseg_t  * vseg;
    4041    uint32_t  k_cxy;
    4142    uint32_t  k_lid;
    42 
    43         error_t   error = 0;
    4443
    4544    thread_t  * this    = CURRENT_THREAD;
    4645    process_t * process = this->process;
    4746
    48     // check buffers in user space
    49     error |= vmm_v2p_translate( false , cxy , &paddr );
    50     error |= vmm_v2p_translate( false , lid , &paddr );
     47    // check cxy buffer in user space
     48    error = vmm_get_vseg( process , (intptr_t)cxy , &vseg );
    5149
    5250        if( error )
    5351        {
    54         printk("\n[ERROR] in %s : user buffer unmapped for thread %x in process %x\n",
    55         __FUNCTION__ , this->trdid , process->pid );
     52
     53#if DEBUG_SYSCALLS_ERROR
     54printk("\n[ERROR] in %s : cxy buffer unmapped %x / thread %x / process %x\n",
     55__FUNCTION__ , (intptr_t)cxy , this->trdid , process->pid );
     56vmm_display( process , false );
     57#endif
     58        this->errno = EFAULT;
     59                return -1;
     60        }
     61
     62    // check lid buffer in user space
     63    error = vmm_get_vseg( process , (intptr_t)lid , &vseg );
     64
     65        if( error )
     66        {
     67
     68#if DEBUG_SYSCALLS_ERROR
     69printk("\n[ERROR] in %s : lid buffer unmapped %x / thread %x / process %x\n",
     70__FUNCTION__ , (intptr_t)lid , this->trdid , process->pid );
     71vmm_display( process , false );
     72#endif
    5673        this->errno = EFAULT;
    5774                return -1;
  • trunk/kernel/syscalls/sys_get_cycle.c

    r408 r440  
    22 * sys_get_cycle.c - get calling core cycles count.
    33 *
    4  * Author    Alain Greiner (2016,2017)
     4 * Author    Alain Greiner (2016,2017,2018)
    55 * 
    66 * Copyright (c) UPMC Sorbonne Universites
     
    3535int sys_get_cycle ( uint64_t * cycle )
    3636{
    37         error_t   error;
    38     paddr_t   paddr;
    39         uint64_t  k_cycle;
     37        error_t     error;
     38    vseg_t    * vseg;
     39        uint64_t    k_cycle;
    4040
    4141    thread_t  * this    = CURRENT_THREAD;
     
    4343
    4444    // check buffer in user space
    45     error = vmm_v2p_translate( false , cycle , &paddr );
     45    error = vmm_get_vseg( process , (intptr_t)cycle , &vseg );
    4646
    4747        if( error )
    4848        {
    49         printk("\n[ERROR] in %s : user buffer unmapped for thread %x in process %x\n",
    50         __FUNCTION__ , this->trdid , process->pid );
     49
     50#if DEBUG_SYSCALLS_ERROR
     51printk("\n[ERROR] in %s : user buffer unmapped %x / thread %x / process %x\n",
     52__FUNCTION__ , (intptr_t)cycle , this->trdid , process->pid );
     53vmm_display( process , false );
     54#endif
    5155        this->errno = EFAULT;
    5256                return -1;
  • trunk/kernel/syscalls/sys_getcwd.c

    r124 r440  
    22 * sys_getcwd.c - get process current work directory
    33 *
    4  * Author    Alain Greiner (2016,2017)
     4 * Author    Alain Greiner (2016,2017,2018)
    55 *
    66 * Copyright (c)  UPMC Sorbonne Universites
     
    4040{
    4141        error_t    error;
    42     paddr_t    paddr;
     42    vseg_t   * vseg;
    4343    char       kbuf[CONFIG_VFS_MAX_PATH_LENGTH];
    4444 
     
    4949        if( nbytes < CONFIG_VFS_MAX_PATH_LENGTH )
    5050        {
    51         printk("\n[ERROR] in %s : buffer too small\n", __FUNCTION__ );
    52                 this->errno = ERANGE;
     51
     52#if DEBUG_SYSCALLS_ERROR
     53printk("\n[ERROR] in %s : buffer too small / thread %x / process %x\n",
     54__FUNCTION__ , this->trdid , process->pid );
     55#endif
     56                this->errno = EINVAL;
    5357        return -1;
    5458        }
    5559
    5660    // check buffer in user space
    57     error = vmm_v2p_translate( false , buf , &paddr );
     61    error = vmm_get_vseg( process, (intptr_t)buf , &vseg );
    5862
    5963        if( error )
    6064        {
    61         printk("\n[ERROR] in %s : user buffer unmapped\n", __FUNCTION__ );
    62                 this->errno = EFAULT;
     65
     66#if DEBUG_SYSCALLS_ERROR
     67printk("\n[ERROR] in %s : user buffer unmapped %x / thread %x / process %x\n",
     68__FUNCTION__ , (intptr_t)buf , this->trdid , process->pid );
     69#endif
     70                this->errno = EINVAL;
    6371        return -1;
    6472        }
  • trunk/kernel/syscalls/sys_kill.c

    r438 r440  
    22 * sys_kill.c - Kernel function implementing the "kill" system call.
    33 *
    4  * Author    Alain Greiner (2016,2017)
     4 * Author    Alain Greiner (2016,2017,2018)
    55 *
    66 * Copyright (c)  UPMC Sorbonne Universites
     
    3838{
    3939    xptr_t      owner_xp;      // extended pointer on target process in owner cluster
    40     cxy_t       owner_cxy;     // target process owner cluster
     40    cxy_t       owner_cxy;     // target process in owner cluster
    4141    process_t * owner_ptr;     // local pointer on target process in owner cluster
    42     xptr_t      parent_xp;     // extended pointer on parent process
    43     cxy_t       parent_cxy;    // parent process cluster
    44     process_t * parent_ptr;    // local pointer on parent process
    45     pid_t       ppid;          // parent process PID
    4642    uint32_t    retval;        // return value for the switch
    4743
    4844    thread_t  * this    = CURRENT_THREAD;
    4945    process_t * process = this->process;
    50     trdid_t     trdid   = this->trdid;
    5146
    5247#if DEBUG_SYS_KILL
     
    7570    }
    7671
    77     // process can kill itself only when calling thread is the main thread
    78     if( (pid == process->pid) && ((owner_cxy != local_cxy) || (LTID_FROM_TRDID( trdid ))) )
     72    // process cannot kill itself
     73    if( (pid == process->pid) )
    7974    {
    8075
    8176#if DEBUG_SYSCALLS_ERROR
    82 printk("\n[ERROR] in %s : only main thread can kill itself\n", __FUNCTION__ );
     77printk("\n[ERROR] in %s : process %x cannot kill itself\n", __FUNCTION__, pid );
    8378#endif
    8479        this->errno = EINVAL;
     
    8681    }
    8782
    88     // get parent process PID
    89     parent_xp  = hal_remote_lwd( XPTR( owner_cxy , &owner_ptr->parent_xp ) );
    90     parent_cxy = GET_CXY( parent_xp );
    91     parent_ptr = GET_PTR( parent_xp );
    92     ppid       = hal_remote_lw( XPTR( parent_cxy , &parent_ptr->pid ) );
    93 
    94     // check processe INIT
     83    // processe INIT cannot be killed
    9584    if( pid == 1 )
    9685    {
  • trunk/kernel/syscalls/sys_mmap.c

    r438 r440  
    33 *
    44 * Authors       Ghassan Almaless (2008,2009,2010,2011,2012)
    5  *               Alain Greiner (2016,2017)
     5 *               Alain Greiner (2016,2017,2018)
    66 *
    77 * Copyright (c) UPMC Sorbonne Universites
     
    4444    xptr_t        mapper_xp;
    4545    error_t       error;
    46     paddr_t       paddr;        // unused, but required for user space checking
    4746    reg_t         save_sr;      // required to enable IRQs
    4847
     
    6059
    6160    // check arguments in user space
    62     error = vmm_v2p_translate( false , attr , &paddr );
     61    error = vmm_get_vseg( process , (intptr_t)attr , &vseg );
    6362
    6463    if ( error )
     
    6665
    6766#if DEBUG_SYSCALLS_ERROR
    68 printk("\n[ERROR] in %s : arguments not in used space = %x\n", __FUNCTION__ , (intptr_t)attr );
     67printk("\n[ERROR] in %s : user buffer unmapped %x / thread %x / process %x\n",
     68__FUNCTION__ , (intptr_t)attr , this->trdid , process->pid );
     69vmm_display( process , false );
    6970#endif
    7071                this->errno = EINVAL;
     
    9293
    9394#if DEBUG_SYSCALLS_ERROR
    94 printk("\n[ERROR] in %s : MAP_FIXED not supported\n", __FUNCTION__ );
     95printk("\n[ERROR] in %s : MAP_FIXED not supported / thread %x / process %x\n",
     96__FUNCTION__ , this->trdid , process->pid );
    9597#endif
    9698        this->errno = EINVAL;
     
    102104
    103105#if DEBUG_SYSCALLS_ERROR
    104 printk("\n[ERROR] in %s : MAP_SHARED xor MAP_PRIVATE\n", __FUNCTION__ );
     106printk("\n[ERROR] in %s : MAP_SHARED == MAP_PRIVATE / thread %x / process %x\n",
     107__FUNCTION__ , this->trdid , process->pid );
    105108#endif
    106109        this->errno = EINVAL;
     
    124127
    125128#if DEBUG_SYSCALLS_ERROR
    126 printk("\n[ERROR] in %s: bad file descriptor = %d\n", __FUNCTION__ , fdid );
     129printk("\n[ERROR] in %s: bad file descriptor %d / thread %x / process %x\n",
     130__FUNCTION__ , fdid , this->trdid , process->pid );
    127131#endif
    128132            this->errno = EBADFD;
     
    137141
    138142#if DEBUG_SYSCALLS_ERROR
    139 printk("\n[ERROR] in %s: file %d not found\n", __FUNCTION__ , fdid );
     143printk("\n[ERROR] in %s: file %d not found / thread %x / process %x\n",
     144__FUNCTION__ , fdid , this->trdid , process->pid );
    140145#endif
    141146            this->errno = EBADFD;
     
    160165
    161166#if DEBUG_SYSCALLS_ERROR
    162 printk("\n[ERROR] in %s: offset (%d) + len (%d) >= file's size (%d)\n",
    163 __FUNCTION__, k_attr.offset, k_attr.length, size );
     167printk("\n[ERROR] in %s: offset(%d) + len(%d) >= file's size(%d) / thread %x / process %x\n",
     168__FUNCTION__, k_attr.offset, k_attr.length, size, this->trdid, process->pid );
    164169#endif
    165170            this->errno = ERANGE;
     
    173178
    174179#if DEBUG_SYSCALLS_ERROR
    175 printk("\n[ERROR] in %s: prot = %x / file_attr = %x)\n",
    176 __FUNCTION__ , k_attr.prot , file_attr );
     180printk("\n[ERROR] in %s: prot = %x / file_attr = %x / thread %x , process %x\n",
     181__FUNCTION__ , k_attr.prot , file_attr , this->trdid , process->pid );
    177182#endif
    178183                        this->errno = EACCES;
     
    206211
    207212#if DEBUG_SYSCALLS_ERROR
    208 printk("\n[ERROR] in %s : illegal cxy for MAP_REMOTE\n", __FUNCTION__ );
     213printk("\n[ERROR] in %s : illegal cxy for MAP_REMOTE / thread %x / process %x\n",
     214__FUNCTION__, this->trdid , process->pid );
    209215#endif
    210216                this->errno = EINVAL;
     
    255261
    256262#if DEBUG_SYSCALLS_ERROR
    257 printk("\n[ERROR] in %s : cannot create vseg\n", __FUNCTION__ );
     263printk("\n[ERROR] in %s : cannot create vseg / thread %x / process %x\n",
     264__FUNCTION__, this->trdid , process->pid );
    258265#endif
    259266        this->errno = ENOMEM;
  • trunk/kernel/syscalls/sys_mutex.c

    r23 r440  
    22 * sys_mutex.c - Access a POSIX mutex.
    33 *
    4  * Author    Alain Greiner (2016,2017)
     4 * Author    Alain Greiner (2016,2017,2018)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    3737               uint32_t   attr )
    3838{
    39         error_t    error;
    40     paddr_t    paddr;
     39        error_t     error;
     40    vseg_t    * vseg;
    4141
    42     thread_t * this = CURRENT_THREAD;
     42    thread_t  * this    = CURRENT_THREAD;
     43    process_t * process = this->process;
    4344
    4445    // check vaddr in user vspace
    45         error = vmm_v2p_translate( false , vaddr , &paddr );
     46        error = vmm_get_vseg( process , (intptr_t)vaddr , &vseg );
     47
    4648        if( error )
    4749    {
    48         printk("\n[ERROR] in %s : illegal virtual address = %x\n",
    49                __FUNCTION__ , (intptr_t)vaddr );
     50
     51#if DEBUG_SYSCALLS_ERROR
     52printk("\n[ERROR] in %s : mutex unmapped %x / thread %x / process %x\n",
     53__FUNCTION__ , (intptr_t)vaddr , this->trdid , process->pid );
     54vmm_display( process , false );
     55#endif
    5056        this->errno = error;
    5157        return -1;
     
    6066            if( attr != 0 )
    6167            {
    62                 printk("\n[ERROR] in %s : mutex attributes non supported yet\n",
    63                        __FUNCTION__ );
     68
     69#if DEBUG_SYSCALLS_ERROR
     70printk("\n[ERROR] in %s : mutex attribute non supported / thread %x / process %x\n",
     71__FUNCTION__ , this->trdid , process->pid );
     72#endif
    6473                this->errno = error;
    6574                return -1;
     
    7079            if( error )
    7180            {
    72                 printk("\n[ERROR] in %s : cannot create mutex\n",
    73                        __FUNCTION__ );
     81
     82#if DEBUG_SYSCALLS_ERROR
     83printk("\n[ERROR] in %s : cannot create mutex / thread %x / process %x\n",
     84__FUNCTION__ , this->trdid , process->pid );
     85#endif
    7486                this->errno = error;
    7587                return -1;
     
    8496            if( mutex_xp == XPTR_NULL )     // user error
    8597            {
    86                 printk("\n[ERROR] in %s : mutex %x not registered\n",
    87                        __FUNCTION__ , (intptr_t)vaddr );
     98
     99#if DEBUG_SYSCALLS_ERROR
     100printk("\n[ERROR] in %s : mutex %x not registered / thread %x / process %x\n",
     101__FUNCTION__ , (intptr_t)vaddr , this->trdid , process->pid );
     102#endif
    88103                this->errno = EINVAL;
    89104                return -1;
     
    102117            if( mutex_xp == XPTR_NULL )     // user error
    103118            {
    104                 printk("\n[ERROR] in %s : mutex %x not registered\n",
    105                        __FUNCTION__ , (intptr_t)vaddr );
     119
     120#if DEBUG_SYSCALLS_ERROR
     121printk("\n[ERROR] in %s : mutex %x not registered / thread %x / process %x\n",
     122__FUNCTION__ , (intptr_t)vaddr , this->trdid , process->pid );
     123#endif
    106124                this->errno = EINVAL;
    107125                return -1;
     
    120138            if( mutex_xp == XPTR_NULL )     // user error
    121139            {
    122                 printk("\n[ERROR] in %s : mutex %x not registered\n",
    123                        __FUNCTION__ , (intptr_t)vaddr );
     140
     141#if DEBUG_SYSCALLS_ERROR
     142printk("\n[ERROR] in %s : mutex %x not registered / thread %x / process %x\n",
     143__FUNCTION__ , (intptr_t)vaddr , this->trdid , process->pid );
     144#endif
    124145                this->errno = EINVAL;
    125146                return -1;
  • trunk/kernel/syscalls/sys_read.c

    r438 r440  
    22 * sys_read.c - read bytes from a file
    33 *
    4  * Author     Alain Greiner (2016,2017)
     4 * Author     Alain Greiner (2016,2017,2018)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    5858{
    5959    error_t      error;
    60     paddr_t      paddr;       // required for user space checking
     60    vseg_t     * vseg;        // required for user space checking
    6161        xptr_t       file_xp;     // remote file extended pointer
    6262    uint32_t     nbytes;      // number of bytes actually read
     
    9191
    9292    // check user buffer in user space
    93     error = vmm_v2p_translate( false , vaddr , &paddr );
     93    error = vmm_get_vseg( process , (intptr_t)vaddr , &vseg );
    9494
    9595    if ( error )
     
    9797
    9898#if DEBUG_SYSCALLS_ERROR
    99 printk("\n[ERROR] in %s : user buffer unmapped = %x\n",
    100 __FUNCTION__ , (intptr_t)vaddr );
     99printk("\n[ERROR] in %s : user buffer unmapped %x / thread %x / process %x\n",
     100__FUNCTION__ , (intptr_t)vaddr, this->trdid, process->pid );
     101vmm_display( process , false );
    101102#endif
    102103                this->errno = EINVAL;
  • trunk/kernel/syscalls/sys_sem.c

    r23 r440  
    22 * sys_sem.c - Acces a POSIX unamed semaphore.
    33 *
    4  * Authors     Alain Greiner (2016,2017)
     4 * Authors     Alain Greiner (2016,2017,2018)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    3636             uint32_t     * value )       // pointer on in/out argument
    3737{
    38         uint32_t             data;   
    39         paddr_t              paddr;
    40     error_t              error;
     38        uint32_t         data;   
     39        vseg_t         * vseg;
     40    error_t          error;
    4141
    42     thread_t           * this = CURRENT_THREAD;
     42    thread_t       * this    = CURRENT_THREAD;
     43    process_t      * process = this->process;
    4344
    4445    // check vaddr in user vspace
    45         error = vmm_v2p_translate( false , vaddr , &paddr );
     46        error = vmm_get_vseg( process , (intptr_t)vaddr , &vseg );
    4647        if( error )
    4748    {
    48         printk("\n[ERROR] in %s : illegal semaphore virtual address = %x\n",
    49                __FUNCTION__ , (intptr_t)vaddr );
    50         this->errno = error;
     49
     50#if DEBUG_SYSCALLS_ERROR
     51printk("\n[ERROR] in %s : unmapped semaphore %x / thread %x / process %x\n",
     52__FUNCTION__ , (intptr_t)vaddr, this->trdid, process->pid );
     53vmm_display( process , false );
     54#endif
     55        this->errno = EINVAL;
    5156        return -1;
    5257    }
    5358
    5459    // check value in user vspace
    55         error = vmm_v2p_translate( false , value , &paddr );
     60        error = vmm_get_vseg( process , (intptr_t)value , &vseg );
    5661        if( error )
    5762    {
    58         printk("\n[ERROR] in %s : illegal argument virtual address = %x\n",
    59                __FUNCTION__ , (intptr_t)value );
    60         this->errno = error;
    61         return -1;   
     63
     64#if DEBUG_SYSCALLS_ERROR
     65printk("\n[ERROR] in %s : unmapped value %x / thread %x / process %x\n",
     66__FUNCTION__ , (intptr_t)vaddr, this->trdid, process->pid );
     67vmm_display( process , false );
     68#endif
     69        this->errno = EINVAL;
     70        return -1;
    6271    }
    63    
     72
    6473    // execute requested operation
    6574        switch( operation )
     
    91100            if( sem_xp == XPTR_NULL )     // user error
    92101            {
    93                 printk("\n[ERROR] in %s : semaphore %x not registered\n",
    94                        __FUNCTION__ , (intptr_t)value );
     102
     103#if DEBUG_SYSCALLS_ERROR
     104printk("\n[ERROR] in %s : semaphore %x not registered / thread %x / process %x\n",
     105__FUNCTION__ , (intptr_t)value, this->trdid, process->pid );
     106#endif
    95107                this->errno = EINVAL;
    96108                return -1;
     
    114126            if( sem_xp == XPTR_NULL )     // user error
    115127            {
    116                 printk("\n[ERROR] in %s : semaphore %x not registered\n",
    117                        __FUNCTION__ , (intptr_t)value );
     128
     129#if DEBUG_SYSCALLS_ERROR
     130printk("\n[ERROR] in %s : semaphore %x not registered / thread %x / process %x\n",
     131__FUNCTION__ , (intptr_t)value, this->trdid, process->pid );
     132#endif
    118133                this->errno = EINVAL;
    119134                return -1;
     
    134149            if( sem_xp == XPTR_NULL )     // user error
    135150            {
    136                 printk("\n[ERROR] in %s : semaphore %x not registered\n",
    137                        __FUNCTION__ , (intptr_t)value );
     151
     152#if DEBUG_SYSCALLS_ERROR
     153printk("\n[ERROR] in %s : semaphore %x not registered / thread %x / process %x\n",
     154__FUNCTION__ , (intptr_t)value, this->trdid, process->pid );
     155#endif
    138156                this->errno = EINVAL;
    139157                return -1;
     
    154172            if( sem_xp == XPTR_NULL )     // user error
    155173            {
    156                 printk("\n[ERROR] in %s : semaphore %x not registered\n",
    157                        __FUNCTION__ , (intptr_t)value );
     174
     175#if DEBUG_SYSCALLS_ERROR
     176printk("\n[ERROR] in %s : semaphore %x not registered / thread %x / process %x\n",
     177__FUNCTION__ , (intptr_t)value, this->trdid, process->pid );
     178#endif
    158179                this->errno = EINVAL;
    159180                return -1;
  • trunk/kernel/syscalls/sys_stat.c

    r407 r440  
    22 * sys_stat.c - Return statistics on a file or directory.
    33 *
    4  * Author    Alain Greiner  (2016,2017)
     4 * Author    Alain Greiner  (2016,2017,2018)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    3737{
    3838    error_t       error;
    39     paddr_t       paddr;
     39    vseg_t      * vseg;         // for user space checking
    4040    struct stat   k_stat;       // kernel space
    4141    xptr_t        file_xp;
     
    4646
    4747    // check stat structure in user space
    48     error = vmm_v2p_translate( false , u_stat , &paddr );
     48    error = vmm_get_vseg( process , (intptr_t)u_stat , &vseg );
    4949
    5050        if( error )
    5151        {
    52         printk("\n[ERROR] in %s : stat structure unmapped  for thread %x in process %x\n",
    53                __FUNCTION__ , this->trdid , process->pid );
     52
     53#if DEBUG_SYCALL_ERROR
     54printk("\n[ERROR] in %s : stat structure unmapped %x / thread %x / process %x\n",
     55__FUNCTION__ , (intptr_t)u_stat , this->trdid , process->pid );
     56vmm_display( process , false );
     57#endif
    5458                this->errno = EINVAL;
    5559                return -1;
  • trunk/kernel/syscalls/sys_thread_cancel.c

    r438 r440  
    2323
    2424#include <hal_types.h>
     25#include <hal_irqmask.h>
    2526#include <hal_remote.h>
    2627#include <hal_special.h>
     
    3233int sys_thread_cancel( trdid_t trdid )
    3334{
     35    reg_t        save_sr;       // required to enable IRQs
    3436    xptr_t       target_xp;     // target thread extended pointer
     37    cxy_t        target_cxy;    // target thread cluster identifier
     38    ltid_t       target_ltid;   // target thread local index
     39    cxy_t        owner_cxy;     // process owner cluster identifier
     40    xptr_t       owner_xp;      // extended pointer on owner process
    3541
    3642    // get killer thread pointers
    3743        thread_t   * this    = CURRENT_THREAD;
    3844    process_t  * process = this->process;
     45    pid_t        pid     = process->pid;
    3946
    4047    // get extended pointer on target thread
    41         target_xp  = thread_get_xptr( process->pid , trdid );
     48        target_xp  = thread_get_xptr( pid , trdid );
    4249
    4350    // check target_xp
     
    6168#endif
    6269
    63     // cal the relevant kernel function
    64     thread_kill( target_xp,
    65                  0,           // is_exit
    66                  0 );         // is forced
     70    // get process owner cluster identifier
     71    owner_cxy = CXY_FROM_PID( pid );
     72
     73    // get target thread ltid and cluster
     74    target_cxy  = CXY_FROM_TRDID( trdid );
     75    target_ltid = LTID_FROM_TRDID( trdid );
     76
     77    // If target thread is the main thread, the process must be deleted,
     78    // This require synchronisation with parent process
     79    if( (target_cxy == owner_cxy) && (target_ltid == 0) )
     80    {
     81        // get extended pointer on owner cluster
     82        owner_xp = cluster_get_owner_process_from_pid( pid );
     83
     84        // mark for delete all threads but the main
     85        hal_enable_irq( &save_sr );
     86        process_sigaction( pid , DELETE_ALL_THREADS );
     87        hal_restore_irq( save_sr );
     88
     89        // remove process from TXT list
     90        process_txt_detach( owner_xp );
     91
     92        // block the main thread
     93        thread_block( XPTR( local_cxy ,this ) , THREAD_BLOCKED_GLOBAL );
     94
     95        // atomically update owner process descriptor term_state to ask
     96        // the parent process sys_wait() function to delete the main thread
     97        hal_remote_atomic_or( XPTR( local_cxy , &process->term_state ) ,
     98                              PROCESS_TERM_EXIT );
     99    }
     100    else
     101    {
     102        // block target thread and mark it for delete
     103        thread_delete( target_xp , pid , false );
     104    }
    67105
    68106#if DEBUG_SYS_THREAD_CANCEL
  • trunk/kernel/syscalls/sys_thread_create.c

    r438 r440  
    5353        trdid_t          trdid;            // created thread identifier
    5454        process_t      * process;          // pointer on local process descriptor
    55         paddr_t          paddr;            // unused, required by vmm_v2p_translate()
     55        vseg_t         * vseg;             // required for user space checking
    5656    cxy_t            target_cxy;       // target cluster identifier
    5757        error_t          error;
     
    6767tm_start = hal_get_cycles();
    6868if( DEBUG_SYS_THREAD_CREATE < tm_start )
    69 printk("\n[DBG] %s : thread %x enter / process %x / cycle %d\n"
    70 __FUNCTION__ , parent , process->pid, (uint32_t)tm_start );
    71 #endif
    72 
    73         // check user_attr in user space & copy to kernel space
     69printk("\n[DBG] %s : thread %x (cxy %x) enter / process %x / cycle %d\n",
     70__FUNCTION__, parent, local_cxy, process->pid, (uint32_t)tm_start );
     71#endif
     72
     73    // check trdid buffer in user space
     74    error = vmm_get_vseg( process , (intptr_t)trdid_ptr , &vseg );
     75
     76    if ( error )
     77    {
     78
     79#if DEBUG_SYSCALLS_ERROR
     80printk("\n[ERROR] in %s : trdid buffer unmapped %x / thread %x / process %x\n",
     81__FUNCTION__ , (intptr_t)trdid_ptr, parent->trdid, process->pid );
     82vmm_display( process , false );
     83#endif
     84                parent->errno = EINVAL;
     85                return -1;
     86    }
     87
     88        // check user_attr buffer in user space & copy to kernel space
    7489    if( user_attr != NULL )
    7590    {
    76             error = vmm_v2p_translate( false , user_attr , &paddr );
     91            error = vmm_get_vseg( process , (intptr_t)user_attr , &vseg );
    7792
    7893            if( error )
     
    8095
    8196#if DEBUG_SYSCALLS_ERROR
    82 printk("\n[ERROR] in %s : user_attr unmapped\n", __FUNCTION__ );
     97printk("\n[ERROR] in %s : user_attr buffer unmapped %x / thread %x / process %x\n",
     98__FUNCTION__ , (intptr_t)user_attr , parent->trdid , process->pid );
     99vmm_display( process , false );
    83100#endif
    84101                    parent->errno = EINVAL;
     
    90107
    91108        // check start_func in user space
    92         error = vmm_v2p_translate( false , start_func , &paddr );
    93 
    94         if( error )
    95         {
    96 
    97 #if DEBUG_SYSCALLS_ERROR
    98 printk("\n[ERROR] in %s : start_func unmapped\n", __FUNCTION__ );
    99 #endif
    100                 parent->errno = EINVAL;
    101                 return -1;
    102         }
    103 
    104         // check start_arg in user space
    105         if( start_arg != NULL ) error = vmm_v2p_translate( false , start_arg , &paddr );
    106 
    107         if( error )
    108         {
    109 
    110 #if DEBUG_SYSCALLS_ERROR
    111 printk("\n[ERROR] in %s : start_arg unmapped\n", __FUNCTION__ );
    112 #endif
    113                 parent->errno = EINVAL;
    114                 return -1;
    115         }
    116 
    117         // check / define attributes an target_cxy
     109        error = vmm_get_vseg( process , (intptr_t)start_func , &vseg );
     110
     111    if( error )
     112    {
     113
     114#if DEBUG_SYSCALLS_ERROR
     115printk("\n[ERROR] in %s : start_func unmapped %x / thread %x / process %x\n",
     116__FUNCTION__ , (intptr_t)start_func , parent->trdid , process->pid );
     117vmm_display( process , false );
     118#endif
     119        parent->errno = EINVAL;
     120            return -1;
     121        }
     122
     123        // check start_arg buffer in user space
     124        if( start_arg != NULL )
     125    {
     126        error = vmm_get_vseg( process , (intptr_t)start_arg , &vseg );
     127
     128            if( error )
     129            {
     130
     131#if DEBUG_SYSCALLS_ERROR
     132printk("\n[ERROR] in %s : start_arg buffer unmapped %x / thread %x / process %x\n",
     133__FUNCTION__ , (intptr_t)start_arg , parent->trdid , process->pid );
     134vmm_display( process , false );
     135#endif
     136                    parent->errno = EINVAL;
     137                    return -1;
     138        }
     139        }
     140
     141    // define attributes and target_cxy
    118142    if( user_attr != NULL )                      // user defined attributes
    119143    {
     
    125149
    126150#if DEBUG_SYSCALLS_ERROR
    127 printk("\n[ERROR] in %s : illegal target cluster = %x\n", __FUNCTION__ , kern_attr.cxy );
     151printk("\n[ERROR] in %s : illegal target cluster = %x / thread %x / process %x\n",
     152__FUNCTION__ , kern_attr.cxy, parent->trdid, process->pid );
    128153#endif
    129154                            parent->errno = EINVAL;
     
    175200
    176201#if DEBUG_SYSCALLS_ERROR
    177 printk("\n[ERROR] in %s : cannot create thread\n", __FUNCTION__ );
    178 #endif
    179                 return ENOMEM;
     202printk("\n[ERROR] in %s : cannot create new thread / thread %x / process %x\n",
     203__FUNCTION__ , parent->trdid, process->pid );
     204#endif
     205                parent->errno = ENOMEM;
     206                return -1;
    180207        }
    181208
     
    184211        hal_copy_to_uspace( trdid_ptr , &trdid , sizeof(pthread_t) );
    185212
    186     // register child in parent if required
    187     if( user_attr != NULL )
    188     {
    189             if( (kern_attr.attributes & PT_ATTR_DETACH) == 0 )
    190                 thread_child_parent_link( parent_xp , child_xp );
    191     }
    192 
    193213    // activate new thread
    194214        thread_unblock( child_xp , THREAD_BLOCKED_GLOBAL );
     
    199219tm_end = hal_get_cycles();
    200220if( DEBUG_SYS_THREAD_CREATE < tm_end )
    201 printk("\n[DBG] %s : thread %x created thread %x for process %x in cluster %x / cycle %d\n"
    202 __FUNCTION__, parent, child_ptr, process->pid, target_cxy, (uint32_t)tm_end );
     221printk("\n[DBG] %s : thread %x (cxy %x) created thread %x (cxy %x) / process %x / cycle %d\n",
     222__FUNCTION__, parent, local_cxy, child_ptr, target_cxy, process->pid, (uint32_t)tm_end );
    203223#endif
    204224
  • trunk/kernel/syscalls/sys_thread_exit.c

    r438 r440  
    22 * sys_thread_exit.c - terminates the execution of calling thread
    33 *
    4  * Authors   Alain Greiner (2016,2017)
     4 * Authors   Alain Greiner (2016,2017,2018)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    2323
    2424#include <hal_types.h>
     25#include <hal_irqmask.h>
    2526#include <thread.h>
     27#include <process.h>
    2628#include <core.h>
    2729#include <vmm.h>
     
    3234int sys_thread_exit( void * exit_value )
    3335{
    34         thread_t  * this    = CURRENT_THREAD;
    35     process_t * process = this->process;
     36    reg_t       save_sr;    // required to enable IRQs
     37    xptr_t      owner_xp;   // extended pointer on owner process
     38 
     39        thread_t  * this      = CURRENT_THREAD;
     40    trdid_t     trdid     = this->trdid;
     41    process_t * process   = this->process;
     42    pid_t       pid       = process->pid;
     43    cxy_t       owner_cxy = CXY_FROM_PID( pid );
    3644
    3745    // check exit_value argument
     
    4048
    4149#if DEBUG_SYSCALLS_ERROR
    42 printk("\n[ERROR] in %s : exit_value argument must be NULL for thread %x in process %x\n",
    43 __FUNCTION__ , exit_value, this->trdid , process->pid );
     50printk("\n[ERROR] in %s : exit_value argument must be NULL / thread %x in process %x\n",
     51__FUNCTION__ , this , pid );
    4452#endif
    4553        this->errno = EINVAL;
     
    5361if( DEBUG_SYS_THREAD_EXIT < tm_start )
    5462printk("\n[DBG] %s : thread %x enter / process %x / cycle %d\n",
    55 __FUNCTION__ , this, process->pid , (uint32_t)tm_start );
     63__FUNCTION__ , this, pid , (uint32_t)tm_start );
    5664#endif
    5765
    58     // cal the relevant kernel function
    59     thread_kill( XPTR( local_cxy , this ),
    60                  1,           // is_exit
    61                  0 );         // is forced
     66    // If calling thread is the main thread, the process must be deleted.
     67    // This require to delete all process threads and synchronise with parent process
     68    if( (local_cxy == owner_cxy) && (LTID_FROM_TRDID(trdid) == 0) )
     69    {
     70        // get extended pointer on owner cluster
     71        owner_xp = cluster_get_owner_process_from_pid( pid );
     72
     73        // mark for delete all threads but the main
     74        hal_enable_irq( &save_sr );
     75        process_sigaction( pid , DELETE_ALL_THREADS );
     76        hal_restore_irq( save_sr );
     77
     78        // remove process from TXT list
     79        process_txt_detach( owner_xp );
     80
     81        // block the main thread
     82        thread_block( XPTR( local_cxy , this ) , THREAD_BLOCKED_GLOBAL );
     83
     84        // atomically update owner process descriptor term_state to ask
     85        // the parent process sys_wait() function to delete the main thread
     86        hal_remote_atomic_or( XPTR( local_cxy , &process->term_state ) ,
     87                              PROCESS_TERM_EXIT );
     88    }
     89    else
     90    {
     91        // block calling thread and mark it for delete,
     92        thread_delete( XPTR( local_cxy , this ) , pid , false );
     93    }
    6294
    6395#if DEBUG_SYS_THREAD_EXIT
     
    6597if( DEBUG_SYS_THREAD_EXIT < tm_end )
    6698printk("\n[DBG] %s : thread %x exit / process %x / cost %d / cycle %d\n",
    67 __FUNCTION__, this, this->process->pid, (uint32_t)(tm_end - tm_start), (uint32_t)tm_end );
     99__FUNCTION__, this, pid, (uint32_t)(tm_end - tm_start), (uint32_t)tm_end );
    68100#endif
    69101
    70     // deschedule <=> suicide, because blocked by thread_kill()
     102    // deschedule <=> suicide, because blocked by thread_delete()
    71103    sched_yield( "suicide after thread_exit" );
    72104   
  • trunk/kernel/syscalls/sys_timeofday.c

    r407 r440  
    22 * sys_timeofday.c - Get current time
    33 *
    4  * Author    Alain Greiner (2016,2017)
     4 * Author    Alain Greiner (2016,2017,2018)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    3737{
    3838        error_t        error;
    39     paddr_t        paddr;
     39    vseg_t       * vseg;
    4040
    4141        uint32_t       tm_s;
     
    5050    if( tz )
    5151    {
    52         printk("\n[ERROR] in %s for thread %x in process %x : tz argument must be NULL\n",
    53                __FUNCTION__ , this->trdid , process->pid );
     52
     53#if DEBUG_SYSCALLS_ERROR
     54printk("\n[ERROR] in %s for thread %x in process %x : tz argument must be NULL\n",
     55__FUNCTION__ , this->trdid , process->pid );
     56#endif
    5457        this->errno = EINVAL;
    5558        return -1;
     
    5760 
    5861    // check tv
    59     error = vmm_v2p_translate( false , tv , &paddr );
     62    error = vmm_get_vseg( process , (intptr_t)tv , &vseg );
    6063
    6164    if( error )
    6265    {
    63         printk("\n[ERROR] in %s for thread %x in process %x : tv argument unmapped\n",
    64         __FUNCTION__ , this->trdid , process->pid );
     66
     67#if DEBUG_SYSCALLS_ERROR
     68printk("\n[ERROR] in %s : user buffer tz unmapped / thread %x / process %x\n",
     69__FUNCTION__ , (intptr_t)tz , this->trdid , process->pid );
     70vmm_display( process , false );
     71#endif
    6572        this->errno = EINVAL;
    6673        return -1;
  • trunk/kernel/syscalls/sys_wait.c

    r438 r440  
    22 * sys_wait.c - wait termination or blocking of a child process.
    33 *
    4  * Author    Alain Greiner (2016,2017)
     4 * Author    Alain Greiner (2016,2017,2018)
    55 * 
    66 * Copyright (c) UPMC Sorbonne Universites
     
    3535{
    3636        error_t     error;
    37     paddr_t     paddr;
     37    vseg_t    * vseg;
    3838    xptr_t      iter_xp;
    3939    xptr_t      child_xp;
     
    5959
    6060    // check status in user space
    61     error = vmm_v2p_translate( false , status , &paddr );
     61    error = vmm_get_vseg( process, (intptr_t)status , &vseg );
    6262
    6363        if( error )
     
    6565
    6666#if DEBUG_SYSCALLS_ERROR
    67 printk("\n[ERROR] in %s : status buffer unmapped for thread %x in process %x\n",
    68 __FUNCTION__ , this->trdid , process->pid );
     67printk("\n[ERROR] in %s : status buffer %x unmapped for thread %x in process %x\n",
     68__FUNCTION__ , (intptr_t)status, this->trdid , process->pid );
     69vmm_display( process , false );
    6970#endif
    7071        this->errno = EINVAL;
  • trunk/kernel/syscalls/sys_write.c

    r438 r440  
    22 * sys_write.c - write bytes to a file
    33 *
    4  * Author        Alain Greiner (2016,2017)
     4 * Author        Alain Greiner (2016,2017,2018)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    3535/* TODO: concurrent user page(s) unmap need to be handled [AG] */
    3636
     37extern uint32_t enter_sys_write;
     38extern uint32_t enter_devfs_write;
     39extern uint32_t enter_txt_write;
     40extern uint32_t enter_chdev_cmd_write;
     41extern uint32_t enter_chdev_server_write;
     42extern uint32_t enter_tty_cmd_write;
     43extern uint32_t enter_tty_isr_write;
     44extern uint32_t exit_tty_isr_write;
     45extern uint32_t exit_tty_cmd_write;
     46extern uint32_t exit_chdev_server_write;
     47extern uint32_t exit_chdev_cmd_write;
     48extern uint32_t exit_txt_write;
     49extern uint32_t exit_devfs_write;
     50extern uint32_t exit_sys_write;
     51
    3752//////////////////////////////////
    3853int sys_write( uint32_t   file_id,
     
    4156{
    4257    error_t      error;
    43     paddr_t      paddr;           // required for user space checking
     58    vseg_t     * vseg;            // required for user space checking
    4459        xptr_t       file_xp;         // remote file extended pointer
    4560    uint32_t     nbytes;          // number of bytes actually written
    4661    reg_t        save_sr;         // required to enable IRQs during syscall
    4762
    48 #if (DEBUG_SYS_WRITE_DEBUG & 1)
    49 enter_sys_read = (uint32_t)tm_start;
     63#if (DEBUG_SYS_WRITE & 1)
     64enter_sys_write = (uint32_t)tm_start;
    5065#endif
    5166
     
    7489
    7590    // check user buffer in user space
    76     error = vmm_v2p_translate( false , vaddr , &paddr );
     91    error = vmm_get_vseg( process , (intptr_t)vaddr , &vseg );
    7792
    7893    if ( error )
     
    8095
    8196#if DEBUG_SYSCALLS_ERROR
    82 printk("\n[ERROR] in %s : user buffer unmapped = %x\n", __FUNCTION__ , (intptr_t)vaddr );
     97printk("\n[ERROR] in %s : user buffer unmapped %x / thread %x / process %x\n",
     98__FUNCTION__ , (intptr_t)vaddr, this->trdid, process->pid );
     99vmm_display( process , false );
    83100#endif
    84101                this->errno = EINVAL;
  • trunk/kernel/syscalls/syscalls.h

    r437 r440  
    169169/******************************************************************************************
    170170 * [10] This function implement the exit system call terminating a POSIX process.
     171 * It can be called by any thread running in any cluster.
     172 * It uses both remote accesses to access the owner process descriptor, ans the
     173 * RPC_PROCESS_SIGACTION to delete remote process and thread descriptors
    171174 * In the present implementation, this function implements actually the _exit():
    172  * - it does not flush open ourput steams.
     175 * - it does not flush open output streams.
    173176 * - it does not close open streams.
    174177 ******************************************************************************************
     
    619622int sys_fg( pid_t   pid );
    620623
     624int sys_place( uint32_t cxy,
     625               uint32_t lid );
    621626
    622627#endif  // _SYSCALLS_H_
Note: See TracChangeset for help on using the changeset viewer.