Changeset 23 for trunk/kernel/syscalls


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

Introduce syscalls.

Location:
trunk/kernel/syscalls
Files:
1 added
1 deleted
37 edited
4 moved

Legend:

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

    r1 r23  
    11/*
    2  * kern/sys_alarm.c - timed sleep/wakeup
     2 * sys_alarm.c - timed sleep/wakeup
    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)
     5*
     6 * Copyright (c) UPMC Sorbonne Universites
    67 *
    7  * This file is part of ALMOS-kernel.
     8 * This file is part of ALMOS-MKH.
    89 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1718 *
    1819 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2021 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2122 */
    2223
    23 #include <types.h>
     24#include <hal_types.h>
    2425#include <thread.h>
     26#include <printk.h>
    2527#include <cluster.h>
    26 #include <task.h>
    27 #include <time.h>
     28#include <process.h>
    2829#include <scheduler.h>
    29 #include <cpu.h>
    30 #include <cpu-trace.h>
     30#include <core.h>
    3131
    32 EVENT_HANDLER(sys_alarm_event_handler)
     32////////////////////////////////
     33int sys_alarm( uint64_t cycles )
    3334{
    34         struct thread_s *thread;
     35    thread_t  * this    = CURRENT_THREAD;
     36    process_t * process = this->process;
    3537
    36         thread = event_get_argument(event);
    37         sched_wakeup(thread);
    38         return 0;
    39 }
    40 
    41 int sys_alarm (unsigned nb_sec)
    42 {
    43         struct thread_s *this;
    44         struct event_s event;
    45         struct alarm_info_s info;
    46 
    47         if( nb_sec == 0)
    48                 return 0;
    49 
    50         this = current_thread;
    51         event_set_handler(&event, &sys_alarm_event_handler);
    52         event_set_priority(&event, E_FUNC);
    53         event_set_argument(&event,this);
    54         info.event = &event;
    55 
    56         alarm_wait(&info, nb_sec * 4);
    57         sched_sleep(this);
    58         return 0;
     38    printk("\n[ERROR] in %s for thread %x in process %x : not implemented yet\n",
     39           __FUNCTION__ , this->trdid , process->pid );
     40    this->errno = EFAULT;
     41    return -1;
    5942}
    6043
    6144
     45
  • trunk/kernel/syscalls/sys_barrier.c

    r1 r23  
    11/*
    2  * kern/sys_barrier.c - barrier service interface for userland
     2 * sys_barrier.c - Access a POSIX barrier.
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * authors       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 */
    2223
    23 #include <types.h>
     24#include <hal_types.h>
     25#include <hal_special.h>
    2426#include <errno.h>
    2527#include <thread.h>
    26 #include <task.h>
    27 #include <kmem.h>
     28#include <printk.h>
    2829#include <vmm.h>
    29 #include <kmagics.h>
    30 #include <barrier.h>
     30#include <syscalls.h>
     31#include <remote_barrier.h>
    3132
    32 int sys_barrier(struct barrier_s **barrier, uint_t operation, uint_t count)
     33//////////////////////////////////
     34int sys_barrier( void     * vaddr,
     35                 uint32_t   operation,
     36                 uint32_t   count )
    3337{
    34         kmem_req_t req;
    35         struct barrier_s *ibarrier;
    36         error_t err = EINVAL;
     38        error_t      error;
     39    paddr_t      paddr;
    3740 
    38         if((err = vmm_check_address("usr barrier ptr",
    39                                     current_task,
    40                                     barrier,
    41                                     sizeof(struct barrier_s*))))
    42                 goto SYS_BARRIER_END;
     41    thread_t   * this = CURRENT_THREAD;
    4342
    44         if((err = cpu_copy_from_uspace(&ibarrier, barrier, sizeof(struct barrier_s *))))
    45                 goto SYS_BARRIER_END;
     43    // check vaddr in user vspace
     44        error = vmm_v2p_translate( false , vaddr , &paddr );
     45        if( error )
     46    {
     47        printk("\n[ERROR] in %s : illegal barrier virtual address = %x\n",
     48               __FUNCTION__ , (intptr_t)vaddr );
     49        this->errno = error;
     50        return -1;
     51    }
    4652
    47         switch(operation)
     53    // execute requested operation
     54        switch( operation )
    4855        {
    49         case BARRIER_INIT_PRIVATE:
    50         case BARRIER_INIT_SHARED:
    51                 req.type  = KMEM_BARRIER;
    52                 req.size  = sizeof(*ibarrier);
    53                 req.flags = AF_USER;
     56        //////////////////
     57            case BARRIER_INIT:
     58        {
     59            error = remote_barrier_create( (intptr_t)vaddr , count );
     60   
     61                    if( error )
     62            {
     63                printk("\n[ERROR] in %s : cannot create barrier = %x\n",
     64                       __FUNCTION__ , (intptr_t)vaddr );
     65                this->errno = error;
     66                return -1;
     67            }
     68                        break;
     69        }
     70        //////////////////
     71            case BARRIER_WAIT:
     72        {
     73            xptr_t barrier_xp = remote_barrier_from_ident( (intptr_t)vaddr );
    5474
    55                 if((ibarrier = kmem_alloc(&req)) == NULL)
    56                 {
    57                         err = ENOMEM;
    58                         break;
    59                 }
    60    
    61                 if((err = barrier_init(ibarrier, count, operation)))
    62                         break;
    63    
    64                 if((err = cpu_copy_to_uspace(barrier, &ibarrier, sizeof(struct barrier_s *))))
    65                 {
    66                         req.ptr = ibarrier;
    67                         kmem_free(&req);
    68                 }
    69                 break;
     75            if( barrier_xp == XPTR_NULL )     // user error
     76            {
     77                printk("\n[ERROR] in %s : barrier %x not registered\n",
     78                       __FUNCTION__ , (intptr_t)vaddr );
     79                this->errno = EINVAL;
     80                return -1;
     81            }
     82            else                          // success
     83            {
     84                remote_barrier_wait( barrier_xp );
     85            }
     86            break;
     87        }
     88        /////////////////////
     89            case BARRIER_DESTROY:
     90        {
     91            xptr_t barrier_xp = remote_barrier_from_ident( (intptr_t)vaddr );
    7092
    71         case BARRIER_WAIT:
     93            if( barrier_xp == XPTR_NULL )     // user error
     94            {
     95                printk("\n[ERROR] in %s : barrier %x not registered\n",
     96                       __FUNCTION__ , (intptr_t)vaddr );
     97                this->errno = EINVAL;
     98                return -1;
     99            }
     100            else                          // success
     101            {
     102                remote_barrier_destroy( barrier_xp );
     103            }
     104            break;
     105        }
     106        ////////
     107            default:
     108        {
     109            printk("\n[PANIC] in %s : illegal operation type\n", __FUNCTION__ );
     110            hal_core_sleep();
     111        }
     112        }  // end switch
    72113
    73                 if((err = vmm_check_object(ibarrier, struct barrier_s, BARRIER_ID)))
    74                         break;
     114        return 0;
    75115
    76                 err = barrier_wait(ibarrier);
    77                 break;
     116}  // end sys_barrier()
    78117
    79         case BARRIER_DESTROY:
    80    
    81                 if((err = vmm_check_object(ibarrier, struct barrier_s, BARRIER_ID)))
    82                         break;
    83    
    84                 if((err = barrier_destroy(ibarrier)))
    85                         break;
    86    
    87                 req.type = KMEM_BARRIER;
    88                 req.ptr  = ibarrier;
    89                 kmem_free(&req);
    90                 return 0;
    91 
    92         default:
    93                 err = EINVAL;
    94         }
    95 
    96 SYS_BARRIER_END:
    97         current_thread->info.errno = err;
    98         return err;
    99 }
    100 
    101 KMEM_OBJATTR_INIT(barrier_kmem_init)
    102 {
    103         attr->type   = KMEM_BARRIER;
    104         attr->name   = "KCM Barrier";
    105         attr->size   = sizeof(struct barrier_s);
    106         attr->aligne = 0;
    107         attr->min    = CONFIG_BARRIER_MIN;
    108         attr->max    = CONFIG_BARRIER_MAX;
    109         attr->ctor   = NULL;
    110         attr->dtor   = NULL;
    111         return 0;
    112 }
  • trunk/kernel/syscalls/sys_chdir.c

    r11 r23  
    11/*
    2  * sys_chdir: change process current work directory
     2 * sys_chdir: change process current working directory
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
     4 * Author    Alain Greiner (2016,2017)
     5 *
    56 * Copyright (c) 2011,2012 UPMC Sorbonne Universites
    67 *
    7  * This file is part of ALMOS-kernel.
     8 * This file is part of ALMOS-MKH.
    89 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1718 *
    1819 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2021 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2122 */
    2223
    23 #include <cpu.h>
     24#include <hal_types.h>
     25#include <hal_uspace.h>
    2426#include <chdev.h>
    25 #include <driver.h>
    2627#include <rwlock.h>
    2728#include <vfs.h>
    28 #include <sys-vfs.h>
     29#include <errno.h>
    2930#include <thread.h>
    30 #include <ku_transfert.h>
    31 #include <task.h>
     31#include <printk.h>
     32#include <process.h>
    3233
    33 int sys_chdir (char *pathname)
     34/////////////////////////////////
     35int sys_chdir ( char * pathname )
    3436{
    35         register error_t err = 0;
    36         register struct thread_s *this;
    37         register struct task_s *task;
    38         struct ku_obj ku_path;
     37        error_t   error;
     38    paddr_t   paddr;
     39    uint32_t  length;
     40    char      kbuf[CONFIG_VFS_MAX_PATH_LENGTH];
    3941
    40         this = current_thread;
    41         task = current_task;
     42        thread_t  * this    = CURRENT_THREAD;
     43    process_t * process = this->process;
    4244
    43         if(!pathname)
     45    // check pathname in user space
     46    error = vmm_v2p_translate( false , pathname , &paddr );
     47
     48        if( error )
    4449        {
    45                 this->info.errno = EINVAL;
     50        printk("\n[ERROR] in %s : user buffer unmapped  for thread %x in process %x\n",
     51               __FUNCTION__ , this->trdid , process->pid );
     52                this->errno = EINVAL;
    4653                return -1;
    4754        }       
    4855     
    49         KU_BUFF(ku_path, pathname);
    50         rwlock_wrlock(&task->cwd_lock);
     56    // get pathname length
     57    length = hal_strlen_from_uspace( pathname );
     58
     59    if( length >= CONFIG_VFS_MAX_PATH_LENGTH )
     60    {
     61        printk("\n[ERROR] in %s : pathname too long for thread %x in process %x\n",
     62               __FUNCTION__ , this->trdid , process->pid );
     63                this->errno = ENFILE;
     64        return -1;
     65    }
     66 
     67        // get pathname copy in kernel space
     68    hal_copy_from_uspace( kbuf, pathname, length );
     69
     70    // get cluster and local pointer on reference process
     71    xptr_t      ref_xp  = process->ref_xp;
     72    process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
     73    cxy_t       ref_cxy = GET_CXY( ref_xp );
     74
     75    // get extended pointer on cwd lock in reference process
     76    xptr_t lock_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
    5177       
    52         if((err = vfs_chdir(&ku_path, &task->vfs_cwd)))
     78    // get cwd lock in read mode
     79        remote_rwlock_rd_lock( lock_xp );
     80
     81    // call relevant VFS function
     82        error = vfs_chdir( process->vfs_cwd_xp , kbuf );
     83
     84    // release cwd lock
     85        remote_rwlock_rd_unlock( lock_xp );
     86
     87        if( error )
    5388        {
    54                 rwlock_unlock(&task->cwd_lock);
    55                 this->info.errno = (err < 0) ? -err : err;
     89        printk("\n[ERROR] in %s : cannot change current directory\n", __FUNCTION__ );
     90                this->errno = error;
    5691                return -1;
    5792        }
    5893   
    59         rwlock_unlock(&task->cwd_lock);
    6094        return 0;
    6195}
  • trunk/kernel/syscalls/sys_chmod.c

    r11 r23  
    11/*
    2  * sys_chmod: change file mode
     2 * sys_chmod.c - Change file access rights.
    33 *
     4 * Author    Alain Greiner  (2016,2017)
     5 *
    46 * Copyright (c) 2015 UPMC Sorbonne Universites
    57 *
    6  * This file is part of ALMOS-kernel.
     8 * This file is part of ALMOS-MKH.
    79 *
    8  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    911 * under the terms of the GNU General Public License as published by
    1012 * the Free Software Foundation; version 2.0 of the License.
    1113 *
    12  * 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
    1315 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1416 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1618 *
    1719 * You should have received a copy of the GNU General Public License
    18  * 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,
    1921 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2022 */
    2123
    22 #include <cpu.h>
    23 #include <chdev.h>
    24 #include <driver.h>
    25 #include <rwlock.h>
     24#include <hal_types.h>
     25#include <hal_uspace.h>
    2626#include <vfs.h>
    27 #include <sys-vfs.h>
     27#include <vmm.h>
     28#include <printk.h>
    2829#include <thread.h>
    29 #include <ku_transfert.h>
    30 #include <task.h>
     30#include <process.h>
    3131
    32 int sys_chmod (char *pathname, uint_t mode)
     32//////////////////////////////////
     33int sys_chmod( char    * pathname,
     34               uint32_t  rights )
    3335{
    34         register error_t err = 0;
    35         register struct thread_s *this;
    36         register struct task_s *task;
    37         struct ku_obj ku_path;
     36    error_t     error;
     37    paddr_t     paddr;
     38    uint32_t    length;
     39    char        kbuf[CONFIG_VFS_MAX_PATH_LENGTH];
     40       
     41        thread_t  * this    = CURRENT_THREAD;
     42        process_t * process = this->process;
    3843
    39         this = current_thread;
    40         task = current_task;
     44    // check pathname in user space
     45    error = vmm_v2p_translate( false , pathname , &paddr );
    4146
    42         if(!pathname || NOT_IN_USPACE(pathname))
     47        if( error )
    4348        {
    44                 this->info.errno = EINVAL;
     49        printk("\n[ERROR] in %s : user pathname unmapped for thread %x in process %x\n",
     50               __FUNCTION__ , this->trdid , process->pid );
     51                this->errno = EINVAL;
    4552                return -1;
    4653        }       
    47        
    48      
    49         KU_BUFF(ku_path, pathname);
    50         rwlock_wrlock(&task->cwd_lock);
    51        
    52         if((err = vfs_chmod(&ku_path, &task->vfs_cwd, mode)))
     54
     55    // get pathname length
     56    length = hal_strlen_from_uspace( pathname );
     57
     58    if( length >= CONFIG_VFS_MAX_PATH_LENGTH )
     59    {
     60        printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ );
     61                this->errno = ENFILE;
     62        return -1;
     63    }
     64 
     65        // get pathname copy in kernel space
     66    hal_copy_from_uspace( kbuf, pathname, length );
     67
     68    // get cluster and local pointer on reference process
     69    xptr_t      ref_xp  = process->ref_xp;
     70    process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
     71    cxy_t       ref_cxy = GET_CXY( ref_xp );
     72
     73    // get extended pointer on cwd inode
     74    xptr_t cwd_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->vfs_cwd_xp ) );
     75   
     76    // get the cwd lock in read mode from reference process
     77        remote_rwlock_rd_lock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
     78
     79    // call the relevant VFS function
     80        error = vfs_chmod( cwd_xp,
     81                       kbuf,
     82                       rights );
     83
     84    // release the cwd lock
     85        remote_rwlock_rd_unlock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
     86
     87    if( error )
    5388        {
    54                 rwlock_unlock(&task->cwd_lock);
    55                 this->info.errno = (err < 0) ? -err : err;
     89        printk("\n[ERROR] in %s : cannot remove directory %s\n",
     90               __FUNCTION__ , kbuf );
     91                this->errno = error;
    5692                return -1;
    5793        }
    5894   
    59         rwlock_unlock(&task->cwd_lock);
    6095        return 0;
    61 }
     96
     97}  // end sys_chmod()   
  • trunk/kernel/syscalls/sys_clock.c

    r1 r23  
    11/*
    2  * sys_clock: get system current time
     2 * sys_clock: get calling core cycles count
    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)
     5 * 
     6 * Copyright (c) UPMC Sorbonne Universites
    67 *
    7  * This file is part of ALMOS-kernel.
     8 * This file is part of ALMOS-MKH.
    89 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1718 *
    1819 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2021 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2122 */
    2223
     24#include <hal_types.h>
     25#include <hal_uspace.h>
    2326#include <errno.h>
    24 #include <config.h>
    25 #include <cpu.h>
     27#include <core.h>
    2628#include <thread.h>
     29#include <process.h>
     30#include <vmm.h>
     31#include <printk.h>
    2732
    28 int sys_clock(uint64_t *val)
     33//////////////////////////////////
     34int sys_clock (uint64_t * cycles )
    2935{
    30         error_t err;
    31         uint64_t cycles;
     36        error_t   error;
     37    paddr_t   paddr;
     38        uint64_t  k_cycles;
    3239
    33         if((val == NULL) || NOT_IN_USPACE((uint_t)val))
     40    thread_t  * this    = CURRENT_THREAD;
     41    process_t * process = this->process;
     42
     43    // check buffer in user space
     44    error = vmm_v2p_translate( false , cycles , &paddr );
     45
     46        if( error )
    3447        {
    35                 err = EINVAL;
    36                 goto fail_inval;
     48        printk("\n[ERROR] in %s : user buffer unmapped for thread %x in process %x\n",
     49               __FUNCTION__ , this->trdid , process->pid );
     50        this->errno = EFAULT;
     51                return -1;
    3752        }
    3853
    39         cycles = cpu_get_cycles(current_cpu);
    40         err    = cpu_copy_to_uspace(val, &cycles, sizeof(cycles));
     54    // call relevant core function
     55        k_cycles = core_get_cycles( this->core );
    4156
    42 fail_inval:
    43         current_thread->info.errno = err;
    44         return err;
    45 }
     57    // copy to user space
     58        hal_copy_to_uspace( cycles , &k_cycles , sizeof(uint64_t) );
     59
     60        return 0;
     61
     62}  // end sys_clock()
  • trunk/kernel/syscalls/sys_close.c

    r11 r23  
    11/*
    2  * sys_close.c  close a process open file
     2 * sys_close.c  close an open file
    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 */
    2223
    23 #include <cpu.h>
    24 #include <chdev.h>
    25 #include <driver.h>
     24#include <kernel_config.h>
     25#include <hal_types.h>
     26#include <hal_special.h>
    2627#include <vfs.h>
    27 #include <sys-vfs.h>
    2828#include <process.h>
    2929#include <thread.h>
    30 #include <config.h>
     30#include <printk.h>
    3131
    32 /////////////////////////////
    33 int sys_close ( uint32_t fd )
     32//////////////////////////////////
     33int sys_close ( uint32_t file_id )
    3434{
    35         register process_t * process = current_process;
    36         register thread_t  * this    = current_thread;
    37         struct vfs_file_s  * file    = NULL;
    38         error_t              err;
    39  
    40         if(( fd >= CONFIG_TASK_FILE_MAX_NR ) || (process_fd_lookup( process , fd , &file )))
     35    error_t     error;
     36    xptr_t      file_xp;
     37
     38        thread_t  * this    = CURRENT_THREAD;
     39        process_t * process = this->process;
     40
     41    // check file_id argument
     42        if( file_id >= CONFIG_PROCESS_FILE_MAX_NR )
    4143        {
    42                 this->info.errno = EBADFD;
     44        printk("\n[ERROR] in %s : illegal file descriptor index = %d\n",
     45               __FUNCTION__ , file_id );
     46                this->errno = EBADFD;
    4347                return -1;
    4448        }
    4549
    46         err = vfs_close( file , NULL );
    47         if( err )
     50    // get extended pointer on remote file descriptor
     51    file_xp = process_fd_get_xptr( process , file_id );
     52
     53    if( file_xp == XPTR_NULL )
     54    {
     55        printk("\n[ERROR] in %s : undefined file descriptor = %d\n",
     56               __FUNCTION__ , file_id );
     57                this->errno = EBADFD;
     58                return -1;
     59    }
     60
     61    // call the relevant VFS function
     62        error = vfs_close( file_xp , file_id );
     63
     64        if( error )
    4865        {
    49                 this->info.errno = err;
     66        printk("\n[ERROR] in %s : cannot close file descriptor = %d\n",
     67               __FUNCTION__ , file_id );
     68                this->errno = error;
    5069                return -1;
    5170        }
    5271
    53         process_fd_release( process , fd );
    54         cpu_wbflush();
     72        hal_wbflush();
     73
    5574        return 0;
    5675}
  • trunk/kernel/syscalls/sys_closedir.c

    r1 r23  
    11/*
    2  * sys_closedir.c close a process open directory
     2 * sys_closedir.c - Close an open directory.
    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 */
    2223
     24#include <hal_types.h>
    2325#include <vfs.h>
    24 #include <sys-vfs.h>
    2526#include <thread.h>
     27#include <printk.h>
    2628#include <process.h>
    2729
    28 ////////////////////////////////
    29 int sys_closedir ( uint32_t fd )
     30/////////////////////////////////////
     31int sys_closedir ( uint32_t file_id )
    3032{
    31         register thread_t  * this    = current-thread;
    32         register process_t * process = current_process;
    33         struct vfs_file_s  * file    = NULL;
    34         error_t              err;
     33        error_t        error;
     34        xptr_t         file_xp;   // extended pointer on searched directory file descriptor
    3535
    36         if(( fd >= CONFIG_TASK_FILE_MAX_NR ) || (process_fd_lookup( process , fd , &file )))
     36        thread_t     * this     = CURRENT_THREAD;
     37        process_t    * process  = this->process;
     38
     39    // check file_id argument
     40        if( file_id >= CONFIG_PROCESS_FILE_MAX_NR )
    3741        {
    38                 this->info.errno = EBADFD;
     42        printk("\n[ERROR] in %s : illegal file descriptor index %d\n",
     43               __FUNCTION__ , file_id );
     44        this->errno = EBADFD;
    3945                return -1;
    4046        }
    4147
    42         err  = vfs_closedir( file , NULL );
    43         if(err)
     48    // get extended pointer on remote file descriptor
     49    file_xp = process_fd_get_xptr( process , file_id );
     50
     51    if( file_xp == XPTR_NULL )
     52    {
     53        printk("\n[ERROR] in %s : undefined file descriptor index = %d\n",
     54               __FUNCTION__ , file_id );
     55                this->errno = EBADFD;
     56                return -1;
     57    }
     58
     59    // call relevant VFS function
     60        error  = vfs_close( file_xp , file_id );
     61
     62        if( error )
    4463        {
    45                 this->info.errno = (err < 0) ? -err : err;
     64        printk("\n[ERROR] in %s : cannot close the directory = %d\n",
     65               __FUNCTION__ , file_id );
     66                this->errno = error;
    4667                return -1;
    4768        }
    4869
    49         process_fd_release( process , fd );
    5070        return 0;
    51 }
     71
     72}  // end sys_closedir()
  • trunk/kernel/syscalls/sys_condvar.c

    r15 r23  
    11/*
    2  * sys_cond_var: interface to access condition vraibles service
     2 * sys_condvar.c - Access a POSIX condvar.
    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 */
    2223
    23 #include <types.h>
     24#include <hal_types.h>
     25#include <hal_special.h>
    2426#include <errno.h>
    2527#include <thread.h>
    26 #include <kmem.h>
    27 #include <task.h>
     28#include <printk.h>
    2829#include <vmm.h>
    29 #include <kmagics.h>
    30 #include <semaphore.h>
    31 #include <cond_var.h>
     30#include <syscalls.h>
     31#include <remote_condvar.h>
    3232
    33 static inline bool_t isBadSem(struct semaphore_s *sem)
    34 {
    35         return vmm_check_object(sem, struct semaphore_s, SEMAPHORE_ID);
    36 }
     33////////////////////////////////////////
     34int sys_condvar( void         * condvar,
     35                 uint32_t       operation,
     36                 void         * mutex )
     37{
     38        error_t    error;
     39    paddr_t    paddr;
     40 
     41    thread_t * this = CURRENT_THREAD;
    3742
    38 static inline bool_t isBadCV(struct cv_s *cv)
    39 {
    40         return vmm_check_object(cv, struct cv_s, COND_VAR_ID);
    41 }
     43    // check condvar in user vspace
     44        error = vmm_v2p_translate( false , condvar , &paddr );
     45        if( error )
     46    {
     47        printk("\n[ERROR] in %s : illegal condvar virtual address = %x\n",
     48               __FUNCTION__ , (intptr_t)condvar );
     49        this->errno = error;
     50        return -1;
     51    }
    4252
    43 int sys_cond_var(struct cv_s **cv, uint_t operation, struct semaphore_s **sem)
    44 {
    45         kmem_req_t req;
    46         struct cv_s *icv;
    47         struct semaphore_s *isem;
    48         error_t err = EINVAL;
    49  
    50         if((err = vmm_check_address("usr cv ptr", current_task,cv,sizeof(struct cv_s*))))
    51                 goto SYS_COND_END;
     53    // execute requested operation
     54        switch( operation )
     55        {
     56        //////////////////
     57        case CONDVAR_INIT:
     58        {
     59            error = remote_condvar_create( (intptr_t)condvar );
     60   
     61                    if( error )
     62            {
     63                printk("\n[ERROR] in %s : cannot create condvar = %x\n",
     64                       __FUNCTION__ , (intptr_t)condvar );
     65                this->errno = error;
     66                return -1;
     67            }
     68                    break;
     69        }
     70        //////////////////
     71            case CONDVAR_WAIT:
     72        {
     73            // check mutex in user vspace
     74                error = vmm_v2p_translate( false , mutex , &paddr );
    5275
    53         if((err = cpu_copy_from_uspace(&icv, cv, sizeof(struct cv_s *))))
    54                 goto SYS_COND_END;
     76                if( error )
     77            {
     78                printk("\n[ERROR] in %s : illegal condvar virtual address = %x\n",
     79                       __FUNCTION__ , (intptr_t)condvar );
     80                this->errno = error;
     81                return -1;
     82            }
    5583
    56         switch(operation)
    57         {
    58         case CV_INIT:
    59                 req.type  = KMEM_CV;
    60                 req.size  = sizeof(*icv);
    61                 req.flags = AF_USER;
     84            xptr_t condvar_xp = remote_condvar_from_ident( (intptr_t)condvar );
     85
     86            if( condvar_xp == XPTR_NULL )     // user error
     87            {
     88                printk("\n[ERROR] in %s : condvar %x not registered\n",
     89                       __FUNCTION__ , (intptr_t)condvar );
     90                this->errno = EINVAL;
     91                return -1;
     92            }
    6293   
    63                 if((icv = kmem_alloc(&req)) == NULL)
    64                 {
    65                         err = ENOMEM;
    66                         break;
     94            xptr_t mutex_xp = remote_condvar_from_ident( (intptr_t)condvar );
     95            if( mutex_xp == XPTR_NULL )     // user error
     96            {
     97                printk("\n[ERROR] in %s : mutex %x not registered\n",
     98                       __FUNCTION__ , (intptr_t)condvar );
     99                this->errno = EINVAL;
     100                return -1;
     101            }
     102
     103            remote_condvar_wait( condvar_xp , mutex_xp );
     104
     105            break;
     106        }
     107        ////////////////////
     108            case CONDVAR_SIGNAL:
     109        {
     110            xptr_t condvar_xp = remote_condvar_from_ident( (intptr_t)condvar );
     111
     112            if( condvar_xp == XPTR_NULL )     // user error
     113            {
     114                printk("\n[ERROR] in %s : condvar %x not registered\n",
     115                       __FUNCTION__ , (intptr_t)condvar );
     116                this->errno = EINVAL;
     117                return -1;
     118            }
     119
     120            remote_condvar_signal( condvar_xp );
     121           
     122            break;
     123        }
     124        ///////////////////////
     125            case CONDVAR_BROADCAST:
     126        {
     127            xptr_t condvar_xp = remote_condvar_from_ident( (intptr_t)condvar );
     128
     129            if( condvar_xp == XPTR_NULL )     // user error
     130            {
     131                printk("\n[ERROR] in %s : condvar %x not registered\n",
     132                       __FUNCTION__ , (intptr_t)condvar );
     133                this->errno = EINVAL;
     134                return -1;
     135            }
     136
     137            remote_condvar_broadcast( condvar_xp );
     138
     139            break;
     140        }
     141        /////////////////////
     142            case CONDVAR_DESTROY:
     143        {
     144            xptr_t condvar_xp = remote_condvar_from_ident( (intptr_t)condvar );
     145
     146            if( condvar_xp == XPTR_NULL )     // user error
     147            {
     148                printk("\n[ERROR] in %s : condvar %x not registered\n",
     149                       __FUNCTION__ , (intptr_t)condvar );
     150                this->errno = EINVAL;
     151                return -1;
     152            }
     153
     154            remote_condvar_destroy( condvar_xp );
     155
     156            break;
    67157                }
    68    
    69                 if((err = cv_init(icv)))
    70                         break;
    71    
    72                 if((err = cpu_copy_to_uspace(cv, &icv, sizeof(struct cv_s *))))
    73                 {
    74                         req.ptr = icv;
    75                         kmem_free(&req);
    76                 }
     158        /////////
     159            default:
     160        {
     161            printk("\n[PANIC] in %s : illegal operation type\n", __FUNCTION__ );
     162            hal_core_sleep();
     163        }
     164        }   // end switch
    77165
    78                 break;
     166        return 0;
    79167
    80         case CV_WAIT:
    81                 err = vmm_check_address("usr sem ptr",
    82                                         current_task,
    83                                         sem, sizeof(struct semaphore_s*));
     168}  // enc sys_condvar()
    84169
    85                 if(err) break;
    86 
    87                 if((err = cpu_copy_from_uspace(&isem, sem, sizeof(struct semaphore_s *))))
    88                         break;
    89 
    90                 if(isBadSem(isem))
    91                         break;
    92 
    93                 if(isBadCV(icv))
    94                         break;
    95    
    96                 return cv_wait(icv, isem);
    97 
    98         case CV_SIGNAL:
    99                 if(isBadCV(icv))
    100                         break;
    101    
    102                 return cv_signal(icv);
    103 
    104         case CV_BROADCAST:
    105                 if(isBadCV(icv))
    106                         break;
    107    
    108                 return cv_broadcast(icv);
    109 
    110         case CV_DESTROY:
    111                 if(isBadCV(icv))
    112                         break;
    113    
    114                 if((err = cv_destroy(icv)))
    115                         break;
    116    
    117                 req.type = KMEM_CV;
    118                 req.ptr  = icv;
    119                 kmem_free(&req);
    120                 return 0;
    121 
    122         default:
    123                 err = EINVAL;
    124         }
    125 
    126 SYS_COND_END:
    127         current_thread->info.errno = err;
    128         return err;
    129 }
    130 
    131 KMEM_OBJATTR_INIT(cv_kmem_init)
    132 {
    133         attr->type   = KMEM_CV;
    134         attr->name   = "KCM Condition Variable";
    135         attr->size   = sizeof(struct cv_s);
    136         attr->aligne = 0;
    137         attr->min    = CONFIG_CONDTION_VAR_MIN;
    138         attr->max    = CONFIG_CONDTION_VAR_MAX;
    139         attr->ctor   = NULL;
    140         attr->dtor   = NULL;
    141  
    142         return 0;
    143 }
  • trunk/kernel/syscalls/sys_creat.c

    r1 r23  
    11/*
    2  * kern/sys_creat.c - create a file
     2 * sys_creat.c - create a file
    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)
     5 *
     6 * Copyright (c) UPMC Sorbonne Universites
    67 *
    78 * This file is part of ALMOS-kernel.
     
    2122 */
    2223
    23 #include <config.h>
     24#include <hal_types.h>
    2425#include <vfs.h>
    25 #include <sys-vfs.h>
    26 #include <spinlock.h>
    27 #include <process.h>
    28 #include <thread.h>
     26#include <syscalls.h>
    2927
    3028////////////////////////////////////
    31 int sys_creat ( char     * pathname,
    32                 uint32_t   mode )
     29int sys_creat( char     * pathname,
     30               uint32_t   mode )
    3331{
    34         CPU_HW_TRACE(sys_creat);
     32        uint32_t    flags = O_CREAT;
    3533
    36         register error_t     err;
    37         register uint32_t    flags;
    38         register thread_t  * this    = durrent_thread;
    39         register process_t * process = current_process;
    40         struct vfs_file_s    file;
    41         struct ku_obj        ku_path;
    42         uint32_t             fd      = (uint32_t)-1;
    43    
    44         if( process_fd_array_full( process ) )
    45         {
    46                 this->info.errno = ENFILE;
    47             CPU_HW_TRACE(sys_creat);
    48         return fd;
    49         }
    50 
    51         flags = 0;
    52         KU_BUFF( ku_path , pathname );
    53 
    54     // get the cwd lock
    55         rwlock_rdlock( &process->cwd_lock );
    56 
    57         err = vfs_create( &process->vfs_cwd , &ku_path , flags , mode , &file );
    58         if( err )
    59         {
    60                 this->info.errno = (err < 0 ) ? -err : err;
    61             rwlock_unlock( &process->cwd_lock );
    62             CPU_HW_TRACE(sys_creat);
    63             return fd;
    64         }
    65 
    66         err = process_fd_set( process , &file , &fd );
    67         if( err )
    68         {
    69                 vfs_close( &file , NULL );
    70                 this->info.errno = err;
    71         }
    72 
    73         rwlock_unlock( &process->cwd_lock );
    74         CPU_HW_TRACE(sys_creat);
    75         return fd;
     34    return sys_open( pathname , flags , mode );
    7635}
  • trunk/kernel/syscalls/sys_exec.c

    r14 r23  
    11/*
    2  * sys_exec.c - Kernel function implementing the "exec" syscall
     2 * sys_exec.c - Kernel function implementing the "exec" system call.
    33 *
    4  * Authors    Mohamed Lamine Karaoui (2015)
    5  *            Alain Greiner          (2016)
     4 * Authors   Alain Greiner (2016,2017)
    65 *
    76 * Copyright (c) UPMC Sorbonne Universites
     
    2524#include <kernel_config.h>
    2625#include <hal_types.h>
     26#include <hal_uspace.h>
    2727#include <errno.h>
    2828#include <printk.h>
     
    5151
    5252    // get string length
    53         hal_strlen_from_uspace( pathname , &length );
    54         if( length > 255 )
    55     {
    56         printk(ERROR, "%s: elf file pathname larger than 255 bytes\n", __FUNCTION__ );
    57         return EINVAL;
    58     }
     53        length = hal_strlen_from_uspace( pathname );
     54
     55        if( length >= CONFIG_VFS_MAX_PATH_LENGTH ) return EINVAL;
    5956
    6057    // copy string to exec_info
     
    7572// The max number of strings is 1024 (for both args and envs). The numbers of pages
    7673// to store the (args) and (envs) strings are configuration parameters.
    77 ////////////////////////////////////////////////i//////////////////////////////////////
     74///////////////////////////////////////////////////////////////////////////////////////
    7875// @ exec_info : pointer on the exec_info structure.
    7976// @ is_args   : true if called for (args) / false if called for (envs).
     
    8885    uint32_t     found_null;  // NULL pointer found in array of pointers
    8986    uint32_t     length;      // string length
    90     uint32_t     strings;     // actual number of strings
    9187    kmem_req_t   req;         // kmem request
    9288    page_t     * page;        // page descriptor
    9389    uint32_t     order;       // ln2( number of pages to store strings )
    94     char      ** k_pointers;  // base of kernel buffer containing array of pointers
    95     char       * buf_ptr;     // pointer on first empty slot in kernel strings buffer
    96     char       * buf_base;    // base address of the kernel strings buffer
     90    char      ** k_pointers;  // base of kernel array of pointers
     91    char       * k_buf_ptr;   // pointer on first empty slot in kernel strings buffer
     92    char       * k_buf_base;  // base address of the kernel strings buffer
    9793
    9894    // compute ln2( number of pages for kernel strings buffer )
    99     if( is_args ) order = CONFIG_PROCESS_ARGS_ORDER;
    100     else          order = CONFIG_PROCESS_ENVS_ORDER;
     95    if( is_args ) order = bits_log2( CONFIG_VMM_ARGS_SIZE );
     96    else          order = bits_log2( CONFIG_VMM_ENVS_SIZE );
    10197
    10298        req.type   = KMEM_PAGE;
     
    106102    req.type   = 0;
    107103    page       = kmem_alloc( &req );
    108     if( page == NULL )
    109     {
    110         printk("ERROR in %s : cannot allocate memory for pointers\n", __FUNCTION__ );
    111         return ENOMEM;
    112     }
     104
     105    if( page == NULL ) return ENOMEM;
     106
    113107    k_pointers = ppm_page2base( page );
    114108   
     
    116110    req.type   = order;
    117111    page       = kmem_alloc( &req );
    118     if( page == NULL )
    119     {
    120         printk("ERROR in %s : cannot allocate memory for strings\n", __FUNCTION__ );
    121         return ENOMEM;
    122     }
    123     buf_base    = ppm_page2base( page );
     112
     113    if( page == NULL ) return ENOMEM;
     114
     115    k_buf_base = ppm_page2base( page );
    124116   
    125117    // copy the array of pointers to kernel buffer
     
    128120                          CONFIG_PPM_PAGE_SIZE );
    129121
    130     // scan local copy of array of pointers to copy the strings
     122    // scan kernel array of pointers to copy the strings
    131123    found_null = 0;
    132     buf_ptr    = buf_base;
     124    k_buf_ptr  = k_buf_base;
    133125    for( index = 0 ; index < 1024 ; index++ )
    134126    {
     
    140132
    141133        // compute string length
    142             hal_strlen_from_uspace( k_pointers[index] , &length );
     134            length = hal_strlen_from_uspace( k_pointers[index] );
    143135 
    144136        // copy the user string to kernel buffer
    145         hal_copy_from_uspace( k_strings,
    146                               k_pointers[index];
     137        hal_copy_from_uspace( k_buf_ptr,
     138                              k_pointers[index],
    147139                              length );
    148140
    149141        // update k_pointer[index] entry
    150         k_pointers[index] = buf_ptr;
     142        k_pointers[index] = k_buf_ptr;
    151143
    152144        // increment pointer on kernel strings buffer
    153         buf_ptr += (length + 1);
     145        k_buf_ptr += (length + 1);
    154146    }
    155147
     
    158150    {
    159151        exec_info->args_pointers  =  k_pointers;
    160         exec_info->args_buf_base  =  buf_base;
     152        exec_info->args_buf_base  =  k_buf_base;
    161153        exec_info->args_nr        =  index;
    162154    }
     
    164156    {
    165157        exec_info->envs_pointers  =  k_pointers;
    166         exec_info->envs_buf_base  =  buf_base;
    167         exec_info->envs_buf_free  =  buf_ptr;
     158        exec_info->envs_buf_base  =  k_buf_base;
     159        exec_info->envs_buf_free  =  k_buf_ptr;
    168160        exec_info->envs_nr        =  index;
    169161    }
    170162    else
    171163    {
    172         printk("ERROR in %s : number of strings larger than 1024\n", __FUNCTION__ );
    173164        return EINVAL;
    174165    }
     
    177168} // end process_exec_get_strings()
    178169
    179 /////////////////////////////////////////////////////////////////////////////////////////
    180 // This function is executed in a "client" cluster by a process whose PID can belong
    181 // to another "server" cluster (defined by the MSB bits of the calling process PID).
    182 // A new process descriptor, and the associated main thread descriptor must be created
    183 // in the "server" cluster, using directly the process_make_exec() function if local,
    184 // or the rpc_process_exec_client() function if server is remote.
    185170/////////////////////////////////////////////////////////////////////////////////////////
    186171// Implementation note:
     
    189174// It calls the static process_exec_get_path() and process_exec_get_strings() functions
    190175// to copy the .elf pathname, the main() arguments and the environment variables from
    191 // user buffers to the exec_info_t, and calls the static process_make_exec() function.
     176// user buffers to the exec_info_t structure, and call the process_make_exec() function.
    192177/////////////////////////////////////////////////////////////////////////////////////////
    193178int sys_exec( char  * filename,     // .elf file pathname
    194               char ** argv,         // process arguments
    195               char ** envp )        // environment variables
     179              char ** args,         // process arguments
     180              char ** envs )        // environment variables
    196181{
    197182    exec_info_t  exec_info;         // structure to pass to process_make_exec()
    198     thread_t   * thread;            // pointer on thread created in server cluster
    199         error_t      error   = 0;
    200         process_t  * process = CURRENT_PROCESS;
    201 
    202     // check arguments
    203         if((filename == NULL) || (argv == NULL) || (envp == NULL))
    204     {
    205         printk("\n[ERROR] in %s : missing arguments / file = %x / argv = %x / envp = %x\n",
    206                __FUNCTION__ , filename , argv , envp );
    207         return EINVAL;
     183        error_t      error;
     184    paddr_t      paddr;
     185
     186    thread_t   * this    = CURRENT_THREAD;
     187        process_t  * process = this->process;
     188
     189    // check argument fileme
     190    error = vmm_v2p_translate( false , filename , &paddr );
     191
     192        if( error )
     193    {
     194        printk("\n[ERROR] in %s : filename unmapped\n", __FUNCTION__ );
     195        this->errno = EINVAL;
     196        return -1;
     197    }
     198
     199    // check argument fileme
     200    error = vmm_v2p_translate( false , args , &paddr );
     201
     202        if( error )
     203    {
     204        printk("\n[ERROR] in %s : args unmapped\n", __FUNCTION__ );
     205        this->errno = EINVAL;
     206        return -1;
     207    }
     208
     209    // check argument fileme
     210    error = vmm_v2p_translate( false , envs , &paddr );
     211
     212        if( error )
     213    {
     214        printk("\n[ERROR] in %s : envs unmapped\n", __FUNCTION__ );
     215        this->errno = EINVAL;
     216        return -1;
    208217    }
    209218
     
    218227                 cxy_client, cxy_server, hal_time_stamp());
    219228
    220     // Change process's state to prevent any concurent access TODO ??? [AG]
    221 
    222229    // initialize exec_info structure
    223     exec_info->pid      = process->pid;
    224     exec_info->ppid     = process->ppid;
    225     exec_info->fd_array = &process->fd_array;
    226     exec_info->vfs_root = &process->vfs_root;
    227     exec_info->vfs_cwd  = &process->vfs_cwd;
    228     exec_info->vfs_bin  = &process->vfs_bin;
     230    exec_info.pid         = process->pid;
     231    exec_info.ppid        = process->ppid;
     232    exec_info.fd_array_xp = XPTR( local_cxy , &process->fd_array );
     233    exec_info.vfs_root_xp = process->vfs_root_xp;
     234    exec_info.vfs_cwd_xp  = process->vfs_cwd_xp;
     235    exec_info.vfs_bin_xp  = process->vfs_bin_xp;
    229236
    230237        // check pathname and store it in exec_info structure
    231238        error = process_exec_get_path( &exec_info , filename );
    232         if ( error ) return EINVAL;
    233 
    234         // check and store argv in exec_info structure
    235         error = process_exec_get_strings( &exec_info , true , argv );
    236         if( error )  return EINVAL;
     239
     240        if ( error )
     241    {
     242        printk("\n[ERROR] in %s : elf pathname too long\n", __FUNCTION__ );
     243        this->errno = error;
     244        return -1;
     245    }
     246
     247        // check and store args in exec_info structure
     248        error = process_exec_get_strings( &exec_info , true , args );
     249
     250        if( error ) 
     251    {
     252        printk("\n[ERROR] in %s : cannot access args\n", __FUNCTION__ );
     253        this->errno = error;
     254        return -1;
     255    }
    237256       
    238         // check and store envp in exec_info structure
    239         error = process_exec_get_strings( &exec_info , false , envp );
    240         if( error )  return EINVAL;
     257        // check and store envs in exec_info structure
     258        error = process_exec_get_strings( &exec_info , false , envs );
     259
     260        if( error )
     261    {
     262        printk("\n[ERROR] in %s : cannot access envs\n", __FUNCTION__ );
     263        this->errno = error;
     264        return -1;
     265    }
    241266       
    242     if( is_local )  ////////////// local exec //////////////////////////
    243     {
    244         exec_dmsg("\n[INFO] %s starts local exec for process %x at cycle %d\n",
    245                   __FUNCTION__, process->pid, hal_time_stamp());
    246 
    247         // call directly the local process_make_exec() function
    248         error = process_make_exec( &exec_info , &thread );
    249         if error
    250         {
    251             printk("\n[ERROR] in %s : failed in local exec for process %x\n",
    252                    __FUNCTION__ , process->pid );
    253             return EINVAL;
    254         }
    255 
    256         exec_dmsg("\n[INFO] %s completes local exec for process %x at cycle %d\n",
    257                   __FUNCTION__, process->pid , hal_time_stamp() );
    258     }
    259     else             ///////////// remote exec /////////////////////////
    260     {
    261         exec_dmsg("\n[INFO] %s starts remote exec for process %x at cycle %d\n",
    262                   __FUNCTION__, process->pid, hal_time_stamp() );
    263 
    264         // call the rpc_process_exec_client() function   
    265         rpc_process_exec_client( cxy_server , &exec_info , &thread , &error );
    266 
    267         if( error )
    268         {
    269             printk("\n[ERROR] in %s : failed in remote exec for process %x\n",
    270                    __FUNCTION__ , process->pid );
    271             return EINVAL;
    272         }
    273 
    274         exec_dmsg("\n[INFO] %s completes remote exec for process %x at cycle %d\n",
    275                   __FUNCTION__, process->pid , hal_time_stamp() );
    276     }
    277 
    278     // If no error, delete the current thread an process descriptors.
     267    exec_dmsg("\n[INFO] %s starts exec for process %x at cycle %d\n",
     268              __FUNCTION__, process->pid, hal_time_stamp() );
     269
     270    if( is_local )  error = process_make_exec( &exec_info );
     271    else            rpc_process_exec_client( cxy_server , &exec_info , &error );
     272
     273    if( error )
     274    {
     275        printk("\n[ERROR] in %s : cannot create new process %x\n",
     276               __FUNCTION__ , process->pid );
     277        this->errno = error;
     278        return -1;
     279    }
     280
     281    exec_dmsg("\n[INFO] %s completes exec for process %x at cycle %d\n",
     282              __FUNCTION__, process->pid , hal_time_stamp() );
     283
     284    // delete the calling thread an process
    279285    thread_kill( CURRENT_THREAD );
    280     process_kill( CURRENT_PROCESS );
     286    process_kill( CURRENT_THREAD->process );
    281287
    282288    return 0;
     289
    283290} // end sys_exec()
    284291
  • trunk/kernel/syscalls/sys_fork.c

    r1 r23  
    11/*
    2  * sys_fork.c - fork the current process
     2 * sys_fork.c - Fork the current process.
    33 *
    4  * Authors  Ghassan Almaless (2008,2009,2010,2011,2012)
    5  *          Mohamed Lamine Karaoui (2015)
    6  *          Alain Greiner (2016)
     4 * Authors  Alain Greiner  (2016,2017)
    75 *
    86 * Copyright (c) UPMC Sorbonne Universites
     
    2422 */
    2523
     24#include <kernel_config.h>
     25#include <hal_types.h>
     26#include <hal_atomic.h>
    2627#include <errno.h>
    27 #include <config.h>
    28 #include <cpu.h>
     28#include <printk.h>
     29#include <core.h>
    2930#include <cluster.h>
    30 #include <event.h>
    3131#include <list.h>
    3232#include <thread.h>
     
    3636#include <process.h>
    3737
    38 #if CONFIG_FORK_DEBUG
    39 #define fork_debug(...) printk(__VA_ARGS__)
    40 #else
    41 #define fork_debug(...) /**/
    42 #endif
    43 
    44 /***********************************************************************************************
    45  * This kernel function implement the "fork" system call.
    46  * The calling process descriptor (parent process), and the associated thread descriptor are
    47  * replicated in the same cluster as the calling thread, but the new process (child process)
    48  * is registered in another target cluster, that will become the process owner.
    49  * The child process and the associated main thread will be migrated to the target cluster
    50  * later, when the child process makes an "exec" or any other system call.
    51  * The target cluster depends on the "fork_user" flag and "fork_cxy" variable that can be
    52  * stored in the calling thread descriptor by the specific fork_place() system call.
    53  * If not, the sys_fork() function makes a query to the DQDT to select the target cluster.
    54  * @ returns child process PID if success / returns -1 if failure
    55  **********************************************************************************************/
    56 int sys_fork();
     38//////////////
     39int sys_fork()
    5740{
    5841        process_t          * parent_process;  // pointer on parent process descriptor
     
    6346        thread_t           * child_thread;    // pointer on child main thread descriptor
    6447    trdid_t              child_trdid;     // child main thread identifier
    65     core_t             * child_core;      // pointer on core for child main thread
    6648    lid_t                child_core_lid;  // core local index for the child main thread
    6749    cxy_t                target_cxy;      // final target cluster for forked child process
    6850        error_t              error;
    6951
    70     cluster_t          * parent_cluster = LOCAL_CLUSTER;
    71 
    7252    // get pointers on parent process and thread
    7353        parent_thread  = CURRENT_THREAD;
    7454        parent_process = parent_thread->process;
     55    parent_pid     = parent_process->pid;
    7556
    7657    // check parent process children number
    77         if( hal_atomic_add( &parent_process->childs_nr , 1 ) >= CONFIG_PROCESS_CHILDS_MAX_NR )
    78         {
    79             printk("ERROR in %s : too much children processes\n", __FUNCTION__);
    80             hal_atomic_add ( &parent_process->childs_nr , -1 );
    81         return EAGAIN;
    82         }
    83 
    84         fork_debug("INFO : %s enters for process %d at cycle [%d]\n",
     58        if( hal_atomic_add( &parent_process->children_nr , 1 ) >= CONFIG_PROCESS_MAX_CHILDREN )
     59        {
     60            printk("\n[ERROR] in %s : too much children processes\n", __FUNCTION__);
     61            hal_atomic_add ( &parent_process->children_nr , -1 );
     62        return EAGAIN;
     63        }
     64
     65        fork_dmsg("\n[INFO] %s : enters for process %d at cycle [%d]\n",
    8566                  __FUNCTION__, parent_process->pid, hal_time_stamp());
    8667
     
    9071        {
    9172                hal_fpu_context_save( parent_thread );
    92                 fork_debug("INFO : %s save FPU\n", __FUNCTION__);
     73                fork_dmsg("\n[INFO] %s : save FPU\n", __FUNCTION__);
    9374        }
    9475
    9576    // Select target cluster for future migration of child process and main thread.
    96     // The placement can be specified by user. If placement is not user-defined,
    97     // the placement is defined by the DQDT.
    98     // The two first processes ("init" and "sh") on boot cluster will not migrate.
    99         if( parent_threads->fork_user )
     77    // If placement is not user-defined, the placement is defined by the DQDT.
     78    // The two first processes ("init" and "sh") on boot cluster do not migrate.
     79
     80        if( parent_thread->fork_user )
    10081        {
    10182        // user defined placement
    102         target_cxy = parent->thread.fork_cxy;
    103         parent->thread.fork_cxy = false;
    104         }
    105     else if( (LPID_FROM_PID(parent_process->pid) < 2 ) 
    106              && ( parent_cluster->cxy == parent_cluster->boot_cxy ) )
     83        target_cxy = parent_thread->fork_cxy;
     84        parent_thread->fork_user = false;
     85        }
     86    else if( (LPID_FROM_PID(parent_process->pid) < 2)  && (local_cxy == 0) )
    10787    {
    10888        // 2 first process stay in boot cluster
    109         target_cxy = parent_cluster->cxy;
     89        target_cxy = local_cxy;
    11090    }
    11191        else
     
    11595        }
    11696
    117         fork_debug("INFO : %s select target_cluster = %x\n",
     97        fork_dmsg("INFO : %s select target_cluster = %x\n",
    11898              __FUNCTION__ , target_cxy );
    11999
    120100    // allocates memory in local cluster for the child process descriptor
    121101        child_process = process_alloc();
     102
    122103        if( child_process == NULL )
    123104        {
    124             printk("ERROR in %s : cannot allocate memory for child process\n", __FUNCTION__ );
    125             hal_atomic_add ( &parent_process->childs_nr , -1 );
    126         return EAGAIN;
    127         }
    128 
    129     // get a new PID for child process
    130     // it requires an RPC if target cluster is remote
    131     xptr_t xp = XPTR( target_cxy , child_process );
    132     if( target_cxy == parent_cluster->cxy )   // local cluster
    133     {
    134         error = process_pid_alloc( xp , &child_pid );
    135     }
    136     else                            // remote cluster
    137     {
    138         rpc_process_pid_alloc_server( target_cxy , xp , &error , &child_pid );
    139     }
     105            printk("\n[ERROR] in %s : cannot allocate child process\n", __FUNCTION__ );
     106            hal_atomic_add ( &parent_process->children_nr , -1 );
     107        return EAGAIN;
     108        }
     109
     110    // get a new PID for child process,
     111    if( target_cxy == local_cxy )                // target cluster is local
     112    {
     113        error = cluster_pid_alloc( XPTR( target_cxy , child_process ) , &child_pid );
     114    }
     115    else                                         // target cluster is remote
     116    {
     117        rpc_process_pid_alloc_client( target_cxy , child_process , &error , &child_pid );
     118    }
     119
    140120    if( error )
    141121    {
    142             printk("ERROR in %s : cannot allocate PID\n", __FUNCTION__ );
    143             atomic_add ( &parent_process->childs_nr , -1 );
     122            printk("\n[ERROR] in %s : cannot allocate PID\n", __FUNCTION__ );
     123            hal_atomic_add ( &parent_process->children_nr , -1 );
    144124        process_destroy( child_process );
    145125        return EAGAIN;
     
    147127
    148128    // initialize and register the child process descriptor
    149     error = process_reference_init( child_process , child_pid , parent_pid );
    150     if( error )
    151     {
    152             printk("ERROR in %s : cannot initialise child process\n", __FUNCTION__ );
    153             atomic_add ( &parent_process->childs_nr , -1 );
    154         process_destroy( child_process );
    155         return EAGAIN;
    156     }
    157 
    158         fork_debug("INFO : %s created child process : pid = %x / ppid = %x\n",
     129    process_reference_init( child_process , child_pid , parent_pid );
     130
     131        fork_dmsg("\n[INFO] : %s created child process : pid = %x / ppid = %x\n",
    159132              __FUNCTION__, child_pid , parent_pid );
    160 
    161     // set IS_REFERENCE flag in child process descriptor
    162     child_process->flags = PDF_IS_REFERENCE;
    163133
    164134    // initialises child process standard files structures
    165135    // ( root / cwd / bin ) from parent process descriptor
    166         spinlock_lock( &parent_process->cwd_lock );
    167 
    168         vfs_file_count_up( &parent_process->vfs_root );
    169         child_process->vfs_root = parent_process->vfs_root;
    170 
    171         vfs_file_count_up( &parent_process->vfs_cwd );
    172         child_process->vfs_cwd  = parent_process->vfs_cwd;
    173 
    174         vfs_file_count_up( &parent_process->vfs_bin );
    175     child_process->vfs_bin = parent_process->vfs_bin;
    176 
    177         spinlock_unlock( &parent_process->cwd_lock );
     136
     137        vfs_file_count_up( parent_process->vfs_root_xp );
     138        child_process->vfs_root_xp = parent_process->vfs_root_xp;
     139
     140        vfs_file_count_up( parent_process->vfs_cwd_xp );
     141        child_process->vfs_cwd_xp  = parent_process->vfs_cwd_xp;
     142
     143        vfs_file_count_up( parent_process->vfs_bin_xp );
     144    child_process->vfs_bin_xp = parent_process->vfs_bin_xp;
     145
     146    // copy the parent process fd_array to the child process fd_array
     147        process_fd_remote_copy( XPTR( local_cxy , &child_process->fd_array ),
     148                            XPTR( local_cxy , &parent_process->fd_array ) );
     149
     150        fork_dmsg("\n[INFO] %s : duplicated child process from parent process\n",
     151                  __FUNCTION__ );
     152
     153    // replicates virtual memory manager
     154        error = vmm_copy( child_process , parent_process );
     155
     156        if( error )
     157    {
     158            printk("\n[ERROR] in %s : cannot duplicate VMM\n", __FUNCTION__ );
     159            hal_atomic_add ( &parent_process->children_nr , -1 );
     160        process_destroy( child_process );
     161        return ENOMEM;
     162    }
    178163 
    179     // copy the parent process fd_array to the child process fd_array
    180         process_fd_fork( child_process , parent_process );
    181 
    182     // initialise child process signal manager TODO ???
    183         signal_manager_init( child_process );
    184  
    185         fork_debug("INFO : %s duplicated child process from parent process\n",
    186                   __FUNCTION__ );
    187 
    188     // replicates virtual memory manager
    189         error = vmm_dup( &child_process->vmm , &parent_process->vmm );
     164        fork_dmsg("\n[INFO] %s : parent vmm duplicated in child process\n", __FUNCTION__ );
     165
     166    // create child main thread descriptor in local cluster
     167    error = thread_user_fork( parent_process , &child_thread );
     168
    190169        if( error )
    191170    {
    192             printk("ERROR in %s : cannot duplicate VMM\n", __FUNCTION__ );
    193             atomic_add ( &parent_process->childs_nr , -1 );
    194         process_destroy( child_process );
    195         return EAGAIN;
    196     }
    197  
    198         fork_debug("INFO : %s: parent vmm duplicated in child process\n", __FUNCTION__ );
    199 
    200     // create child main thread descriptor in local cluster TODO stack ???
    201     error = thread_user_fork( &child_thread , process , parent_thread );
    202         if( error )
    203     {
    204             printk("ERROR in %s : cannot duplicate thread\n", __FUNCTION__ );
    205             atomic_add ( &parent_process->childs_nr , -1 );
    206         process_destroy( child_process );
    207         return EAGAIN;
     171            printk("\n[ERROR] in %s : cannot duplicate thread\n", __FUNCTION__ );
     172            hal_atomic_add( &parent_process->children_nr , -1 );
     173        process_destroy( child_process );
     174        return ENOMEM;
    208175    }
    209176
    210177    // register child thread in child process, and get a TRDID
    211     spinlock_lock( &child->process->th_lock );
    212     error = process_register_thread( child->process, child->thread , &child_trdid );
    213     spinlock_unlock( &process->th_lock );
     178    spinlock_lock( &child_process->th_lock );
     179    error = process_register_thread( child_process, child_thread , &child_trdid );
     180    spinlock_unlock( &child_process->th_lock );
    214181
    215182    if( error )
    216183    {
    217         printk("ERROR in %s : cannot register thread\n", __FUNCTION__ );
    218             atomic_add ( &parent_process->childs_nr , -1 );
     184        printk("\n[ERROR] in %s : cannot register thread\n", __FUNCTION__ );
     185            hal_atomic_add ( &parent_process->children_nr , -1 );
    219186        thread_destroy( child_thread );
    220187        process_destroy( child_process );
     
    226193
    227194        // Update child thread descriptor
    228         child_thread->core    = process->core_tbl[child_core_lid];
     195        child_thread->core    = &LOCAL_CLUSTER->core_tbl[child_core_lid];
    229196        child_thread->process = child_process;
    230     child_thread->trdid   = chid_trdid;
    231 
    232         fork_debug("INFO : %s initialised child main thread\n", __FUNCTION__ );
     197    child_thread->trdid   = child_trdid;
     198
     199        fork_dmsg("\n[INFO] %s : initialised child main thread\n", __FUNCTION__ );
    233200
    234201    // register local child thread into local child process th_tbl[]
    235202    // we don't use the th_lock because there is no concurrent access
    236     ltid_t ltid = LTID_FROM_TRDID( trdid );
    237         child_process->th_tbl[ltid] = XPTR( local_cxy , child_thread );
    238         child_process->threads_nr = 1;
     203    ltid_t ltid = LTID_FROM_TRDID( child_trdid );
     204        child_process->th_tbl[ltid] = child_thread;
     205        child_process->th_nr = 1;
    239206
    240207    // register child thread in scheduler
    241         sched_register( child_thread->core , child_thread );
     208        sched_register_thread( child_thread->core , child_thread );
    242209 
    243         fork_debug("INFO : %s registered main thread in scheduler\n", __FUNCTION__);
     210        fork_dmsg("\n[INFO] %s : registered main thread in scheduler\n", __FUNCTION__);
    244211
    245212        // update DQDT for the child thread
    246     dqdt_update_threads_number( 1 );
    247 
    248         fork_debug("INFO :%s completed / parent pid = %x / child pid = %x / at cycle [%d]\n",
     213    dqdt_local_update_threads( 1 );
     214
     215        fork_dmsg("\n[INFO] %s : completed / parent pid = %x / child pid = %x / at cycle [%d]\n",
    249216                  __FUNCTION__, parent_process->pid, child_process->pid, hal_time_stamp() );
    250217
  • trunk/kernel/syscalls/sys_getcwd.c

    r1 r23  
    11/*
    2  * kern/sys_getcwd.c - get process current work directory
     2 * sys_getcwd.c - get process current work directory
    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 */
    2223
    23 #include <libk.h>
     24#include <kernel_config.h>
     25#include <hal_types.h>
     26#include <hal_uspace.h>
     27#include <hal_special.h>
     28#include <errno.h>
    2429#include <vfs.h>
    25 #include <sys-vfs.h>
    26 #include <task.h>
    27 #include <kmem.h>
    28 #include <ppm.h>
     30#include <vmm.h>
     31#include <process.h>
    2932#include <thread.h>
     33#include <printk.h>
    3034
    31 /* TODO: user page need to be locked as long as its region */
     35/* TODO: user page(s) need to be locked  [AG] */
    3236
    33 int sys_getcwd (char *buff, size_t size)
     37////////////////////////////////
     38int sys_getcwd ( char     * buf,
     39                 uint32_t   nbytes )
    3440{
    35         register struct thread_s *this;
    36         register struct task_s *task;
    37         register error_t err;
    38         struct ku_obj ku_buff;
     41        error_t    error;
     42    paddr_t    paddr;
     43    char       kbuf[CONFIG_VFS_MAX_PATH_LENGTH];
    3944 
    40         this      = current_thread;
    41         task      = current_task;
     45        thread_t  * this    = CURRENT_THREAD;
     46    process_t * process = this->process;
    4247
    43         if((size < VFS_MAX_NAME_LENGTH) || (!buff))
     48    // check buffer size
     49        if( nbytes < CONFIG_VFS_MAX_PATH_LENGTH )
    4450        {
    45                 err = ERANGE;
    46                 goto SYS_GETCWD_ERROR;
     51        printk("\n[ERROR] in %s : buffer too small\n", __FUNCTION__ );
     52                this->errno = ERANGE;
     53        return -1;
    4754        }
    4855
    49         if(vmm_check_address("usr cwd buffer", task, buff, size))
     56    // check buffer in user space
     57    error = vmm_v2p_translate( false , buf , &paddr );
     58
     59        if( error )
    5060        {
    51                 err = EFAULT;
    52                 goto SYS_GETCWD_ERROR;
     61        printk("\n[ERROR] in %s : user buffer unmapped\n", __FUNCTION__ );
     62                this->errno = EFAULT;
     63        return -1;
    5364        }
    5465
    55         KU_SZ_BUFF(ku_buff, buff, size);
     66    // get reference process cluster and local pointer
     67    xptr_t      ref_xp  = process->ref_xp;
     68    cxy_t       ref_cxy = GET_CXY( ref_xp );
     69    process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
    5670
    57         rwlock_rdlock(&task->cwd_lock);
     71    // get CWD lock in read mode
     72        remote_rwlock_rd_lock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
    5873
    59         err = vfs_get_path(&task->vfs_cwd, &ku_buff);
     74    // call relevant VFS function
     75        error = vfs_get_path( XPTR( ref_cxy , &ref_ptr->vfs_cwd_xp ) ,
     76                          kbuf , CONFIG_VFS_MAX_PATH_LENGTH );
    6077
    61         rwlock_unlock(&task->cwd_lock);
     78    // release CWD lock
     79        remote_rwlock_rd_unlock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
    6280
     81    // copy kernel buffer to user space
     82    hal_copy_to_uspace( buf , kbuf , CONFIG_VFS_MAX_PATH_LENGTH );
    6383
    64 SYS_GETCWD_ERROR:
    65         this->info.errno = err;
    66         return (int)buff;
    67 }
     84    hal_wbflush();
     85
     86        return 0;
     87
     88}  // end sys_getcwd()
  • trunk/kernel/syscalls/sys_getpid.c

    r1 r23  
    22 * kern/sys_getpid.c - get process id
    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 */
    2223
    23 #include <task.h>
    2424#include <thread.h>
    2525
     26////////////////
    2627int sys_getpid()
    2728{
    28         return current_task->pid;
     29        return CURRENT_THREAD->process->pid;
    2930}
  • trunk/kernel/syscalls/sys_gettimeofday.c

    r1 r23  
    11/*
    2  * sys_gettimeofday: get current time
    3  *
    4  * Copyright (c) 2015 UPMC Sorbonne Universites
     2 * sys_gettimeofday.c - Get current time
    53 *
    6  * This file is part of ALMOS-kernel.
     4 * Author    Alain Greiner (2016,2017)
    75 *
    8  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     6 * Copyright (c) UPMC Sorbonne Universites
     7 *
     8 * This file is part of ALMOS-MKH.
     9 *
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    911 * under the terms of the GNU General Public License as published by
    1012 * the Free Software Foundation; version 2.0 of the License.
    1113 *
    12  * 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
    1315 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1416 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1618 *
    1719 * You should have received a copy of the GNU General Public License
    18  * 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,
    1921 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2022 */
    2123
    22 #include <cpu.h>
     24#include <hal_types.h>
     25#include <hal_uspace.h>
    2326#include <thread.h>
     27#include <printk.h>
     28#include <errno.h>
     29#include <process.h>
     30#include <vmm.h>
     31#include <core.h>
    2432#include <time.h>
    2533
    26 int sys_gettimeofday(struct timeval *tv, struct timezone *tz)
     34///////////////////////////////////////////
     35int sys_gettimeofday( struct timeval  * tv,
     36                      struct timezone * tz )
    2737{
    28         error_t err;
    29         uint_t tm_ms, tm_us;
    30         struct timeval time;
     38        error_t        error;
     39    paddr_t        paddr;
    3140
    32         if((tv == NULL) || NOT_IN_USPACE(tv) || NOT_IN_USPACE(tv+sizeof(*tv)))
    33         {
    34                 err = EINVAL;
    35                 goto fail_inval;
    36         }
     41        uint32_t       tm_s;
     42    uint32_t       tm_us;
    3743
    38         if(tz)
    39                 return ENOTSUPPORTED;
     44        struct timeval k_tv;
    4045
    41         cpu_get_time(current_cpu, &tm_ms, &tm_us);
    42         time.tv_sec = tm_ms/1000;
    43         time.tv_usec = ((tm_ms%1000)*1000)+tm_us;
     46        thread_t  *    this    = CURRENT_THREAD;
     47        process_t *    process = this->process;
    4448
    45         //printk(INFO, "%s: [%d] (%u ms) sec %u, usec %u\n", __FUNCTION__,
    46         //current_cpu->gid, tm_ms, (uint32_t)time.tv_sec, (uint32_t)time.tv_usec);
     49    // check tz (non supported / must be null)
     50    if( tz )
     51    {
     52        printk("\n[ERROR] in %s for thread %x in process %x : tz argument must be NULL\n",
     53               __FUNCTION__ , this->trdid , process->pid );
     54        this->errno = EINVAL;
     55        return -1;
     56    }
     57 
     58    // check tv
     59    error = vmm_v2p_translate( false , tv , &paddr );
    4760
    48         err    = cpu_copy_to_uspace(tv, &time, sizeof(time));
     61    if( error )
     62    {
     63        printk("\n[ERROR] in %s for thread %x in process %x : tv argument unmapped\n",
     64        __FUNCTION__ , this->trdid , process->pid );
     65        this->errno = EINVAL;
     66        return -1;
     67    }
    4968
    50 fail_inval:
    51         current_thread->info.errno = err;
    52         return err;
    53 }
     69    // get time from calling core descriptor
     70    core_get_time( this->core , &tm_s , &tm_us );
     71        k_tv.tv_sec  = tm_s;
     72        k_tv.tv_usec = tm_us;
     73
     74    // copy values to user space
     75        hal_copy_to_uspace( tv , &k_tv , sizeof(struct timeval) );
     76
     77    hal_wbflush();
     78
     79        return 0;
     80
     81}  // end sys_timeofday()
  • trunk/kernel/syscalls/sys_lseek.c

    r1 r23  
    2121 */
    2222
    23 #include <types.h>
     23#include <kernel_config.h>
     24#include <hal_types.h>
     25#include <hal_uspace.h>
     26#include <errno.h>
    2427#include <vfs.h>
     28#include <vmm.h>
    2529#include <thread.h>
    26 #include <sys-vfs.h>
    27 #include <task.h>
     30#include <printk.h>
     31#include <process.h>
    2832
    29 int sys_lseek (uint_t fd, off_t offset, int whence)
     33////////////////////////////////
     34int sys_lseek (uint32_t file_id,
     35               uint32_t offset,
     36               uint32_t whence )
    3037{
    31         error_t err = 0;
    32         size_t new_offset;
    33         struct thread_s *this;
    34         struct task_s *task;
    35         struct vfs_file_s *file;
     38        error_t    error;
     39    xptr_t     file_xp;
     40    uint32_t   new_offset;
    3641
    37         file = NULL;
    38         this = current_thread;
    39         task = current_task;
     42        thread_t  * this    = CURRENT_THREAD;
     43        process_t * process = this->process;
     44
     45    // check file_id argument
     46        if( file_id >= CONFIG_PROCESS_FILE_MAX_NR )
     47        {
     48        printk("\n[ERROR] in %s : illegal file descriptor index = %d\n",
     49               __FUNCTION__ , file_id );
     50                this->errno = EBADFD;
     51                return -1;
     52        }
     53
     54    // get extended pointer on remote file descriptor
     55    file_xp = process_fd_get_xptr( process , file_id );
     56
     57    if( file_xp == XPTR_NULL )
     58    {
     59        printk("\n[ERROR] in %s : undefined file descriptor index = %d\n",
     60               __FUNCTION__ , file_id );
     61                this->errno = EBADFD;
     62                return -1;
     63    }
    4064
    4165        /* FIXME: file may be closed in parallel
    4266         * of seek/read/write/mmap ..etc
    4367         * so file may be NULL or invalid */
    44         if((fd >= CONFIG_TASK_FILE_MAX_NR) || (task_fd_lookup(task, fd, &file)))
     68
     69    // call relevant VFS function
     70        error = vfs_lseek( file_xp , offset , whence , &new_offset );
     71
     72        if( error )
    4573        {
    46                 this->info.errno = EBADFD;
    47                 return -1;
    48         }
    49 
    50         if((err = vfs_lseek(file, offset, whence, &new_offset)))
    51         {
    52                 this->info.errno = (err < 0) ? -err : err;
     74        printk("\n[ERROR] in %s : cannot seek file = %d\n",
     75               __FUNCTION__ , file_id );
     76                this->errno = error;
    5377                return -1;
    5478        }
  • trunk/kernel/syscalls/sys_mkdir.c

    r1 r23  
    11/*
    2  * kern/sys_mkdir.c - creates new directory
     2 * sys_mkdir.c - Create a new directory
    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 */
    2223
     24#include <hal_types.h>
     25#include <hal_uspace.h>
    2326#include <vfs.h>
    24 #include <sys-vfs.h>
    25 #include <task.h>
     27#include <vmm.h>
     28#include <errno.h>
     29#include <process.h>
    2630#include <thread.h>
     31#include <printk.h>
    2732
    28 int sys_mkdir (char *pathname, uint_t mode)
     33///////////////////////////////////
     34int sys_mkdir( char     * pathname,
     35               uint32_t   mode )
    2936{
    30         register error_t err = 0;
    31         struct task_s *task = current_task;
    32         struct ku_obj ku_path;
     37        error_t        error;
     38    paddr_t        paddr;
     39    uint32_t       length;
     40    char           kbuf[CONFIG_VFS_MAX_PATH_LENGTH];
    3341
    34         KU_BUFF(ku_path, pathname);
    35         rwlock_rdlock(&task->cwd_lock);
     42        thread_t     * this     = CURRENT_THREAD;
     43        process_t    * process  = this->process;
    3644
    37         if((err = vfs_mkdir(&task->vfs_cwd, &ku_path, mode)))
     45    // check pathname in user space
     46    error = vmm_v2p_translate( false , pathname , &paddr );
     47
     48        if( error )
    3849        {
    39                 current_thread->info.errno = (err < 0) ? -err : err;
    40                 rwlock_unlock(&task->cwd_lock);
     50        printk("\n[ERROR] in %s : user buffer unmapped  for thread %x in process %x\n",
     51               __FUNCTION__ , this->trdid , process->pid );
     52                this->errno = EINVAL;
     53                return -1;
     54        }       
     55     
     56    // check fd_array not full
     57        if( process_fd_array_full() )
     58        {
     59        printk("\n[ERROR] in %s : file descriptor array full for process %x\n",
     60               __FUNCTION__ , process->pid );
     61                this->errno = ENFILE;
     62        return -1;
     63        }
     64   
     65    // get pathname length
     66    length = hal_strlen_from_uspace( pathname );
     67
     68    if( length >= CONFIG_VFS_MAX_PATH_LENGTH )
     69    {
     70        printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ );
     71                this->errno = ENFILE;
     72        return -1;
     73    }
     74 
     75        // get pathname copy in kernel space
     76    hal_copy_from_uspace( kbuf, pathname, length );
     77
     78    // get cluster and local pointer on reference process
     79    xptr_t      ref_xp  = process->ref_xp;
     80    process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
     81    cxy_t       ref_cxy = GET_CXY( ref_xp );
     82
     83    // get extended pointer on cwd inode
     84    xptr_t cwd_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->vfs_cwd_xp ) );
     85   
     86    // get the cwd lock in read mode from reference process
     87        remote_rwlock_rd_lock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
     88
     89    // call the relevant VFS function
     90        error = vfs_mkdir( cwd_xp,
     91                       kbuf,
     92                       mode );
     93
     94    // release the cwd lock
     95        remote_rwlock_rd_unlock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
     96
     97    if( error )
     98        {
     99        printk("\n[ERROR] in %s : cannot create directory %s\n",
     100               __FUNCTION__ , kbuf );
     101                this->errno = error;
    41102                return -1;
    42103        }
    43104   
    44         rwlock_unlock(&task->cwd_lock);
    45105        return 0;
    46106}
  • trunk/kernel/syscalls/sys_mkfifo.c

    r1 r23  
    11/*
    2  * kern/sys_mkfifo.c - creates a FIFO named file
     2 * sys_mkfifo.c - creates a named FIFO file.
    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 */
    2223
    23 #include <kdmsg.h>
     24#include <hal_types.h>
     25#include <hal_uspace.h>
     26#include <printk.h>
    2427#include <vfs.h>
    25 #include <sys-vfs.h>
    26 #include <task.h>
     28#include <process.h>
    2729#include <thread.h>
    2830
    29 int sys_mkfifo (char *pathname, uint_t mode)
     31////////////////////////////////////
     32int sys_mkfifo ( char    * pathname,
     33                 uint32_t  mode )
    3034{
    31         register error_t err = 0;
    32         struct task_s *task = current_task;
    33         struct ku_obj ku_path;
     35    error_t        error;
     36    uint32_t       length;                           // pathname length (bytes)
     37    char           kbuf[CONFIG_VFS_MAX_PATH_LENGTH];
    3438
    35         current_thread->info.errno = ENOSYS;
    36         return -1;
     39    thread_t  * this    = CURRENT_THREAD;
     40        process_t * process = this->process;
    3741
    38         KU_BUFF(ku_path, pathname);
    39         rwlock_rdlock(&task->cwd_lock);
    40         if((err = vfs_mkfifo(&task->vfs_cwd, &ku_path, mode)))
     42        if( pathname == NULL )
    4143        {
    42                 printk(INFO, "INFO: sys_mkfifo: Thread %x, CPU %d, Error Code %d\n",
    43                        current_thread,
    44                        cpu_get_id(),
    45                        err);
     44        printk("\n[ERROR] in %s : pathname is NULL\n", __FUNCTION__ );
     45                this->errno = EINVAL;
     46                return -1;
     47        }       
    4648
    47                 rwlock_unlock(&task->cwd_lock);
     49    // check fd_array not full
     50        if( process_fd_array_full() )
     51        {
     52        printk("\n[ERROR] in %s : file descriptor array full for process %x\n",
     53               __FUNCTION__ , process->pid );
     54                this->errno = ENFILE;
     55        return -1;
     56        }
     57   
     58    // get pathname length
     59    length = hal_strlen_from_uspace( pathname );
     60
     61    if( length >= CONFIG_VFS_MAX_PATH_LENGTH )
     62    {
     63        printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ );
     64                this->errno = ENFILE;
     65        return -1;
     66    }
     67 
     68        // get pathname copy in kernel space
     69    hal_copy_from_uspace( kbuf, pathname, length );
     70
     71    // get cluster and local pointer on reference process
     72    xptr_t      ref_xp  = process->ref_xp;
     73    process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
     74    cxy_t       ref_cxy = GET_CXY( ref_xp );
     75
     76    // get extended pointer on cwd inode
     77    xptr_t cwd_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->vfs_cwd_xp ) );
     78   
     79    // get the cwd lock in read mode from reference process
     80        remote_rwlock_rd_lock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
     81
     82    // call the relevant VFS function
     83        error = vfs_mkfifo( cwd_xp,
     84                        kbuf,
     85                        mode );
     86
     87    // release the cwd lock
     88        remote_rwlock_rd_unlock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
     89
     90    if( error )
     91        {
     92        printk("\n[ERROR] in %s : cannot create named FIFO %s\n",
     93               __FUNCTION__ , kbuf );
     94                this->errno = error;
    4895                return -1;
    4996        }
    50         rwlock_unlock(&task->cwd_lock);
    5197   
    5298        return 0;
    53 }
     99
     100} // end sys_mkfifo()
  • trunk/kernel/syscalls/sys_mmap.c

    r1 r23  
    11/*
    2  * kern/sys_mmap.c - map files, memory or devices into process's
    3  *                   virtual address space
     2 * sys_mmap.c - map files, memory or devices into process virtual address space
    43 *
    5  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    6  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * Authors       Ghassan Almaless (2008,2009,2010,2011,2012)
     5 *               Alain Greiner (2016,2017)
    76 *
    8  * This file is part of ALMOS-kernel.
     7 * Copyright (c) UPMC Sorbonne Universites
    98 *
    10  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     9 * This file is part of ALMOS-MKH.
     10 *
     11 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1112 * under the terms of the GNU General Public License as published by
    1213 * the Free Software Foundation; version 2.0 of the License.
    1314 *
    14  * ALMOS-kernel is distributed in the hope that it will be useful, but
     15 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1516 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1617 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1819 *
    1920 * You should have received a copy of the GNU General Public License
    20  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     21 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2122 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2223 */
    2324
     25#include <hal_types.h>
    2426#include <errno.h>
    2527#include <thread.h>
     28#include <printk.h>
    2629#include <vfs.h>
    27 #include <sys-vfs.h>
    2830#include <process.h>
    2931#include <vmm.h>
    3032
    3133///////////////////////////////////
    32 int sys_mmap( mmap_attr_t * mattr )
     34int sys_mmap( mmap_attr_t * attr )
    3335{
     36    printk("\n[WARNING] function %s not implemented\n", __FUNCTION__ );
     37    return 0;
     38/*   
    3439        error_t err;
    3540        uint_t count;
     
    4651        file = NULL;
    4752
    48         if((err = cpu_copy_from_uspace(&attr, mattr, sizeof(mmap_attr_t))))
     53        if((err = cpu_copy_from_uspace(&attr, attr, sizeof(mmap_attr_t))))
    4954        {
    5055                printk(INFO, "%s: failed, copying from uspace @%x\n",
    5156                       __FUNCTION__,
    52                        mattr);
     57                       attr);
    5358
    5459                this->info.errno = EFAULT;
     
    8287        else
    8388        {     
    84                 /* FIXEME: possible concurent delete of file from another bugy thread closing it */
     89                // FIXME: possible concurent delete of file from another bugy thread closing it
    8590                if((attr.fd >= CONFIG_TASK_FILE_MAX_NR) || (process_fd_lookup(process, attr.fd, &file)))
    8691                {
     
    145150
    146151        return (int)VM_FAILED;
    147 }
     152*/
     153}  // end sys_mmap()
  • trunk/kernel/syscalls/sys_mutex.c

    r15 r23  
    11/*
    2  * kern/sys_rwlock.c - interface to access Read-Write locks service
     2 * sys_mutex.c - Access a POSIX mutex.
    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 */
    2223
    23 #include <types.h>
     24#include <hal_types.h>
     25#include <hal_special.h>
    2426#include <errno.h>
    2527#include <thread.h>
    26 #include <kmem.h>
    27 #include <task.h>
     28#include <printk.h>
    2829#include <vmm.h>
    29 #include <kmagics.h>
    30 #include <rwlock.h>
     30#include <syscalls.h>
     31#include <remote_mutex.h>
    3132
    3233
    33 static inline bool_t isBadLock(struct rwlock_s *rwlock)
    34 {
    35         return vmm_check_object(rwlock, struct rwlock_s, RWLOCK_ID);
    36 }
     34/////////////////////////////////
     35int sys_mutex( void     * vaddr,
     36               uint32_t   operation,
     37               uint32_t   attr )
     38{
     39        error_t    error;
     40    paddr_t    paddr;
    3741
    38 int sys_rwlock(struct rwlock_s **rwlock, uint_t operation)
    39 {
    40         kmem_req_t req;
    41         struct rwlock_s *irwlock;
    42         error_t err;
    43  
    44         err = vmm_check_address("usr rwlock ptr",
    45                                 current_task,
    46                                 rwlock,
    47                                 sizeof(struct rwlock_s*));
    48         if(err)
    49                 goto SYS_RWLOCK_END;
     42    thread_t * this = CURRENT_THREAD;
    5043
    51         if((err = cpu_copy_from_uspace(&irwlock, rwlock, sizeof(struct rwlock_s *))))
    52                 goto SYS_RWLOCK_END;
    53  
    54         switch(operation)
    55         {   
    56         case RWLOCK_INIT:   
    57                 req.type  = KMEM_RWLOCK;
    58                 req.size  = sizeof(*irwlock);
    59                 req.flags = AF_USER;
     44    // check vaddr in user vspace
     45        error = vmm_v2p_translate( false , vaddr , &paddr );
     46        if( error )
     47    {
     48        printk("\n[ERROR] in %s : illegal virtual address = %x\n",
     49               __FUNCTION__ , (intptr_t)vaddr );
     50        this->errno = error;
     51        return -1;
     52    }
    6053
    61                 if((irwlock = kmem_alloc(&req)) == NULL)
    62                 {
    63                         err = ENOMEM;
    64                         break;
     54    // execute requested operation
     55        switch( operation )
     56        {   
     57        ////////////////
     58            case MUTEX_INIT:
     59        {
     60            if( attr != 0 )
     61            {
     62                printk("\n[ERROR] in %s : mutex attributes non supported yet\n",
     63                       __FUNCTION__ );
     64                this->errno = error;
     65                return -1;
     66            }
     67   
     68            error = remote_mutex_create( (intptr_t)vaddr );
     69
     70            if( error )
     71            {
     72                printk("\n[ERROR] in %s : cannot create mutex\n",
     73                       __FUNCTION__ );
     74                this->errno = error;
     75                return -1;
     76            }
     77                    break;
    6578                }
    66    
    67                 if((err = rwlock_init(irwlock)))
    68                         break;
    69    
    70                 if((err = cpu_copy_to_uspace(rwlock, &irwlock, sizeof(struct rwlock_s *))))
    71                 {
    72                         req.ptr = irwlock;
    73                         kmem_free(&req);
    74                 }
    75                 break;
     79        ///////////////////
     80            case MUTEX_DESTROY:
     81        {
     82            xptr_t mutex_xp = remote_mutex_from_ident( (intptr_t)vaddr );
    7683
    77         case RWLOCK_WRLOCK:
    78                 if(isBadLock(irwlock))
    79                         break;
    80    
    81                 return rwlock_wrlock(irwlock);
     84            if( mutex_xp == XPTR_NULL )     // user error
     85            {
     86                printk("\n[ERROR] in %s : mutex %x not registered\n",
     87                       __FUNCTION__ , (intptr_t)vaddr );
     88                this->errno = EINVAL;
     89                return -1;
     90            }
     91            else                          // success
     92            {
     93                remote_mutex_destroy( mutex_xp );
     94            }
     95            break;
     96        }
     97        ////////////////
     98            case MUTEX_LOCK:
     99        {
     100            xptr_t mutex_xp = remote_mutex_from_ident( (intptr_t)vaddr );
    82101
    83         case RWLOCK_RDLOCK:
    84                 if(isBadLock(irwlock))
    85                         break;
    86    
    87                 return rwlock_rdlock(irwlock);
     102            if( mutex_xp == XPTR_NULL )     // user error
     103            {
     104                printk("\n[ERROR] in %s : mutex %x not registered\n",
     105                       __FUNCTION__ , (intptr_t)vaddr );
     106                this->errno = EINVAL;
     107                return -1;
     108            }
     109            else                          // success
     110            {
     111                remote_mutex_lock( mutex_xp );
     112            }
     113            break;
     114        }
     115        //////////////////
     116            case MUTEX_UNLOCK:
     117        {
     118            xptr_t mutex_xp = remote_mutex_from_ident( (intptr_t)vaddr );
    88119
    89         case RWLOCK_TRYWRLOCK:
    90                 if(isBadLock(irwlock))
    91                         break;
    92    
    93                 return rwlock_trywrlock(irwlock);
    94 
    95         case RWLOCK_TRYRDLOCK:
    96                 if(isBadLock(irwlock))
    97                         break;
    98    
    99                 return rwlock_tryrdlock(irwlock);
    100 
    101         case RWLOCK_UNLOCK:
    102                 if(isBadLock(irwlock))
    103                         break;
    104    
    105                 if((err = rwlock_unlock(irwlock)))
    106                         break;
    107 
    108         case RWLOCK_DESTROY:
    109                 if(isBadLock(irwlock))
    110                         break;
    111    
    112                 if((err = rwlock_destroy(irwlock)))
    113                         break;
    114 
    115                 req.type = KMEM_RWLOCK;
    116                 req.ptr  = irwlock;
    117                 kmem_free(&req);
    118                 return 0;
    119 
    120         default:
    121                 err = EINVAL;
     120            if( mutex_xp == XPTR_NULL )     // user error
     121            {
     122                printk("\n[ERROR] in %s : mutex %x not registered\n",
     123                       __FUNCTION__ , (intptr_t)vaddr );
     124                this->errno = EINVAL;
     125                return -1;
     126            }
     127            else                          // success
     128            {
     129                remote_mutex_unlock( mutex_xp );
     130            }
     131            break;
     132        }
     133        ////////
     134            default:
     135        {
     136            printk("\n[PANIC] in %s : illegal operation type\n", __FUNCTION__ );
     137                    hal_core_sleep();
     138        }
    122139        }
    123140
    124 SYS_RWLOCK_END:
    125         current_thread->info.errno = err;
    126         return err;
    127 }
     141        return 0;
    128142
    129 KMEM_OBJATTR_INIT(rwlock_kmem_init)
    130 {
    131         attr->type   = KMEM_RWLOCK;
    132         attr->name   = "KCM RWLOCK";
    133         attr->size   = sizeof(struct rwlock_s);
    134         attr->aligne = 0;
    135         attr->min    = CONFIG_RWLOCK_MIN;
    136         attr->max    = CONFIG_RWLOCK_MAX;
    137         attr->ctor   = NULL;
    138         attr->dtor   = NULL;
    139  
    140         return 0;
    141 }
     143}  // end sys_mutex()
     144
  • trunk/kernel/syscalls/sys_open.c

    r1 r23  
    11/*
    2  * kern/sys_open.c - open a named file
     2 * sys_open.c - open a file.
    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 */
    2223
     24#include <kernel_config.h>
     25#include <hal_types.h>
     26#include <hal_uspace.h>
    2327#include <errno.h>
    2428#include <thread.h>
     29#include <printk.h>
    2530#include <vfs.h>
    26 #include <sys-vfs.h>
    2731#include <process.h>
    28 #include <spinlock.h>
    29 #include <cpu-trace.h>
     32#include <remote_spinlock.h>
     33#include <remote_rwlock.h>
    3034
    3135///////////////////////////////////
     
    3438               uint32_t   mode )
    3539{
    36         CPU_HW_TRACE(sys_open);
    3740
    38         error_t            err;
    39         struct vfs_file_s  file;   
    40         struct ku_obj      ku_path;
    41         thread_t         * this     = current_thread;
    42         process_t        * process  = current_process;
    43         uint32_t           fd       = (uint32_t)-1;
     41        error_t        error;
     42        xptr_t         file_xp;                          // extended pointer on vfs_file_t
     43        uint32_t       file_id;                          // file descriptor index
     44    uint32_t       length;                           // pathname length (bytes)
     45    char           kbuf[CONFIG_VFS_MAX_PATH_LENGTH];
    4446
    45         cpu_trace_write(current_cpu, sys_open);
     47        thread_t     * this     = CURRENT_THREAD;
     48        process_t    * process  = this->process;
    4649
    47         if( process_fd_aray_full( process ) )
     50        if( pathname == NULL )
    4851        {
    49                 this->info.errno = ENFILE;
    50         CPU_HW_TRACE(sys_open);
    51         return fd;
     52        printk("\n[ERROR] in %s : pathname is NULL\n", __FUNCTION__ );
     53                this->errno = EINVAL;
     54                return -1;
     55        }       
     56
     57    // check fd_array not full
     58        if( process_fd_array_full() )
     59        {
     60        printk("\n[ERROR] in %s : file descriptor array full for process %x\n",
     61               __FUNCTION__ , process->pid );
     62                this->errno = ENFILE;
     63        return -1;
    5264        }
    5365   
    54         if( VFS_IS( flags , VFS_O_DIRECTORY ) ) VFS_SET( flags , VFS_DIR );
     66    // get pathname length
     67    length = hal_strlen_from_uspace( pathname );
    5568
    56         KU_BUFF( ku_path , pathname );
     69    if( length >= CONFIG_VFS_MAX_PATH_LENGTH )
     70    {
     71        printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ );
     72                this->errno = ENFILE;
     73        return -1;
     74    }
     75 
     76        // get pathname copy in kernel space
     77    hal_copy_from_uspace( kbuf, pathname, length );
    5778
    58     // get the cwd lock
    59         rwlock_rdlock( &process->cwd_lock );
     79    // get cluster and local pointer on reference process
     80    xptr_t      ref_xp  = process->ref_xp;
     81    process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
     82    cxy_t       ref_cxy = GET_CXY( ref_xp );
     83
     84    // get extended pointer on cwd inode
     85    xptr_t cwd_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->vfs_cwd_xp ) );
    6086   
    61         err = vfs_open( &process->vfs_cwd , &ku_path , flags , mode , &file );
    62         if( err )
     87    // get the cwd lock in read mode from reference process
     88        remote_rwlock_rd_lock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
     89
     90    // call the relevant VFS function
     91        error = vfs_open( cwd_xp,
     92                      kbuf,
     93                      flags,
     94                      mode,
     95                      &file_xp,
     96                      &file_id );
     97
     98    // release the cwd lock
     99        remote_rwlock_rd_unlock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
     100
     101        if( error )
    63102        {
    64                 this->info.errno = (err < 0 ) ? -err : err;
    65             rwlock_unlock( &process->cwd_lock );
    66             CPU_HW_TRACE(sys_open);
    67             return fd;
    68         }
    69        
    70         err = process_fd_set( process , &file , &fd );
    71         if( err )
    72         {
    73                 vfs_close(&file, NULL);
    74                 this->info.errno = err;
     103        printk("\n[ERROR] in %s : cannot create file descriptor\n", __FUNCTION__ );
     104                this->errno = ENFILE;
     105            return -1;
    75106        }
    76107
    77         rwlock_unlock( &process->cwd_lock );
    78         CPU_HW_TRACE(sys_open);
    79         return fd;
     108    // update local fd_array
     109    remote_spinlock_lock( XPTR( local_cxy , &process->fd_array.lock ) );
     110        process->fd_array.array[file_id] = file_xp;
     111    remote_spinlock_unlock( XPTR( local_cxy , &process->fd_array.lock ) );
     112
     113        return file_id;
    80114}
  • trunk/kernel/syscalls/sys_opendir.c

    r1 r23  
    11/*
    2  * kern/sys_opendir.c - open a directory
     2 * sys_opendir.c - open a directory.
    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 */
    2223
     24#include <hal_types.h>
    2325#include <vfs.h>
    24 #include <sys-vfs.h>
    25 #include <process.h>
    26 #include <thread.h>
    27 #include <spinlock.h>
     26#include <syscalls.h>
    2827
    2928///////////////////////////////////
    3029int sys_opendir ( char * pathname )
    3130{
    32         error_t             err;
    33         struct vfs_file_s   file;
    34         struct ku_obj       ku_path;
    35         thread_t          * this    = current_thread;
    36         process_t         * process = current_process;
    37         uint32_t            fd        = (uint32_t)-1;
    38         uint32_t            mode      = 0;
    39    
    40         if( process_fd_array_full( process ) )
    41         {
    42                 this->info.errno = ENFILE;
    43             return fd;
    44         }
     31        uint32_t   mode  = 0;
     32    uint32_t   flags = O_DIR;
    4533
    46         KU_BUFF(ku_path, pathname);
    47 
    48         rwlock_rdlock( &process->cwd_lock );
    49 
    50         err = vfs_opendir( &process->vfs_cwd , &ku_path , mode , &file );
    51         if( err )
    52         {
    53                 this->info.errno = (err < 0 ) ? -err : err;
    54             rwlock_unlock( &process->cwd_lock );
    55             return fd;
    56         }
    57 
    58         err = process_fd_set( process , &file , &fd);
    59         if( err )
    60         {
    61                 vfs_close(&file, NULL);
    62                 this->info.errno = err;
    63         }
    64    
    65         rwlock_unlock( &process->cwd_lock );
    66         return fd;
     34    return sys_open( pathname , flags , mode );
    6735}
  • trunk/kernel/syscalls/sys_pipe.c

    r1 r23  
    11/*
    2  * kern/sys_pipe.c - open a pipe communication channel
     2 * sys_pipe.c - open a pipe communication channel
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * Author    Alain Greiner  (2016,1017)
    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 */
    2223
     24#include <hal_types.h>
    2325#include <vfs.h>
    24 #include <sys-vfs.h>
    25 #include <task.h>
     26#include <process.h>
    2627#include <thread.h>
    27 #include <spinlock.h>
     28#include <printk.h>
    2829
    29 int sys_pipe (uint_t *pipefd)
     30//////////////////////////////////////
     31int sys_pipe ( uint32_t * file_fd[2] )
    3032{
    31         current_thread->info.errno = ENOSYS;
    32         return -1;
     33    thread_t * this = CURRENT_THREAD;
     34
     35    printk("\n[ERROR] in %d : not implemented yet\n", __FUNCTION__ );
     36    this->errno = ENOSYS;
     37    return -1;
     38
    3339}
  • trunk/kernel/syscalls/sys_read.c

    r1 r23  
    11/*
    2  * kern/sys_read.c - read bytes from an opened file
     2 * sys_read.c - read bytes from a file
    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 */
    2223
     24#include <kernel_config.h>
     25#include <hal_types.h>
     26#include <hal_uspace.h>
     27#include <hal_special.h>
    2328#include <errno.h>
     29#include <vfs.h>
     30#include <vmm.h>
    2431#include <thread.h>
    25 #include <vfs.h>
    26 #include <sys-vfs.h>
    27 #include <task.h>
     32#include <printk.h>
     33#include <process.h>
    2834
    29 int sys_read (uint_t fd, void *buf, size_t count)
     35/* TODO: user page(s) need to be locked  [AG] */
     36
     37/////////////////////////////////
     38int sys_read( uint32_t   file_id,
     39              void     * buf,
     40              uint32_t   count )
    3041{
    31         struct ku_obj kub;
    32         ssize_t err;
    33         struct thread_s *this;
    34         struct task_s *task;
    35         struct vfs_file_s *file;
     42    error_t      error;
     43    paddr_t      paddr;
     44    char         kbuf[CONFIG_VFS_KBUF_SIZE];
    3645
    37         file = NULL;
    38         this = current_thread;
    39         task = current_task;
     46        xptr_t       file_xp;     // remote file extended pointer
     47    uint32_t     nbytes;      // number of bytes in one iteration
    4048
    41         if((fd >= CONFIG_TASK_FILE_MAX_NR) || (task_fd_lookup(task, fd, &file)))
     49        thread_t  *  this    = CURRENT_THREAD;
     50        process_t *  process = this->process;
     51 
     52    // check file_id argument
     53        if( file_id >= CONFIG_PROCESS_FILE_MAX_NR )
    4254        {
    43                 this->info.errno = EBADFD;
     55        printk("\n[ERROR] in %s : illegal file descriptor index = %d\n",
     56               __FUNCTION__ , file_id );
     57                this->errno = EBADFD;
    4458                return -1;
    4559        }
    4660
    47         KU_SLICE_BUFF(kub, buf, count);
    48         if((err = vfs_read(file, &kub)) < 0)
     61    // check user buffer in user space
     62    error = vmm_v2p_translate( false , buf , &paddr );
     63
     64    if ( error )
     65    {
     66        printk("\n[ERROR] in %s : user buffer unmapped = %x\n",
     67               __FUNCTION__ , (intptr_t)buf );
     68                this->errno = EINVAL;
     69                return -1;
     70    }
     71
     72    // get extended pointer on remote file descriptor
     73    file_xp = process_fd_get_xptr( process , file_id );
     74
     75    if( file_xp == XPTR_NULL )
     76    {
     77        printk("\n[ERROR] in %s : undefined file descriptor index = %d\n",
     78               __FUNCTION__ , file_id );
     79        this->errno = EBADFD;
     80        return -1;
     81    }
     82
     83    // get file descriptor cluster and local pointer
     84    vfs_file_t * file_ptr = (vfs_file_t *)GET_PTR( file_xp );
     85    cxy_t        file_cxy = GET_CXY( file_xp );
     86
     87    // check file readable
     88    uint32_t attr = hal_remote_lw( XPTR( file_cxy , &file_ptr->attr ) );
     89    if( (attr & FD_ATTR_READ_ENABLE) == 0 )
    4990        {
    50                 this->info.errno = -err;
    51                 printk(INFO, "INFO: sys_read: Error %d\n", this->info.errno);
     91        printk("\n[ERROR] in %s : file %d not readable\n",
     92               __FUNCTION__ , file_id );
     93                this->errno = EBADFD;
    5294                return -1;
    5395        }
    5496   
    55         return err;
    56 }
     97    // transfer at most CONFIG_VFS_KBUF_SIZE bytes per iteration
     98    while( count )
     99    {
     100        if( count <= CONFIG_VFS_KBUF_SIZE )
     101        {
     102            nbytes = count;
     103            count  = 0;
     104        }
     105        else
     106        {
     107            nbytes = CONFIG_VFS_KBUF_SIZE;
     108            count  = count - CONFIG_VFS_KBUF_SIZE;
     109        }
     110
     111        // transfer nbytes to kernel buffer
     112        error = vfs_move( true,               // read => (to_buffer = true)
     113                          file_xp ,
     114                          kbuf ,
     115                          nbytes );
     116
     117        if( error )
     118        {
     119            printk("\n[ERROR] in %s cannot read data from file %d\n",
     120                   __FUNCTION__ , file_id );
     121            this->errno = error;
     122            return -1;
     123        }
     124
     125        // copy kernel buffer to user space
     126        hal_copy_to_uspace( buf , kbuf , nbytes );
     127    }
     128
     129    hal_wbflush();
     130
     131        return 0;
     132
     133}  // end sys_read()
  • trunk/kernel/syscalls/sys_readdir.c

    r1 r23  
    11/*
    2  * sys_read.c: read entries from an opened directory
    3  *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     2 * sys_readdir.c - Read one entry from an open directory.
    63 *
    7  * This file is part of ALMOS-kernel.
     4 * Author    Alain Greiner (2016,2017)
    85 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     6 * Copyright (c) UPMC Sorbonne Universites
     7 *
     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 */
    2223
     24#include <kernel_config.h>
     25#include <hal_types.h>
     26#include <hal_uspace.h>
     27#include <errno.h>
     28#include <thread.h>
     29#include <printk.h>
    2330#include <vfs.h>
    24 #include <sys-vfs.h>
    25 #include <task.h>
    26 #include <thread.h>
     31#include <process.h>
     32#include <syscalls.h>
    2733
    28 /* FIXEME: reading dirent from user without any protection */
     34//////////////////////////////////////////
     35int sys_readdir ( uint32_t       file_id,
     36                  vfs_dirent_t * dirent )
     37{
     38        error_t        error;
     39    paddr_t        paddr;
     40        xptr_t         file_xp;    // extended pointer on searched directory file descriptor
     41    vfs_dirent_t   k_dirent;   // kernel copy of dirent
    2942
    30 int sys_readdir (uint_t fd, struct vfs_usp_dirent_s *dirent)
    31 {
    32         error_t err;
    33         struct ku_obj dir;
    34         struct task_s *task;
    35         struct thread_s *this;
    36         struct vfs_file_s *file;
    37  
    38         file = NULL;
    39         task = current_task;
    40         this = current_thread;
     43        thread_t     * this     = CURRENT_THREAD;
     44        process_t    * process  = this->process;
    4145
    42         if((dirent == NULL)                ||
    43            (fd >= CONFIG_TASK_FILE_MAX_NR) ||
    44            (task_fd_lookup(task, fd, &file)))
     46    // check file_id argument
     47        if( file_id >= CONFIG_PROCESS_FILE_MAX_NR )
    4548        {
    46                 this->info.errno = EBADFD;
     49        printk("\n[ERROR] in %s : illegal file descriptor index\n", __FUNCTION__ );
     50        this->errno = EBADFD;
    4751                return -1;
    4852        }
    4953
    50         KU_OBJ(dir, dirent);
    51         if((err = vfs_readdir(file, &dir)))
     54    // check dirent structure in user space
     55    error = vmm_v2p_translate( false , dirent , &paddr );
     56
     57    if ( error )
     58    {
     59        printk("\n[ERROR] in %s : user buffer for dirent unmapped = %x\n",
     60               __FUNCTION__ , (intptr_t)dirent );
     61                this->errno = EFAULT;
     62                return -1;
     63    }
     64
     65    // get extended pointer on remote file descriptor
     66    file_xp = process_fd_get_xptr( process , file_id );
     67
     68    if( file_xp == XPTR_NULL )
     69    {
     70        printk("\n[ERROR] in %s : undefined file descriptor index = %d\n",
     71               __FUNCTION__ , file_id );
     72            this->errno = EBADFD;
     73        return -1;
     74    }
     75 
     76    // call the relevant VFS function
     77        error = vfs_readdir( file_xp , &k_dirent );
     78
     79        if( error )
    5280        {
    53                 this->info.errno = (err < 0) ? -err : err;
     81        printk("\n[ERROR] in %s : cannot access directory %d\n",
     82               __FUNCTION__ , file_id );
     83                this->errno = error;
    5484                return -1;
    5585        }
    5686   
     87    // copy dirent to user space
     88    hal_copy_to_uspace( dirent , &k_dirent , sizeof(vfs_dirent_t) );
     89
    5790        return 0;
    58 }
     91
     92}  // end sys_readdir()
  • trunk/kernel/syscalls/sys_rmdir.c

    r1 r23  
    11/*
    2  * sys_rmdir: remove a directory
     2 * sys_rmdir.c - Remove a directory from file system.
     3 *
     4 * Author    Alain Greiner (2016,2017)
    35 *
    46 * Copyright (c) 2015 UPMC Sorbonne Universites
    57 *
    6  * This file is part of ALMOS-kernel.
     8 * This file is part of ALMOS-MKH.
    79 *
    8  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    911 * under the terms of the GNU General Public License as published by
    1012 * the Free Software Foundation; version 2.0 of the License.
    1113 *
    12  * 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
    1315 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1416 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1618 *
    1719 * You should have received a copy of the GNU General Public License
    18  * 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,
    1921 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2022 */
    2123
    22 #include <cpu.h>
     24#include <hal_types.h>
     25#include <hal_uspace.h>
     26#include <printk.h>
     27#include <errno.h>
    2328#include <vfs.h>
    24 #include <sys-vfs.h>
     29#include <vmm.h>
    2530#include <thread.h>
    26 #include <task.h>
     31#include <process.h>
    2732
     33////////////////////////////////
     34int sys_rmdir( char * pathname )
     35{
     36    error_t     error;
     37    paddr_t     paddr;
     38    uint32_t    length;
     39    char        kbuf[CONFIG_VFS_MAX_PATH_LENGTH];
     40       
     41        thread_t  * this    = CURRENT_THREAD;
     42        process_t * process = this->process;
    2843
    29 int sys_rmdir (char *pathname)
    30 {
    31         register struct thread_s *this;
    32         register struct task_s *task;
    33         struct ku_obj ku_path;
    34         error_t err = 0;
    35        
    36         this = current_thread;
    37         task = current_task;
     44    // check pathname in user space
     45    error = vmm_v2p_translate( false , pathname , &paddr );
    3846
    39         if(!pathname)
     47        if( error )
    4048        {
    41                 this->info.errno = EINVAL;
     49        printk("\n[ERROR] in %s : user buffer unmapped  for thread %x in process %x\n",
     50               __FUNCTION__ , this->trdid , process->pid );
     51                this->errno = EINVAL;
     52                return -1;
     53        }       
     54
     55    // get pathname length
     56    length = hal_strlen_from_uspace( pathname );
     57
     58    if( length >= CONFIG_VFS_MAX_PATH_LENGTH )
     59    {
     60        printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ );
     61                this->errno = ENFILE;
     62        return -1;
     63    }
     64 
     65        // get pathname copy in kernel space
     66    hal_copy_from_uspace( kbuf, pathname, length );
     67
     68    // get cluster and local pointer on reference process
     69    xptr_t      ref_xp  = process->ref_xp;
     70    process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
     71    cxy_t       ref_cxy = GET_CXY( ref_xp );
     72
     73    // get extended pointer on cwd inode
     74    xptr_t cwd_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->vfs_cwd_xp ) );
     75   
     76    // get the cwd lock in read mode from reference process
     77        remote_rwlock_rd_lock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
     78
     79    // call the relevant VFS function
     80        error = vfs_rmdir( cwd_xp,
     81                       kbuf );
     82
     83    // release the cwd lock
     84        remote_rwlock_rd_unlock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
     85
     86    if( error )
     87        {
     88        printk("\n[ERROR] in %s : cannot remove directory %s\n",
     89               __FUNCTION__ , kbuf );
     90                this->errno = error;
    4291                return -1;
    4392        }
     93   
     94        return 0;
    4495
    45         KU_BUFF(ku_path, pathname);
    46         rwlock_wrlock(&task->cwd_lock);
    47 
    48         if((err = vfs_rmdir(&current_task->vfs_cwd, &ku_path)))
    49         {
    50                 current_thread->info.errno = (err < 0) ? -err : err;
    51                 rwlock_unlock(&task->cwd_lock);
    52                 return -1;
    53         }
    54        
    55         rwlock_unlock(&task->cwd_lock);
    56         return 0;
    57 }
     96}  // end sys_rmdir()
  • trunk/kernel/syscalls/sys_sem.c

    r1 r23  
    22 * sys_sem.c - Acces a POSIX unamed semaphore.
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * Authors     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 */
    2223
    2324#include <hal_types.h>
    24 #include <hal_uspace.
     25#include <hal_uspace.h>
     26#include <errno.h>
     27#include <thread.h>
     28#include <printk.h>
     29#include <vmm.h>
    2530#include <remote_sem.h>
     31#include <syscalls.h>
    2632
    2733//////////////////////////////////
     
    3137{
    3238        uint32_t             data;   
    33         error_t              error;
     39        paddr_t              paddr;
     40    error_t              error;
    3441
    35     thread_t           * this      = CURRENT_THREAD;
    36         process_t          * process   = CURRENT_PROCESS;
     42    thread_t           * this = CURRENT_THREAD;
    3743
    3844    // check vaddr in user vspace
    39         error = vmm_check_address( process , vaddr , sizeof(unsigned long) );
    40         if( error ) 
     45        error = vmm_v2p_translate( false , vaddr , &paddr );
     46        if( error )
    4147    {
     48        printk("\n[ERROR] in %s : illegal semaphore virtual address = %x\n",
     49               __FUNCTION__ , (intptr_t)vaddr );
    4250        this->errno = error;
    4351        return -1;
     
    4553
    4654    // check value in user vspace
    47     error = vmm_check_address( process , value , sizeof(int*) );
    48         if( error ) 
     55        error = vmm_v2p_translate( false , value , &paddr );
     56        if( error )
    4957    {
     58        printk("\n[ERROR] in %s : illegal argument virtual address = %x\n",
     59               __FUNCTION__ , (intptr_t)value );
    5060        this->errno = error;
    5161        return -1;   
     
    6272
    6373            // call init function
    64             error = remote_sem_init( (intptr_t)vaddr , data );
     74            error = remote_sem_create( (intptr_t)vaddr , data );
    6575
    6676            if ( error )
    6777            {
     78                printk("\n[ERROR] in %s : cannot create semaphore = %x\n",
     79                       __FUNCTION__ , (intptr_t)value );
    6880                this->errno = error;
    6981                return -1;
     
    7991            if( sem_xp == XPTR_NULL )     // user error
    8092            {
     93                printk("\n[ERROR] in %s : semaphore %x not registered\n",
     94                       __FUNCTION__ , (intptr_t)value );
    8195                this->errno = EINVAL;
    8296                return -1;
     
    100114            if( sem_xp == XPTR_NULL )     // user error
    101115            {
     116                printk("\n[ERROR] in %s : semaphore %x not registered\n",
     117                       __FUNCTION__ , (intptr_t)value );
    102118                this->errno = EINVAL;
    103119                return -1;
     
    118134            if( sem_xp == XPTR_NULL )     // user error
    119135            {
     136                printk("\n[ERROR] in %s : semaphore %x not registered\n",
     137                       __FUNCTION__ , (intptr_t)value );
    120138                this->errno = EINVAL;
    121139                return -1;
     
    136154            if( sem_xp == XPTR_NULL )     // user error
    137155            {
     156                printk("\n[ERROR] in %s : semaphore %x not registered\n",
     157                       __FUNCTION__ , (intptr_t)value );
    138158                this->errno = EINVAL;
    139159                return -1;
     
    149169            default:  // undefined operation                       
    150170        {
    151                     this->errno = EINVAL;
    152             return -1;
     171            printk("\n[PANIC] in %s : illegal operation type\n", __FUNCTION__ );
     172            hal_core_sleep();
    153173        }
    154174        }
  • trunk/kernel/syscalls/sys_signal.c

    r1 r23  
    11/*
    2  * sys_sem.c: interface to access signal service
     2 * sys_signal.c - associate a specific signal handler to a given signal.
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012,2013,2014,2015 UPMC Sorbonne Universites
     4 * Authors   Ghassan Almaless (2008,2009,2010,2011,2012)
     5 *           Alain Greiner (2016,2017)
     6 *
     7 * Copyright (c) UPMC Sorbonne Universites
    68 *
    79 * This file is part of ALMOS-kernel.
     
    2123 */
    2224
    23 #include <types.h>
     25#include <hal_types.h>
    2426#include <errno.h>
    2527#include <thread.h>
    26 #include <task.h>
    27 #include <pid.h>
     28#include <printk.h>
    2829#include <signal.h>
    2930
     31//////////////////////////////////
     32int sys_signal( uint32_t   sig_id,
     33                void     * handler )
     34
     35        thread_t  * this = CURRENT_THREAD;
    3036
    31 int sys_signal(uint_t sig, sa_handler_t *handler)
    32 
    33         register struct thread_s *this;
    34         int retval;
    35 
    36         this = current_thread;
    37 
    38         if((sig == 0) || (sig >= SIG_NR) || (sig == SIGKILL) || (sig == SIGSTOP))
     37        if((sig_id == 0) || (sig_id >= SIG_NR) || (sig_id == SIGKILL) || (sig_id == SIGSTOP))
    3938        {
    40                 this->info.errno = EINVAL;
    41                 return SIG_ERROR;
     39        printk("\n[ERROR] in %s : illega signal index = %d\n", __FUNCTION__ , sig_id );
     40                this->errno = EINVAL;
     41                return -1;
    4242        }
    4343
    44         retval = (int) this->task->sig_mgr.sigactions[sig];
    45         this->task->sig_mgr.sigactions[sig] = handler;
     44        // register handler in signal manager for the calling process
     45        this->process->sig_mgr.sigactions[sig_id] = handler;
    4646
    47         sig_dmsg(1, "%s: handler @%x has been registred for signal %d\n",
    48                __FUNCTION__,
    49                handler,
    50                sig);
     47        signal_dmsg("\n[INFO] %s : handler @%x has been registred for signal %d\n",
     48                    __FUNCTION__ , handler , sig_id );
    5149
    52         return retval;
    53 }
    54 
    55 
    56 int sys_sigreturn_setup(void *sigreturn_func)
    57 {
    58         struct thread_s *this;
    59 
    60         this = current_thread;
    61         this->info.attr.sigreturn_func = sigreturn_func;
    62         cpu_context_set_sigreturn(&this->pws, sigreturn_func);
    6350        return 0;
    6451}
    6552
    66 
    67 int sys_kill(pid_t pid, uint_t sig)
    68 {
    69         cid_t   location;
    70         error_t err;
    71 
    72         if((sig == 0) || (sig >= SIG_NR))
    73         {
    74                 err = EINVAL;
    75         }
    76         else
    77         {
    78                 if ( PID_GET_CLUSTER(pid) == current_cid )
    79                         location = current_cid;
    80                 else
    81                         location = task_whereis(pid);
    82 
    83                 err = signal_rise(pid, location, sig);
    84 
    85                 /* No error, return 0 */
    86                 if (!err)
    87                         return 0;
    88         }
    89 
    90         /* Error. Set errno and return */
    91         current_thread->info.errno = err;
    92         return -1;
    93 }
  • trunk/kernel/syscalls/sys_stat.c

    r1 r23  
    11/*
    2  * kern/sys_stat.c - stats a file or directory
     2 * sys_stat.c - Return statistics on a file or directory.
    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 */
    2223
     24#include <hal_types.h>
     25#include <hal_uspace.h>
     26#include <hal_special.h>
    2327#include <errno.h>
    2428#include <thread.h>
     29#include <printk.h>
    2530#include <vfs.h>
    26 #include <sys-vfs.h>
    27 #include <task.h>
    28 #include <spinlock.h>
    29 #include <cpu-trace.h>
     31#include <vmm.h>
     32#include <process.h>
    3033
     34//////////////////////////////////////////
     35int sys_stat( uint32_t            file_id,
     36              struct vfs_stat_s * stat )
     37{
     38    error_t           error;
     39    paddr_t           paddr;
     40    struct vfs_stat_s k_stat;
     41    xptr_t            file_xp;
     42       
     43        thread_t  * this    = CURRENT_THREAD;
     44        process_t * process = this->process;
    3145
    32 int sys_stat(char *pathname, struct vfs_stat_s *buff, int fd)
    33 {
    34         CPU_HW_TRACE(sys_stat);
    35         struct thread_s *this;
    36         register error_t err = 0;
    37         struct vfs_file_s *file;
    38         struct ku_obj ku_path;
    39         struct task_s *task;
     46    // check stat structure in user space
     47    error = vmm_v2p_translate( false , stat , &paddr );
    4048
    41         file = NULL;
    42         this = current_thread;
    43         task = current_task;
     49        if( error )
     50        {
     51        printk("\n[ERROR] in %s : stat structure unmapped  for thread %x in process %x\n",
     52               __FUNCTION__ , this->trdid , process->pid );
     53                this->errno = EINVAL;
     54                return -1;
     55        }       
    4456
    45         if((buff == NULL) || ((pathname == NULL) && (fd == -1)))
     57    // get extended pointer on remote file descriptor
     58    file_xp = process_fd_get_xptr( process , file_id );
     59
     60    if( file_xp == XPTR_NULL )
     61    {
     62        printk("\n[ERROR] in %s : undefined file descriptor for thread %x in process %x\n",
     63               __FUNCTION__ , this->trdid , process->pid );
     64        this->errno = EBADFD;
     65        return -1;
     66    }
     67
     68    // call the relevant VFS function
     69    error = vfs_stat( file_xp,
     70                      &k_stat );
     71    if( error )
    4672        {
    47                 this->info.errno = EINVAL;
    48                 CPU_HW_TRACE(sys_stat);
     73        printk("\n[ERROR] in %s : cannot access file %d for thread %x in process %x\n",
     74               __FUNCTION__ , file_id , this->trdid , process->pid );
     75                this->errno = error;
    4976                return -1;
    5077        }
     78   
     79    // copy stat to user space
     80    hal_copy_to_uspace( stat , &k_stat , sizeof(struct vfs_stat_s) );
    5181
    52         if(NOT_IN_USPACE((uint_t)buff))
    53         {
    54                 this->info.errno = EPERM;
    55                 CPU_HW_TRACE(sys_stat);
    56                 return -1;
    57         }
     82    hal_wbflush();
    5883
    59         if(pathname == NULL)
    60         {
    61                 if((fd >= CONFIG_TASK_FILE_MAX_NR) || (task_fd_lookup(task, fd, &file)))
    62                 {
    63                         CPU_HW_TRACE(sys_stat);
    64                         return EBADFD;
    65                 }
    66  
    67                 err = vfs_stat(&task->vfs_cwd, NULL, buff, file);
    68         }
    69         else
    70         {
    71                 KU_BUFF(ku_path, pathname);
    72                 rwlock_rdlock(&task->cwd_lock);
    73                 err = vfs_stat(&task->vfs_cwd, &ku_path, buff, NULL);
    74                 rwlock_unlock(&task->cwd_lock);
    75         }
    76  
    77         this->info.errno = err;
    78         CPU_HW_TRACE(sys_stat);
    7984        return 0;
    80 }
     85
     86}  // end sys_stat()
     87
  • trunk/kernel/syscalls/sys_thread_create.c

    r14 r23  
    22 * sys_thread_create.c - creates a new user thread
    33 *
    4  * Author  Ghassan Almaless (2008,2009,2010,2011,2012)
    5  *         Mohamed lamine Karaoui (2015)
    6  *         Alain Greiner (2016)
     4 * Author     Alain Greiner (2016,2017)
    75 *
    86 * Copyright (c) UPMC Sorbonne Universites
     
    2624#include <kernel_config.h>
    2725#include <hal_types.h>
     26#include <hal_uspace.h>
    2827#include <printk.h>
    2928#include <errno.h>
     
    3837#include <spinlock.h>
    3938#include <dqdt.h>
     39#include <rpc.h>
    4040
    4141
     
    4646                        pthread_attr_t * user_attr,     // [in] argument
    4747                        void           * start_func,    // [in] argument
    48                         void           * start_args )   // [in] argument
     48                        void           * start_arg )    // [in] argument
    4949{
    50         pthread_attr_t   attr;             // copy of pthread attributes in kernel space
     50        pthread_attr_t   k_attr;           // copy of pthread attributes in kernel space
    5151        thread_t       * parent;           // pointer on thread executing the pthread_create
    52     xptr_t           xp_parent;        // extended pointer on created thread
    53     thread_t       * child;            // pointer on created child thread
    54     xptr_t           xp_child;         // extended pointer on created thread
     52    xptr_t           parent_xp;        // extended pointer on created thread
     53    thread_t       * child_ptr;        // pointer on created child thread
     54    xptr_t           child_xp;         // extended pointer on created thread
    5555    trdid_t          trdid;            // created thread identifier
    5656    process_t      * process;          // pointer on local process descriptor
     57    paddr_t          paddr;            // unused, required by vmm_v2p_translate()
    5758    error_t          error;
    5859
     
    6465    // get parent thead pointer, extended pointer, and process pointer
    6566        parent     = CURRENT_THREAD;
    66     xp_parent  = XPTR( local_cxy , parent );   
     67    parent_xp  = XPTR( local_cxy , parent );   
    6768        process    = parent->process;
    6869
    69     // check user_attr & start_func arguments
    70         if( user_attr == NULL )
     70    // check user_attr in user space
     71    error = vmm_v2p_translate( false , user_attr , &paddr );
     72
     73        if( error )
    7174        {
    72                 printk("\n[ERROR] in %s : user_attr is NULL\n", __FUNCTION__ );
    73                 return EINVAL;
    74         }
    75         if( start_func== NULL )
    76         {
    77                 printk("\n[ERROR] in %s : start_func is NULL\n", __FUNCTION__ );
    78                 return EINVAL;
     75                printk("\n[ERROR] in %s : user_attr unmapped\n", __FUNCTION__ );
     76                parent->errno = EINVAL;
     77        return -1;
    7978        }
    8079
    81     // copy user_attr structure to kernel space
    82         hal_copy_from_uspace( &attr , user_attr , sizeof(pthread_attr_t) );
     80    // check start_func in user space
     81    error = vmm_v2p_translate( false , start_func , &paddr );
     82
     83        if( error )
     84        {
     85                printk("\n[ERROR] in %s : start_func unmapped\n", __FUNCTION__ );
     86                parent->errno = EINVAL;
     87        return -1;
     88        }
     89
     90    // check start_arg in user space
     91    if( start_arg != NULL ) error = vmm_v2p_translate( false , start_arg , &paddr );
     92
     93        if( error )
     94        {
     95                printk("\n[ERROR] in %s : start_arg unmapped\n", __FUNCTION__ );
     96                parent->errno = EINVAL;
     97        return -1;
     98        }
     99
     100    // copy user_attr structure from user space to kernel space
     101        hal_copy_from_uspace( &k_attr , user_attr , sizeof(pthread_attr_t) );
    83102
    84103    // check/set "cxy" attribute
    85         if( attr.flags & PT_FLAG_CLUSTER_DEFINED )
     104        if( k_attr.attributes & PT_ATTR_CLUSTER_DEFINED )
    86105    {
    87         if( cluster_is_undefined( attr.cxy ) )
     106        if( cluster_is_undefined( k_attr.cxy ) )
    88107        {
    89                     printk("\n[ERROR] in %s : illegal target cluster = %x\n",
    90                    __FUNCTION__ , attr.cxy );
    91                     return = EINVAL;
     108                    printk("\n[ERROR] in %s : illegal target cluster attribute = %x\n",
     109                   __FUNCTION__ , k_attr.cxy );
     110                    parent->errno = EINVAL;
     111            return -1;
    92112        }
    93113    }
    94114    else
    95115    {
    96         attr.cxy = dqdt_get_cluster_for_process();
     116        k_attr.cxy = dqdt_get_cluster_for_process();
    97117    }
    98118
    99     // set "pid", "start_func" & "start_args" attributes
    100     attr.pid        = process->pid;
    101     attr.start_func = start_func;
    102     attr.start_args = start_args;
    103 
    104119    // create the thread, using a RPC if required
    105     // this returns "error", "child", and "xp_child"
    106     if( attr.cxy == local_cxy )                 // target cluster is local
     120    // this returns "error", "child", and "child_xp"
     121 
     122    if( k_attr.cxy == local_cxy )                         // target cluster is local
    107123    {
    108         // allocate a stack from local VMM
    109         vseg_t * vseg = vmm_create_vseg( process,
    110                                          0,
    111                                          0,
    112                                          VSEG_TYPE_STACK,
    113                                          local_cxy );
    114         if( vseg == NULL )
    115         {
    116                     printk("\n[ERROR] in %s for : cannot create stack vseg\n", __FUNCTION__ );
    117                     return = EINVAL;
    118         }
    119124
    120125        // create thread in local cluster
    121         error = thread_user_create( &child,
    122                                     &attr,
    123                                     vseg->min,
    124                                     vseg->max - vseg->min );
     126        error = thread_user_create( process->pid,
     127                                    start_func,
     128                                    start_arg,
     129                                    &k_attr,
     130                                    &child_ptr );
    125131
    126         xp_child = XPTR( local_cxy , thread );
     132        child_xp = XPTR( local_cxy , child_ptr );
    127133    }
    128134    else                                                 // target cluster is remote
    129135    {
    130         rpc_thread_user_create( attr.cxy , &attr , &error , &xp_child );
    131         child = (thread_t *)GET_PTR( xp_child );
     136        rpc_thread_user_create_client( k_attr.cxy,
     137                                       process->pid,
     138                                       start_func,
     139                                       start_arg,
     140                                       &k_attr,
     141                                       &child_xp,
     142                                       &error );
     143
     144        child_ptr = (thread_t *)GET_PTR( child_xp );
    132145    }
    133146
     
    140153
    141154    // returns trdid to user space
    142     trdid = hal_remote_lw( XPTR( attr.cxy , &child->trdid ) );   
     155    trdid = hal_remote_lw( XPTR( k_attr.cxy , &child_ptr->trdid ) );   
    143156        hal_copy_to_uspace( new_thread , &trdid , sizeof(pthread_t) );
    144157   
    145158    // register new-thread in parent-thread children list if required
    146     if( attr.flags & PT_FLAG_DETACH == 0 ) thread_child_parent_link( xp_parent , xp_child );
     159    if( (k_attr.attributes & PT_ATTR_DETACH) == 0 )
     160        thread_child_parent_link( parent_xp , child_xp );
    147161
    148162        tm_end = hal_time_stamp();
     
    150164        thread_dmsg("\n[INFO] %s created thread %x for process %x in cluster %x\n"
    151165                "  start_cycle = %d / end_cycle = %d\n",
    152                    trdid , process->pid , attr.cxy , tm_start , tm_end );
     166                   trdid , process->pid , k_attr.cxy , tm_start , tm_end );
    153167        return 0;
    154168
  • trunk/kernel/syscalls/sys_thread_detach.c

    r1 r23  
    11/*
    2  * kern/sys_thread_detach.c - detach a joinable thread
     2 * sys_thread_detach.c - detach a joinable thread
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
     4 * Authors   Alain Greiner (2016,2017)
     5 *
    56 * Copyright (c) 2011,2012 UPMC Sorbonne Universites
    67 *
    7  * This file is part of ALMOS-kernel.
     8 * This file is part of ALMOS-MKH.
    89 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1718 *
    1819 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2021 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2122 */
    2223
    23 #include <list.h>
     24#include <hal_types.h>
     25#include <hal_remote.h>
     26#include <hal_special.h>
    2427#include <thread.h>
    25 #include <kmem.h>
    26 #include <kmagics.h>
    2728#include <errno.h>
    28 #include <task.h>
    29 #include <spinlock.h>
     29#include <printk.h>
    3030
    31 int sys_thread_detach (pthread_t tid)
     31//////////////////////////////////////
     32int sys_thread_detach( trdid_t trdid )
    3233{
    33         register struct task_s *task;
    34         struct thread_s *target_th;
    35         uint_t state;
    36         error_t err;
     34    xptr_t       target_xp;
     35        thread_t   * target_ptr;
     36    cxy_t        target_cxy;
     37    ltid_t       target_ltid;
     38    uint32_t     flags;
    3739
    38         task = current_task;
     40        thread_t   * this    = CURRENT_THREAD;
     41    process_t  * process = this->process;
    3942
    40         if(tid > task->max_order)
     43    // get target thread ltid and cxy
     44    target_ltid = LTID_FROM_TRDID( trdid );
     45    target_cxy  = CXY_FROM_TRDID( trdid );
     46
     47    // check trdid argument
     48        if( (target_ltid >= CONFIG_THREAD_MAX_PER_CLUSTER) || cluster_is_undefined( target_cxy ) ) 
    4149        {
    42                 err = EINVAL;
    43                 goto fail_arg;
    44         }
    45  
    46         spinlock_lock(&task->th_lock);
    47 
    48         target_th = task->th_tbl[tid];
    49    
    50         if((target_th == NULL)                 ||
    51            (target_th->signature != THREAD_ID) ||
    52            (target_th->info.attr.key != tid))
    53         {
    54                 err = ESRCH;
    55                 goto fail_srch;
    56         }
    57  
    58         if(!(thread_isJoinable(target_th)))
    59         {
    60                 err = EINVAL;
    61                 goto fail_not_joinable;
    62         }
    63  
    64         err = 0;
    65 
    66         spinlock_lock(&target_th->lock);
    67 
    68         thread_clear_joinable(target_th);
    69 
    70         if((target_th->info.join == NULL) &&
    71            !(state = wait_queue_isEmpty(&target_th->info.wait_queue)))
    72         {
    73                 wakeup_one(&target_th->info.wait_queue, WAIT_ANY);
     50        printk("\n[ERROR] in %s : illegal trdid argument\n", __FUNCTION__ );
     51                this->errno = EINVAL;
     52                return -1;
    7453        }
    7554
    76         spinlock_unlock(&target_th->lock);
    77  
    78 fail_not_joinable:
    79 fail_srch:
    80         spinlock_unlock(&task->lock);
     55    // get extended pointer on target thread
     56        target_xp  = thread_get_xptr( process->pid , trdid );
    8157
    82 fail_arg:
    83         current_thread->info.errno = err;
    84         return err;
    85 }
     58    if( target_xp == XPTR_NULL )
     59    {
     60        printk("\n[ERROR] in %s : target thread not found\n", __FUNCTION__ );
     61        this->errno = ESRCH;
     62        return -1;
     63    }
     64
     65    // get local pointer on target thread
     66    target_ptr = (thread_t *)GET_PTR( target_xp );
     67
     68    // get target thread flags
     69    flags = hal_remote_lw( XPTR( target_cxy , &target_ptr->flags ) );
     70
     71    // check target thread joinable
     72    if( flags & THREAD_FLAG_DETACHED )
     73    {
     74        printk("\n[ERROR] in %s : target thread not joinable\n", __FUNCTION__ );
     75        this->errno = EINVAL;
     76        return -1;
     77    }
     78
     79    // atomically set the thread DETACHED flag
     80    hal_remote_atomic_or( XPTR( target_cxy , &target_ptr->flags ) , THREAD_FLAG_DETACHED );
     81
     82        return 0;
     83
     84}  // end sys_thread_detach()
  • trunk/kernel/syscalls/sys_thread_exit.c

    r16 r23  
    11/*
    2  * kern/sys_thread_exit.c - terminates the execution of current thread
     2 * sys_thread_exit.c - terminates the execution of current thread
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * Authors       Ghassan Almaless (2008,2009,2010,2011,2012)
     5 *               Alain Greiner (2016,2017)
    66 *
    7  * This file is part of ALMOS-kernel.
     7 * Copyright (c) UPMC Sorbonne Universites
    88 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     9 * This file is part of ALMOS-MKH.
     10 *
     11 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1012 * under the terms of the GNU General Public License as published by
    1113 * the Free Software Foundation; version 2.0 of the License.
    1214 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     15 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1416 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1517 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1719 *
    1820 * 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,
     21 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2022 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2123 */
    2224
    23 #include <list.h>
     25#include <hal_types.h>
     26#include <hal_irqmask.h>
    2427#include <thread.h>
     28#include <core.h>
    2529#include <scheduler.h>
    26 #include <wait_queue.h>
    27 #include <cluster.h>
    28 #include <dqdt.h>
    29 #include <process.h>
     30#include <printk.h>
    3031
    31 ///////////////////////////////////////
    32 int sys_thread_exit ( void * exit_val )
     32
     33////////////////////////////////////////
     34int sys_thread_exit( void * exit_value )
    3335{
    3436        thread_t  * this = CURRENT_THREAD;
    3537    core_t    * core = this->core;
    36         bool_t      isEmpty;
    37         bool_t      isReleased;
    3838    uint32_t    irq_state;
    3939
    40         // update DQDT TODO must be done by thread destroy
    41         if(this->process->pid != 1) dqdt_local_update_threads( -1 );
     40    // register the exit_value in thread descriptor
     41    this->exit_value = exit_value;
    4242
    43         spinlock_lock( &this->lock );
     43    // we enter the join loop to wait the join
     44    // only if thread is joinable
     45    if( (this->flags & THREAD_FLAG_DETACHED) == 0 )
     46    {
     47            while( 1 )
     48            {
     49            // take the lock protecting the flags
     50                remote_spinlock_lock( XPTR( local_cxy, &this->flags_lock ) );
    4451
    45         if(!(thread_isJoinable(this)))
    46         {
    47                 goto exit_dead;
     52            // check the JOIN flag
     53            if( this->flags & THREAD_FLAG_JOIN )       // parent made a join
     54            {
     55                // unblock the parent thread
     56                thread_unblock( this->parent , THREAD_BLOCKED_JOIN );
     57
     58                // release the lock protecting the flags
     59                    remote_spinlock_unlock( XPTR( local_cxy, &this->flags_lock ) );
     60
     61                // exit while
     62                break;
     63            }
     64            else                                       // no join done by parent thread
     65            {
     66                // set the EXIT flag
     67                this->flags |= THREAD_FLAG_EXIT;
     68
     69                // block this thread
     70                thread_block( this , THREAD_BLOCKED_EXIT );
     71
     72                // release the lock protecting the flags
     73                    remote_spinlock_unlock( XPTR( local_cxy, &this->flags_lock ) );
     74
     75                // deschedule
     76                sched_yield();
     77            }     
     78        }
    4879        }
    49 
    50         // Check if there's a thread waiting the end of calling thread
    51         isEmpty = wait_queue_isEmpty(&this->info.wait_queue);
    52 
    53         if(isEmpty)
    54         {
    55                 this->info.exit_value = exit_val;
    56                 wait_on(&this->info.wait_queue, WAIT_ANY);
    57                 spinlock_unlock_nosched(&this->lock);
    58                 sched_sleep(this);
    59         }
    60         else
    61         {
    62                 this->info.join->info.exit_value = exit_val;
    63                 wakeup_one(&this->info.wait_queue, WAIT_ANY);
    64                 spinlock_unlock_nosched(&this->lock);
    65         }
    66 
    67 exit_dead:
    68 
    69         isReleased = false;
    7080
    7181        // Release FPU if required
    7282        hal_disable_irq( &irq_state );
    73         if(core->fpu_owner == this)
    74         {
    75                 core->fpu_owner = NULL;
    76                 isReleased = true;
    77         }
     83        if( core->fpu_owner == this )  core->fpu_owner = NULL;
    7884        hal_restore_irq( irq_state );
    7985
    80         if(isReleased)
    81         {
    82                 thread_dmsg(1, "INFO: Thread %x has released FPU on CPU %d\n",
    83                        this,
    84                        current_cpu->gid);
    85         }
     86        // suicide
     87    thread_kill( this );
     88        return 0;       
    8689
    87         sched_exit(this);
    88 
    89         PANIC ("Thread %x, CPU %d must never return", this, current_cpu->gid);
    90         return -1;              /* Fake return ! */
    91 }
     90}  // end sys_thread_exit()
  • trunk/kernel/syscalls/sys_thread_join.c

    r1 r23  
    11/*
    2  * kern/sys_thread_join.c - passive wait on the end of a given thread
     2 * sys_thread_join.c - passive wait on the end of a given thread.
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
     4 * Authors    Alain Greiner (2016,2017)
     5 *
    56 * Copyright (c) 2011,2012 UPMC Sorbonne Universites
    67 *
    7  * This file is part of ALMOS-kernel.
     8 * This file is part of ALMOS-MKH.
    89 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1718 *
    1819 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2021 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2122 */
    2223
    23 #include <list.h>
     24#include <hal_types.h>
     25#include <hal_remote.h>
     26#include <hal_special.h>
    2427#include <thread.h>
     28#include <vmm.h>
    2529#include <scheduler.h>
    26 #include <kmem.h>
    2730#include <errno.h>
    28 #include <task.h>
    29 #include <spinlock.h>
     31#include <printk.h>
     32#include <remote_spinlock.h>
    3033
    31 int sys_thread_join (pthread_t tid, void **thread_return)
     34///////////////////////////////////////
     35int sys_thread_join ( trdid_t    trdid,
     36                      void    ** exit_value )
    3237{
    33         register struct task_s *task;
    34         register struct thread_s *this;
    35         register struct thread_s *target_th;
    36         register uint_t state = 0;
    37         void *retval;
    38         int err;
     38    xptr_t        target_xp;
     39    thread_t    * target_ptr;
     40    cxy_t         target_cxy;
     41    ltid_t        target_ltid;
     42    uint32_t      flags;        // target thread flags
     43    intptr_t      value;        // value returned by target thread
     44    paddr_t       paddr;        // required for vmm_v2p_translate()
    3945
    40         this   = current_thread;
    41         task   = this->task;
    42         retval = 0;
     46        thread_t  * this    = CURRENT_THREAD;
     47    process_t * process = this->process;
    4348
    44         if((tid > task->max_order) ||
    45            ((thread_return != NULL) &&
    46             (NOT_IN_USPACE((uint_t)thread_return + sizeof(void*)))))
     49    // get target thread ltid and cxy
     50    target_ltid = LTID_FROM_TRDID( trdid );
     51    target_cxy  = CXY_FROM_TRDID( trdid );
     52
     53    // check trdid argument
     54        if( (target_ltid >= CONFIG_THREAD_MAX_PER_CLUSTER) || cluster_is_undefined( target_cxy ) ) 
    4755        {
    48                 err = EINVAL;
    49                 goto fail_arg;
     56        printk("\n[ERROR] in %s : illegal trdid argument\n", __FUNCTION__ );
     57                this->errno = EINVAL;
     58                return -1;
    5059        }
    5160
    52         /* try to write to userland address */
    53         if(thread_return)
     61    // check exit_value argument
     62        if( (exit_value != NULL) && (vmm_v2p_translate( false , exit_value , &paddr ) != 0 ) )
    5463        {
    55                 if((err = cpu_copy_to_uspace(thread_return, &retval, sizeof(void *))))
    56                         goto fail_uspace_ret;
     64        printk("\n[ERROR] in %s : illegal exit_value argument\n", __FUNCTION__ );
     65                this->errno = EINVAL;
     66                return -1;
    5767        }
    5868
    59         spinlock_lock(&task->th_lock);
    60         target_th = task->th_tbl[tid];
     69    // check target thread != this thread
     70    if( this->trdid == trdid )
     71    {
     72        printk("\n[ERROR] in %s : this thread == target thread\n", __FUNCTION__ );
     73        this->errno = EDEADLK;
     74        return -1;
     75    }
    6176
    62         if((target_th == NULL)                 ||
    63            (target_th->signature != THREAD_ID) ||
    64            (target_th->info.attr.key != tid))
    65         {
    66                 err = ESRCH;
    67                 goto fail_srch;
    68         }
     77    // get extended pointer on target thread
     78        target_xp  = thread_get_xptr( process->pid , trdid );
    6979
    70         if(target_th == this)
    71         {
    72                 err = EDEADLK;
    73                 goto fail_deadlock;
    74         }
     80    if( target_xp == XPTR_NULL )
     81    {
     82        printk("\n[ERROR] in %s : target thread not found\n", __FUNCTION__ );
     83        this->errno = ESRCH;
     84        return -1;
     85    }
    7586
    76         if(!(thread_isJoinable(target_th)))
    77         {
    78                 err = EINVAL;
    79                 goto fail_joinable;
    80         }
    81    
    82         spinlock_lock(&target_th->lock);
    83    
    84         if(target_th->info.join != NULL)
    85         {
    86                 spinlock_unlock(&target_th->lock);
    87                 err = EINVAL;
    88                 goto fail_joined;
    89         }
     87    // get cluster and local pointer on target thread
     88    target_ptr = (thread_t *)GET_PTR( target_xp );
    9089
    91         // Get the exit code of the target thread
    92         if ((state=wait_queue_isEmpty(&target_th->info.wait_queue)))
    93         {
    94                 target_th->info.join = this;
    95                 wait_on(&target_th->info.wait_queue, WAIT_ANY);
    96                 spinlock_unlock(&target_th->lock);
    97                 spinlock_unlock_nosched(&task->th_lock);
    98                 sched_sleep(this);
    99                 retval = this->info.exit_value;
    100         }
    101         else
    102         {
    103                 retval = target_th->info.exit_value;
    104                 wakeup_one(&target_th->info.wait_queue, WAIT_ANY);
    105                 spinlock_unlock(&target_th->lock);
    106                 spinlock_unlock(&task->th_lock);
    107         }
     90    // check target thread joinable
     91    flags = hal_remote_lw( XPTR( target_cxy , &target_ptr->flags ) );
     92    if( flags & THREAD_FLAG_DETACHED )
     93    {
     94        printk("\n[ERROR] in %s : target thread not joinable\n", __FUNCTION__ );
     95        this->errno = EINVAL;
     96        return -1;
     97    }
    10898
    109         /* Probably will not fail */
    110         if(thread_return)
    111         {
    112                 if((err = cpu_copy_to_uspace(thread_return, &retval, sizeof(void *))))
    113                         goto fail_uspace;
    114         }
     99    // check kernel stack overflow
     100    if( target_ptr->signature != THREAD_SIGNATURE )
     101    {
     102        printk("\n[PANIC] in %s : kernel stack overflow\n", __FUNCTION__ );
     103        hal_core_sleep();
     104    }
    115105
    116         return 0;
     106    // wait target thread exit
     107    while( 1 )
     108    {
     109        // take the target thread lock protecting flags     
     110        remote_spinlock_lock( XPTR( target_cxy , &target_ptr->flags_lock ) );
    117111
    118 fail_joined:
    119 fail_joinable:
    120 fail_deadlock:
    121 fail_srch:
    122         spinlock_unlock(&task->th_lock);
     112        // get the remote thread flags
     113        flags = hal_remote_lw( XPTR( target_cxy , &target_ptr->flags ) );
    123114
    124 fail_uspace:
    125 fail_uspace_ret:
    126 fail_arg:
    127         this->info.errno = err;
    128         return err;
    129 }
     115        // check the EXIT flag
     116        if( flags & THREAD_FLAG_EXIT )   // target made an exit
     117        {
     118            // unblock the target thread
     119            thread_unblock( target_xp , THREAD_BLOCKED_EXIT );
     120
     121            // release the target thread lock protecting flags     
     122            remote_spinlock_unlock( XPTR( target_cxy , &target_ptr->flags_lock ) );
     123
     124            // exit while
     125            break;
     126        }
     127        else                             // no exit done by target thread
     128        {
     129            // set the JOIN flag in target thread
     130            hal_remote_atomic_or( XPTR( target_xp , &target_ptr->flags ) ,
     131                                  THREAD_BLOCKED_JOIN );
     132
     133            // block this thread
     134            thread_block( this , THREAD_BLOCKED_JOIN );
     135
     136            // release the target thread lock protecting flags
     137                remote_spinlock_unlock( XPTR( target_cxy , &target_ptr->flags_lock ) );
     138
     139            // deschedule
     140            sched_yield();
     141        }
     142    }
     143
     144    // return exit_value from target thread descriptor
     145    value = (intptr_t)hal_remote_lpt( XPTR( target_cxy , &target_ptr->exit_value ) );
     146    *exit_value = (void *)value;
     147    return 0;
     148
     149}  // end sys_thread_join()
  • trunk/kernel/syscalls/sys_thread_sleep.c

    r1 r23  
    11/*
    2  * kern/sys_thread_sleep.c - puts the current thread in sleep state
     2 * sys_thread_sleep.c - put the calling thread in sleep state
    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 */
    2223
     24#include <hal_special.h>
    2325#include <scheduler.h>
    2426#include <thread.h>
    25 #include <task.h>
     27#include <printk.h>
    2628
     29//////////////////////
    2730int sys_thread_sleep()
    2831{
    29         struct thread_s *this;
     32    thread_t * this = CURRENT_THREAD;
    3033
    31         this = current_thread;
     34    thread_dmsg("\n[INFO] %s : thread %x in process %x goes to sleep at cycle %d\n",
     35                __FUNCTION__ , this->trdid , this->process->pid , hal_time_stamp() );
    3236
    33         if(this->info.isTraced == true)
    34         {
    35                 printk(INFO, "%s: cpu %d, pid %d, tid %d, asked to go sleep [%d]\n",
    36                        __FUNCTION__,
    37                        cpu_get_id(),
    38                        this->task->pid,
    39                        this->info.order,
    40                        cpu_time_stamp());
    41         }
     37    thread_block( CURRENT_THREAD , THREAD_BLOCKED_GLOBAL );
     38    sched_yield();
    4239
    43         thread_set_cap_wakeup(this);
    44         sched_sleep(this);
    45  
    46         if(this->info.isTraced == true)
    47         {
    48                 printk(INFO, "%s: cpu %d, pid %d, tid %d, resuming [%d]\n",
    49                        __FUNCTION__,
    50                        cpu_get_id(),
    51                        this->task->pid,
    52                        this->info.order,
    53                        cpu_time_stamp());
    54         }
     40    thread_dmsg("\n[INFO] %s : thread %x in process %x resume at cycle\n",
     41                __FUNCTION__ , this->trdid , this->process->pid , hal_time_stamp() );
    5542
    5643        return 0;
    57 }
     44}  // end sys_thread_sleep()
  • trunk/kernel/syscalls/sys_thread_wakeup.c

    r1 r23  
    11/*
    2  * kern/sys_thread_wakeup.c - wakeup all indicated threads
     2 * sys_thread_wakeup.c - wakeup all indicated threads
    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 */
    2223
     24#include <hal_types.h>
     25#include <thread.h>
     26#include <printk.h>
     27#include <process.h>
    2328#include <errno.h>
    24 #include <kmagics.h>
    25 #include <cpu.h>
    26 #include <kdmsg.h>
    27 #include <cluster.h>
    28 #include <task.h>
    29 #include <scheduler.h>
    30 #include <thread.h>
    3129
    32 /*
    33  * FIXME: define spinlock_rdlock() so all locking on task->th_lock
    34  * becoms rdlock but on join/detach/destroy
    35  */
    36 int sys_thread_wakeup(pthread_t tid, pthread_t *tid_tbl, uint_t count)
     30//////////////////////////////////////
     31int sys_thread_wakeup( trdid_t trdid )
    3732{
    38         struct task_s *task;
    39         struct thread_s *this;
    40         struct thread_s *target;
    41         pthread_t tbl[100];
    42         void *listner;
    43         uint_t event;
    44         sint_t i;
    45         error_t err;
     33        thread_t  * this    = CURRENT_THREAD;
     34    process_t * process = this->process;
    4635
    47         this = current_thread;
    48         task = this->task;
    49         i = -1;
     36    // get target thread ltid and cxy
     37    ltid_t   target_ltid = LTID_FROM_TRDID( trdid );
     38    cxy_t    target_cxy  = CXY_FROM_TRDID( trdid );
    5039
    51         if(tid_tbl != NULL)
     40    // check trdid argument
     41        if( (target_ltid >= CONFIG_THREAD_MAX_PER_CLUSTER) || cluster_is_undefined( target_cxy ) ) 
    5242        {
    53                 if((NOT_IN_USPACE((uint_t)tid_tbl + (count*sizeof(pthread_t)))) ||
    54                    (count == 0) || (count > 100))
    55                 {
    56                         err = -1;
    57                         goto fail_tid_tbl;
    58                 }
    59 
    60                 if((err = cpu_copy_from_uspace(&tbl[0], tid_tbl, sizeof(pthread_t*) * count)))
    61                         goto fail_usapce;
    62 
    63                 if(tbl[0] != tid)
    64                 {
    65                         err = -2;
    66                         goto fail_first_tid;
    67                 }
    68         }
    69         else
    70         {
    71                 count = 1;
    72                 tbl[0] = tid;
     43        printk("\n[ERROR] in %s : illegal trdid argument\n", __FUNCTION__ );
     44                this->errno = EINVAL;
     45                return -1;
    7346        }
    7447
    75         for(i = 0; i < count; i++)
    76         {
    77                 tid = tbl[i];
     48    // get extended pointer on target thread
     49    xptr_t thread_xp = thread_get_xptr( process->pid , trdid );
    7850
    79                 if(tid > task->max_order)
    80                 {
    81                         err = -3;
    82                         goto fail_tid;
    83                 }
     51    if( thread_xp == XPTR_NULL )
     52    {
     53        printk("\n[ERROR] in %s : cannot find thread %x in process %x/n",
     54               __FUNCTION__ , trdid , CURRENT_THREAD->process->pid );
     55        CURRENT_THREAD->errno = EINVAL;
     56        return -1;
     57    }
    8458
    85                 target = task->th_tbl[tid];
    86    
    87                 if((target == NULL) || (target->signature != THREAD_ID))
    88                 {
    89                         err = -4;
    90                         goto fail_target;
    91                 }
     59    // unblock target thread
     60    thread_unblock( thread_xp , THREAD_BLOCKED_GLOBAL );
    9261
    93                 listner = sched_get_listner(target, SCHED_OP_UWAKEUP);
    94                 event = sched_event_make(target,SCHED_OP_UWAKEUP);
    95    
    96                 if(this->info.isTraced == true)
    97                 {
    98                         printk(INFO,"%s: tid %d --> tid %d [%d][%d]\n",
    99                                __FUNCTION__,
    100                                this->info.order,
    101                                tid,
    102                                cpu_time_stamp(),
    103                                i);
    104                 }
    105 
    106                 sched_event_send(listner,event);
    107                 cpu_wbflush();
    108         }
    109 
    110         return 0;
    111 
    112 fail_target:
    113 fail_tid:
    114 fail_first_tid:
    115 fail_usapce:
    116 fail_tid_tbl:
    117 
    118         printk(INFO, "%s: cpu %d, pid %d, tid %x, i %d, count %d, ttid %x, request has failed with err %d [%d]\n",
    119                __FUNCTION__,
    120                cpu_get_id(),
    121                task->pid,
    122                this,
    123                i,
    124                count,
    125                tid,
    126                err,
    127                cpu_time_stamp());
    128  
    129         this->info.errno = EINVAL;
    130         return -1;
    131 }
     62    return 0;
     63}  // end sys_thread_wakeup()
  • trunk/kernel/syscalls/sys_thread_yield.c

    r1 r23  
    11/*
    2  * kern/sys_thread_yield.c - calls the scheduler to yield current CPU
     2 * sys_thread_yield.c - calls the scheduler to yield
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
     4 * Authors       Ghassan Almaless (2008,2009,2010,2011,2012)
     5 *               Alain Greiner (2016,2017)
     6 *
    57 * Copyright (c) 2011,2012 UPMC Sorbonne Universites
    68 *
    7  * This file is part of ALMOS-kernel.
     9 * This file is part of ALMOS-MKH.
    810 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     11 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1012 * under the terms of the GNU General Public License as published by
    1113 * the Free Software Foundation; version 2.0 of the License.
    1214 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     15 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1416 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1517 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1719 *
    1820 * 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,
     21 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2022 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2123 */
    2224
    23 #include <thread.h>
    2425#include <scheduler.h>
    2526
    2627int sys_thread_yield()
    2728{
    28         return sched_yield(current_thread);
     29        sched_yield();
     30        return 0;
    2931}
  • trunk/kernel/syscalls/sys_trace.c

    r15 r23  
    11/*
    2  * kern/sys_ps.c - show kernel active processes and threads
     2 * sys_trace.c - show kernel active processes and threads
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012,2013,2014,2015 UPMC Sorbonne Universites
     4 * Author    Alain Greiner (c) (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 */
    2223
    23 #include <types.h>
    24 #include <task.h>
    25 #include <pid.h>
     24#include <hal_types.h>
     25#include <hal_special.h>
     26#include <printk.h>
    2627#include <thread.h>
    27 #include <vmm.h>
    2828#include <errno.h>
    29 #include <utils.h>
    30 #include <rpc.h>
    31 #include <cluster.h>
     29#include <syscalls.h>
    3230
    33 extern error_t ps_func(void *param);
     31//////////////////////////////////
     32int sys_trace( uint32_t operation,
     33               pid_t    pid,
     34               uint32_t trdid )
     35{
     36    // get extended pointer on target thread
     37    xptr_t thread_xp = thread_get_xptr( pid , trdid );
    3438
    35 /* TODO: add remote support. */
    36 static error_t sys_ps_check_thread(pid_t pid, uint_t tid, struct thread_s **th_ptr)
    37 {
    38         struct task_s *task;
    39         struct thread_s *thread;
    40         cid_t  location;
     39    if( thread_xp == XPTR_NULL )
     40    {
     41        printk("\n[ERROR] in %s : undefined thread for PID = %x / TRDID = %x\n",
     42               __FUNCTION__ , pid , trdid );
     43        CURRENT_THREAD->errno = EINVAL;
     44        return -1;
     45    }
    4146
    42         if(pid == PID_MIN_LOCAL)
    43                 return EINVAL;
     47    if( operation == TRACE_OFF )
     48    {
     49        // desactivate thread trace TODO
    4450
    45         location = task_whereis(pid);
     51            printk("\n[INFO] %s : trace OFF  for thread %x in process %x\n",
     52               __FUNCTION__ , trdid , pid );
     53    }
     54    else if( operation == TRACE_ON )
     55    {
     56        // activate thread trace TODO
     57                   
     58            printk("\n[INFO] %s : trace ON for thread %x in process %x\n",
     59               __FUNCTION__ , trdid , pid );
     60    }
     61    else
     62    {
     63        printk("\n[ERROR] in %s : undefined operation\n", __FUNCTION__ );
     64        CURRENT_THREAD->errno = EINVAL;
     65        return -1;
     66    }
    4667
    47         tasks_manager_lock();
    48         if ( location == current_cid )
    49         {
    50                 task = task_lookup(pid)->task;
     68    hal_wbflush();
    5169
    52                 if((task == NULL) || (tid > task->max_order))
    53                         return EINVAL;
     70    return 0;
    5471
    55                 thread = task->th_tbl[tid];
    56 
    57                 if((thread == NULL)                 ||
    58                    (thread->signature != THREAD_ID) ||
    59                    (thread->info.attr.key != tid))
    60                 {
    61                         return ESRCH;
    62                 }
    63 
    64                 *th_ptr = thread;
    65                 return 0;
    66         }
    67         else
    68         {
    69                 printk(WARNING, "%s: cluster %u can't execute this function on remote task (pid %u on cluster %u)\n",   \
    70                                 __FUNCTION__, current_cid, pid, location);
    71                 return ENOSYS;
    72         }
    73         tasks_manager_unlock();
    74 }
    75 
    76 /*TODO: use RPC_ARG_NULL instead of sending a useless variable.
    77  * It's not urgent, it's a minor change.
    78  */
    79 RPC_DECLARE(__ps_func,                                  \
    80                 RPC_RET( RPC_RET_PTR(error_t, err) ),   \
    81                 RPC_ARG( RPC_ARG_PTR(error_t, foo) )    \
    82            )
    83 {
    84         *err = ps_func(NULL);
    85 }
    86 
    87 int sys_ps(uint_t cmd, pid_t pid, uint_t tid)
    88 {
    89         cid_t next;
    90         error_t err;
    91         struct thread_s *thread;
    92         struct kernel_iter_s *kernel_iter;
    93 
    94         err = 0;
    95 
    96         switch(cmd)
    97         {
    98         case TASK_PS_TRACE_OFF:
    99                 err = sys_ps_check_thread(pid, tid, &thread);
    100                 if(err) goto fail_trace_off;
    101                 thread->info.isTraced = false;
    102                 cpu_wbflush();
    103                 printk(INFO,"INFO: pid %d, tid %x, tracing is turned [OFF]\n", pid, tid);
    104                 break;
    105 
    106         case TASK_PS_TRACE_ON:
    107                 err = sys_ps_check_thread(pid, tid, &thread);
    108                 if(err) goto fail_trace_on;
    109                 thread->info.isTraced = true;
    110                 cpu_wbflush();
    111                 printk(INFO,"INFO: pid %d, tid %x, tracing is turned [ON]\n", pid, tid);
    112                 break;
    113 
    114         case TASK_PS_SHOW:
    115                 kernel_foreach_backward(kernel_iter, next)
    116                 {
    117                         RCPC( next, RPC_PRIO_PS, __ps_func,
    118                               RPC_RECV( RPC_RECV_OBJ(err) ),
    119                               RPC_SEND( RPC_SEND_OBJ(err) )
    120                            );
    121                 }
    122                 break;
    123         }
    124 
    125 fail_trace_on:
    126 fail_trace_off:
    127         current_thread->info.errno = err;
    128         return err;
    129 }
     72}  // end sys_trace()
  • trunk/kernel/syscalls/sys_undefined.c

    r15 r23  
    11/*
    2  * kern/sys_dma_memcpy.c - exported DMA access to user process
     2 * sys_undefined.c - function executed for an undefined syscall.
    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 */
    2223
    2324#include <errno.h>
    24 #include <types.h>
    25 #include <event.h>
    26 #include <chdev.h>
    27 #include <driver.h>
    28 #include <kmem.h>
    29 #include <kdmsg.h>
    30 #include <dma.h>
    31 #include <kcm.h>
    3225#include <thread.h>
    33 #include <cluster.h>
    34 #include <kcm.h>
     26#include <process.h>
     27#include <printk.h>
    3528
     29///////////////////
     30int sys_undefined()
     31{
     32    thread_t  * this    = CURRENT_THREAD;
     33    process_t * process = this->process;
    3634
    37 KMEM_OBJATTR_INIT(dma_kmem_request_init)
    38 {
    39         attr->type = KMEM_DMA_REQUEST;
    40         attr->name = "KCM Dev-Request";
    41         attr->size = sizeof(dev_request_t);
    42         attr->aligne = 0;
    43         attr->min  = CONFIG_DMA_RQ_KCM_MIN;
    44         attr->max  = CONFIG_DMA_RQ_KCM_MAX;
    45         attr->ctor = NULL;
    46         attr->dtor = NULL;
    47  
    48         return 0;
     35    printk("\n[ERROR] in %s : undefined syscall calle by thread %x in process %x\n",
     36           __FUNCTION__ , this->trdid , process->pid );
     37    this->errno = EINVAL;
     38    return -1;
    4939}
    50 
    51 static EVENT_HANDLER(dma_async_request_event)
    52 {
    53         kmem_req_t req;
    54         error_t err;
    55  
    56         if((err=event_get_error(event)) != 0)
    57                 printk(ERROR, "ERROR: dma_async_request_event: DMA transfare is not well completed, remaining %d\n", err);
    58 
    59         req.type = KMEM_DMA_REQUEST;
    60         req.ptr  = event_get_argument(event);
    61 
    62         assert(req.ptr != NULL && "Corrupted argument, expected the address of request");
    63 
    64         kmem_free(&req);
    65         return 0;
    66 }
    67 
    68 static inline error_t dma_do_async_request(void *dst, void *src, size_t size)
    69 {
    70         kmem_req_t req;
    71         dev_request_t *rq;
    72  
    73         req.type  = KMEM_DMA_REQUEST;
    74         req.size  = sizeof(*rq);
    75         req.flags = AF_KERNEL;
    76 
    77         if((rq = kmem_alloc(&req)) == NULL)
    78                 return ENOMEM;
    79 
    80         memset(rq, 0, sizeof(*rq));
    81 
    82         rq->src   = src;
    83         rq->dst   = dst;
    84         rq->count = size;
    85         rq->flags = DEV_RQ_NOBLOCK;
    86 
    87         event_set_priority(&rq->event, E_FUNC);
    88         event_set_handler(&rq->event, &dma_async_request_event);
    89         event_set_argument(&rq->event, rq);
    90  
    91         return __sys_dma->op.dev.write(__sys_dma, rq);
    92 }
    93 
    94 static inline error_t dma_do_sync_request(void *dst, void *src, size_t size)
    95 {
    96         dev_request_t rq;
    97  
    98         rq.src   = src;
    99         rq.dst   = dst;
    100         rq.count = size;
    101         rq.flags = 0;
    102  
    103         return __sys_dma->op.dev.write(__sys_dma, &rq);
    104 }
    105 
    106 
    107 error_t dma_memcpy(void *dst, void *src, size_t size, uint_t isAsync)
    108 {
    109         if(isAsync == DMA_ASYNC)
    110                 return dma_do_async_request(dst, src, size);
    111         else
    112                 return dma_do_sync_request(dst, src, size);
    113 }
    114 
    115 
    116 int sys_dma_memcpy(void *src, void *dst, size_t size)
    117 {
    118         return dma_do_sync_request(dst, src, size);
    119 }
  • trunk/kernel/syscalls/sys_unlink.c

    r1 r23  
    11/*
    2  * kern/sys_unlink.c - file unlink
     2 * sys_unlink.c - file unlink
    33 *
    44 * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
     
    2121 */
    2222
     23#include <hal_types.h>
     24#include <hal_uspace.h>
    2325#include <vfs.h>
    24 #include <sys-vfs.h>
    25 #include <task.h>
     26#include <process.h>
    2627#include <thread.h>
     28#include <printk.h>
    2729
    28 int sys_unlink (char *pathname)
     30//////////////////////////////////
     31int sys_unlink ( char * pathname )
    2932{
    30         error_t err = 0;
    31         struct ku_obj ku_path;
     33        error_t   error;
     34    uint32_t  length;
     35    char      kbuf[CONFIG_VFS_MAX_PATH_LENGTH];
    3236
    33         KU_BUFF(ku_path, pathname);
    34         if((err = vfs_unlink(&current_task->vfs_cwd, &ku_path)))
     37        thread_t     * this     = CURRENT_THREAD;
     38        process_t    * process  = this->process;
     39
     40    // get pathname length
     41    length = hal_strlen_from_uspace( pathname );
     42
     43    if( length >= CONFIG_VFS_MAX_PATH_LENGTH )
     44    {
     45        printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ );
     46                this->errno = ENFILE;
     47        return -1;
     48    }
     49 
     50        // get pathname copy in kernel space
     51    hal_copy_from_uspace( kbuf, pathname, length );
     52
     53    // get cluster and local pointer on reference process
     54    xptr_t      ref_xp  = process->ref_xp;
     55    process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
     56    cxy_t       ref_cxy = GET_CXY( ref_xp );
     57
     58    // get the cwd lock in read mode from reference process
     59        remote_rwlock_rd_lock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
     60
     61    // get extended pointer on cwd inode
     62    xptr_t cwd_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->vfs_cwd_xp ) );
     63
     64    // call relevant VFS function
     65    error  = vfs_unlink( cwd_xp , kbuf );
     66
     67    // release the cwd lock in reference process
     68        remote_rwlock_rd_unlock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
     69
     70        if( error )
    3571        {
    36                 current_thread->info.errno = (err < 0) ? -err : err;
    37                 return -1;
     72        printk("\n[ERROR] in %s : cannot unlink file/dir %s\n",
     73               __FUNCTION__ , pathname );
     74                this->errno = ENFILE;
     75            return -1;
    3876        }
    39  
     77
    4078        return 0;
    41 }
     79
     80} // end sys_unlink()
  • trunk/kernel/syscalls/sys_utls.c

    r1 r23  
    22 * kern/sys_utls.c - User Thread Local Storage
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * Author    Ghassan Almaless (2008,2009,2010,2011,2012)
     5 *           Alain Greiner (2016,2017)
    66 *
    7  * This file is part of ALMOS-kernel.
     7 * Copyright (c) UPMC Sorbonne Universites
    88 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     9 * This file is part of ALMOS-MKH.
     10 *
     11 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1012 * under the terms of the GNU General Public License as published by
    1113 * the Free Software Foundation; version 2.0 of the License.
    1214 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     15 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1416 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1517 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1719 *
    1820 * 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,
     21 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2022 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2123 */
    2224
    23 #include <types.h>
     25#include <hal_types.h>
    2426#include <errno.h>
    2527#include <thread.h>
    26 #include <kmem.h>
    27 #include <kmagics.h>
    28 #include <semaphore.h>
     28#include <printk.h>
     29#include <syscalls.h>
    2930
    30 #define UTLS_SET       1
    31 #define UTLS_GET       2
    32 #define UTLS_GET_ERRNO 3
    33 
    34 int sys_utls(uint_t operation, uint_t value)
     31/////////////////////////////////
     32int sys_utls( uint32_t operation,
     33              uint32_t value )
    3534{
    36         struct thread_s *this = current_thread;
     35    thread_t * this = CURRENT_THREAD;
    3736 
    3837        switch(operation)
    3938        {
    40         case UTLS_SET:
    41                 this->info.usr_tls = value;
     39            case UTLS_SET:
     40                this->utls = value;
    4241                return 0;
    4342
    44         case UTLS_GET:
    45                 return this->info.usr_tls;
     43            case UTLS_GET:
     44                return this->utls;
    4645
    47         case UTLS_GET_ERRNO:
    48                 return this->info.errno;
     46            case UTLS_GET_ERRNO:
     47                return this->errno;
    4948
    50         default:
    51                 this->info.errno = EINVAL;
     49            default:
     50        printk("\n[ERROR] in %s : illegal utls operation\n", __FUNCTION__ );
     51                this->errno = EINVAL;
    5252                return -1;
    5353        }
    54 }
     54
     55}  // end sys_utls()
  • trunk/kernel/syscalls/sys_write.c

    r1 r23  
    11/*
    2  * kern/sys_write.c - write bytes to a file
     2 * sys_write.c - write bytes to a file
    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 */
    2223
     24#include <kernel_config.h>
     25#include <hal_types.h>
     26#include <hal_uspace.h>
     27#include <hal_special.h>
    2328#include <errno.h>
    24 #include <thread.h>
    2529#include <vfs.h>
    2630#include <thread.h>
    27 #include <sys-vfs.h>
    28 #include <task.h>
     31#include <printk.h>
     32#include <process.h>
    2933
    30 int sys_write (uint_t fd, void *buf, size_t count)
     34/* TODO: user page(s) need to be locked  [AG] */
     35
     36//////////////////////////////////
     37int sys_write( uint32_t   file_id,
     38               void     * buf,
     39               uint32_t   count )
    3140{
    32         ssize_t err = 0;
    33         struct thread_s *this;
    34         struct task_s *task;
    35         struct vfs_file_s *file;
    36         struct ku_obj kub;
     41    error_t      error;
     42    paddr_t      paddr;
     43    char         kbuf[CONFIG_VFS_KBUF_SIZE];
     44        xptr_t       file_xp;                       // remote file extended pointer
     45    uint32_t     nbytes;                        // number of bytes in one iteration
    3746
    38         file = NULL;
    39         this = current_thread;
    40         task = current_task;
     47        thread_t   * this = CURRENT_THREAD;
     48        process_t  * process = this->process;
    4149 
    42         if((fd >= CONFIG_TASK_FILE_MAX_NR) || (task_fd_lookup(task, fd, &file)))
     50    // check file_id argument
     51        if( file_id >= CONFIG_PROCESS_FILE_MAX_NR )
    4352        {
    44                 this->info.errno = EBADFD;
     53        printk("\n[ERROR] in %s : illegal file descriptor index\n", __FUNCTION__ );
     54        this->errno = EBADFD;
    4555                return -1;
    4656        }
    4757
    48         KU_SLICE_BUFF(kub, buf, count);
    49         if((err = vfs_write(file, &kub)) < 0)
     58    // check user buffer in user space
     59    error = vmm_v2p_translate( false , buf , &paddr );
     60
     61    if ( error )
     62    {
     63        printk("\n[ERROR] in %s : user buffer unmapped = %x\n",
     64               __FUNCTION__ , (intptr_t)buf );
     65                this->errno = EINVAL;
     66                return -1;
     67    }
     68
     69    // get extended pointer on remote file descriptor
     70    file_xp = process_fd_get_xptr( process , file_id );
     71
     72    if( file_xp == XPTR_NULL )
     73    {
     74        printk("\n[ERROR] in %s : undefined file descriptor index = %d\n",
     75               __FUNCTION__ , file_id );
     76                this->errno = EBADFD;
     77                return -1;
     78    }
     79
     80    // get file descriptor cluster and local pointer
     81    vfs_file_t * file_ptr = (vfs_file_t *)GET_PTR( file_xp );
     82    cxy_t        file_cxy = GET_CXY( file_xp );
     83
     84    // check file writable
     85    uint32_t attr = hal_remote_lw( XPTR( file_cxy , &file_ptr->attr ) );
     86    if( (attr & FD_ATTR_WRITE_ENABLE) == 0 )
    5087        {
    51                 this->info.errno = (err < 0) ? -err : err;
     88        printk("\n[ERROR] in %s : file %d not writable\n",
     89               __FUNCTION__ , file_id );
     90                this->errno = EBADFD;
    5291                return -1;
    5392        }
    5493   
    55         return err;
    56 }
     94    // transfer at most CONFIG_VFS_KBUF_SIZE bytes per iteration
     95    while( count )
     96    {
     97        if( count <= CONFIG_VFS_KBUF_SIZE )
     98        {
     99            nbytes = count;
     100            count  = 0;
     101        }
     102        else
     103        {
     104            nbytes = CONFIG_VFS_KBUF_SIZE;
     105            count  = count - CONFIG_VFS_KBUF_SIZE;
     106        }
     107
     108        // copy user buffer to kernel buffer
     109        hal_copy_to_uspace( buf , kbuf , nbytes );
     110
     111        // transfer nbytes from kernel buffer
     112        error = vfs_move( false,               // write => (to_buffer = false)
     113                          file_xp,
     114                          kbuf ,
     115                          nbytes );
     116
     117        if( error )
     118        {
     119            printk("\n[ERROR] in %s cannot read data from file %d\n",
     120                   __FUNCTION__ , file_id );
     121            this->errno = error;
     122            return -1;
     123        }
     124    }
     125
     126    hal_wbflush();
     127
     128        return 0;
     129
     130}  // end sys_write()
  • trunk/kernel/syscalls/syscalls.h

    r16 r23  
    22 * syscalls.h - kernel services definition
    33 *
    4  * Author  Ghassan Almaless (2007,2008,2009,2010,2011,2012)
    5  *         Alain Greiner    (2016)
     4 * Author     Alain Greiner (2016,2017)
    65 *
    76 * Copyright (c) UPMC Sorbonne Universites
     
    2625#define _SYSCALLS_H_
    2726
     27#include <hal_types.h>
     28#include <time.h>
     29
     30/*****   Forward declarations  *****/
     31
     32struct thread_s;                  // defined in thread.h
     33struct pthread_attr_s;            // defined in thread.h
     34struct vfs_stat_s;                // defined in vfs.h
     35struct vfs_dirent_s;              // defined in vfs.h
     36struct mmap_attr_s;               // defined in vmm.h
     37
    2838/******************************************************************************************
    2939 * This enum defines the mnemonics for the syscall indexes.
     
    3242enum
    3343{
    34         SYS_EXIT,          /* 0  */
    35         SYS_MMAP,          /* 1  */
    36         SYS_CREATE,        /* 2  */
    37         SYS_JOIN,          /* 3  */
    38         SYS_DETACH,        /* 4  */
    39         SYS_YIELD,         /* 5  */
    40         SYS_SEMAPHORE,     /* 6  */
    41         SYS_COND_VAR,      /* 7  */
    42         SYS_BARRIER,       /* 8  */
    43         SYS_RWLOCK,        /* 9  */
    44         SYS_SLEEP,         /* 10 */
    45         SYS_WAKEUP,        /* 11 */
    46         SYS_OPEN,          /* 12 */
    47         SYS_CREAT,         /* 13 */
    48         SYS_READ,          /* 14 */
    49         SYS_WRITE,         /* 15 */
    50         SYS_LSEEK,         /* 16 */
    51         SYS_CLOSE,         /* 17 */
    52         SYS_UNLINK,        /* 18 */   
    53         SYS_PIPE,          /* 19 */
    54         SYS_CHDIR,         /* 20 */
    55         SYS_MKDIR,         /* 21 */
    56         SYS_MKFIFO,        /* 22 */   
    57         SYS_OPENDIR,       /* 23 */
    58         SYS_READDIR,       /* 24 */
    59         SYS_CLOSEDIR,      /* 25 */
    60         SYS_GETCWD,        /* 26 */
    61         SYS_CLOCK,         /* 27 */
    62         SYS_ALARM,         /* 28 */   
    63         SYS_DMA_MEMCPY,    /* 29 */
    64         SYS_UTLS,          /* 30 */ 
    65         SYS_SIGRETURN,     /* 31 */
    66         SYS_SIGNAL,        /* 32 */
    67         SYS_SET_SIGRETURN, /* 33 */
    68         SYS_KILL,          /* 34 */
    69         SYS_GETPID,        /* 35 */
    70         SYS_FORK,          /* 36 */
    71         SYS_EXEC,          /* 37 */
    72         SYS_GETATTR,       /* 38 */     
    73         SYS_PS,            /* 39 */
    74         SYS_MADVISE,       /* 40 */   
    75         SYS_PAGEINFO,      /* 41 */
    76         SYS_STAT,          /* 42 */
    77         SYS_MIGRATE,       /* 43 */
    78         SYS_SBRK,          /* 44 */
    79         SYS_RMDIR,         /* 45 */
    80         SYS_FTIME,         /* 46 */
    81         SYS_CHMOD,         /* 47 */
    82         SYS_FSYNC,         /* 48 */
    83         SYS_GET_TOD,       /* 49 */
    84         SYS_TIMES,         /* 50 */
    85         SYSCALLS_NR,
     44        SYS_THREAD_EXIT    = 0,
     45        SYS_MMAP           = 1,
     46        SYS_THREAD_CREATE  = 2,
     47        SYS_THREAD_JOIN    = 3,
     48        SYS_THREAD_DETACH  = 4,
     49        SYS_THREAD_YIELD   = 5,
     50        SYS_SEM            = 6,
     51        SYS_CONDVAR        = 7,
     52        SYS_BARRIER        = 8,
     53        SYS_MUTEX          = 9,
     54
     55        SYS_SLEEP          = 10,
     56        SYS_WAKEUP         = 11,
     57        SYS_OPEN           = 12,
     58        SYS_CREAT          = 13,
     59        SYS_READ           = 14,
     60        SYS_WRITE          = 15,
     61        SYS_LSEEK          = 16,
     62        SYS_CLOSE          = 17,
     63        SYS_UNLINK         = 18,   
     64        SYS_PIPE           = 19,
     65
     66        SYS_CHDIR          = 20,
     67        SYS_MKDIR          = 21,
     68        SYS_MKFIFO         = 22,   
     69        SYS_OPENDIR        = 23,
     70        SYS_READDIR        = 24,
     71        SYS_CLOSEDIR       = 25,
     72        SYS_GETCWD         = 26,
     73        SYS_CLOCK          = 27,
     74        SYS_ALARM          = 28,   
     75        SYS_RMDIR          = 29,
     76
     77        SYS_UTLS           = 30, 
     78        SYS_CHMOD          = 31,
     79        SYS_SIGNAL         = 32,
     80        SYS_TIMEOFDAY      = 33,
     81        SYS_KILL           = 34,
     82        SYS_GETPID         = 35,
     83        SYS_FORK           = 36,
     84        SYS_EXEC           = 37,
     85        SYS_STAT           = 38,     
     86        SYS_TRACE          = 39,
     87       
     88        SYSCALLS_NR        = 40,
    8689};
    8790
     91
    8892/********************************************************************************************/
    89 /********************   Process related system calls  ***************************************/
     93/********************    system calls    ****************************************************/
    9094/********************************************************************************************/
    9195
    92 
    93 /*********************************************************************************************
    94  * [0] This function TODO
    95  ********************************************************************************************/
    96 int sys_thread_exit( void * );
    97 
    98 /*********************************************************************************************
    99  * [1] This function TODO
    100  ********************************************************************************************/
    101 int sys_mmap();
    102 
    103 /*********************************************************************************************
    104  * [2] This function TODO
    105  ********************************************************************************************/
    106 int sys_thread_create();
    107 
    108 /*********************************************************************************************
    109  * [3] This function TODO
    110  ********************************************************************************************/
    111 int sys_thread_join();
    112 
    113 /*********************************************************************************************
    114  * [4] This function TODO
    115  ********************************************************************************************/
    116 int sys_thread_detach();
    117 
    118 /*********************************************************************************************
    119  * [5] This function TODO
     96/*********************************************************************************************
     97 * [0] This function terminates the execution of the calling user thread value,
     98 * and makes the exit_value pointer available to any successful pthread_join() with the
     99 * terminating thread.
     100 *********************************************************************************************
     101 * @ exit_vallue  : [out] pointer to to the parrent thread if attached.
     102 * @ return 0 if success / return -1 if failure.
     103 ********************************************************************************************/
     104int sys_thread_exit( void * exit_value );
     105
     106/*********************************************************************************************
     107 * [1] This function map physical memory (or a file) in the calling thread virtual space.
     108 * The <attr> argument is a pointer on a structure containing arguments, defined in vmm.h.
     109 * TODO not implemented yet...
     110 *********************************************************************************************
     111 * @ attr       : pointer on attributes structure.
     112 * @ return 0 if success / return -1 if failure.
     113 ********************************************************************************************/
     114int sys_mmap( struct mmap_attr_s * attr );
     115
     116/*********************************************************************************************
     117 * [2] This function creates a new user thread. The <user_attr> argument is a pointer
     118 * on astructure containing the thread attributes, defined in thread.h file.
     119 *********************************************************************************************
     120 * @ new_thread  : [out] local pointer on created thread descriptor.
     121 * @ user_attr   : [in]  pointer on thread attributes structure.
     122 * @ start_func  : [in]  pointer on start function.
     123 * @ start_args  : [in]  pointer on start function arguments.
     124 * @ return 0 if success / return -1 if failure.
     125 ********************************************************************************************/
     126int sys_thread_create( struct thread_s        * new_thread,
     127                       struct pthread_attr_s  * user_attr,
     128                       void                   * start_func,
     129                       void                   * start_args );
     130
     131/*********************************************************************************************
     132 * [3] This blocking function suspend execution of the calling thread until completion
     133 * of another target thread identified by the <trdid> argument.
     134 * If the <exit_value> argument is not NULL, the value passed to pthread_exit() by the
     135 * target thread is stored in the location referenced by exit_value.
     136 *********************************************************************************************
     137 * @ trdid     : [in]  target thread identifier.
     138 * @ thread    : [out] buffer for exit_value returned by target thread.
     139 * @ return 0 if success / return -1 if failure.
     140 ********************************************************************************************/
     141int sys_thread_join( trdid_t    trdid,
     142                     void    ** exit_value );
     143
     144/*********************************************************************************************
     145 * [4] This function detach a joinable thread.
     146 *********************************************************************************************
     147 * @ trdid   : thread identifier.
     148 * @ return 0 if success / return -1 if failure.
     149 ********************************************************************************************/
     150int sys_thread_detach( trdid_t  trdid );
     151
     152/*********************************************************************************************
     153 * [5] This function calls the scheduler for the core running the calling thread.
     154 *********************************************************************************************
     155 * @ return always 0.
    120156 ********************************************************************************************/
    121157int sys_thread_yield();
    122158
    123159/*********************************************************************************************
    124  * [6] This function TODO
    125  ********************************************************************************************/
    126 int sys_sem();
    127 
    128 /*********************************************************************************************
    129  * [7] This function TODO
    130  ********************************************************************************************/
    131 int sys_cond_var();
    132 
    133 /*********************************************************************************************
    134  * [8] This function TODO
    135  ********************************************************************************************/
    136 int sys_barrier();
    137 
    138 /*********************************************************************************************
    139  * [9] This function TODO
    140  ********************************************************************************************/
    141 int sys_rwlock();
    142 
    143 /*********************************************************************************************
    144  * [10] This function TODO
     160 * [6] This function implement all operations on a POSIX unnamed semaphore,
     161 * that can be shared by threads running in different clusters.
     162 * The kernel structure representing a remote semaphore is in the remote_sem.h file,
     163 * and the code implementing the operations is in the remore_sem.c file.
     164 *********************************************************************************************
     165 * @ vaddr     : semaphore virtual address in user space == identifier.
     166 * @ operation : SEM_INIT / SEM_DESTROY / SEM_GETVALUE / SEM_POST / SEM_WAIT.
     167 * @ value     : pointer on in/out argument in user space.
     168 * @ return 0 if success / return -1 if failure.
     169 ********************************************************************************************/
     170int sys_sem( void       * vaddr,
     171             uint32_t     operation,
     172             uint32_t   * value );
     173
     174typedef enum
     175{
     176        SEM_INIT,
     177        SEM_DESTROY,
     178        SEM_GETVALUE,
     179        SEM_WAIT,
     180        SEM_POST,
     181}
     182sem_operation_t;
     183
     184/*********************************************************************************************
     185 * [7] This function implement all operations on a POSIX condition variable.
     186 * The kernel structure representing a cond_var is defined in the remote_cv.h file,
     187 * The code implementing the operations is defined in the remote_cv.c file.
     188 *********************************************************************************************
     189 * @ vaddr     : condvar virtual address in user space == identifier.
     190 * @ operation : operation type (see below).
     191 * @ attr      : mutex virtual address in user space == identifier.
     192 * @ return 0 if success / return -1 if failure.
     193 ********************************************************************************************/
     194int sys_condvar( void     * condvar,
     195                 uint32_t   operation,
     196                 void     * mutex );
     197
     198typedef enum
     199{
     200        CONDVAR_INIT,
     201        CONDVAR_DESTROY,
     202    CONDVAR_WAIT,
     203    CONDVAR_SIGNAL,
     204    CONDVAR_BROADCAST,
     205}
     206condvar_operation_t;
     207
     208/*********************************************************************************************
     209 * [8] This function implement all operations on a POSIX barrier.
     210 * The kernel structure representing a barrier is defined in the remote_barrier.h file.
     211 * The code implementting the operations is defined in the remote_barrier.c file.
     212 *********************************************************************************************
     213 * @ vaddr     : barrier virtual address in user space == identifier.
     214 * @ operation : BARRIER_INIT / BARRIER_DESTROY / BARRIER_WAIT.
     215 * @ count     : number of expected threads (only used by BARRIER_INIT operation).
     216 * @ return 0 if success / return -1 if failure.
     217 ********************************************************************************************/
     218int sys_barrier( void     * vaddr,
     219                 uint32_t   operation,
     220                 uint32_t   count );
     221
     222typedef enum
     223{
     224        BARRIER_INIT,
     225        BARRIER_DESTROY,
     226        BARRIER_WAIT,
     227}
     228barrier_operation_t;
     229
     230/*********************************************************************************************
     231 * [9] This function implement all operations on a POSIX mutex.
     232 * The kernel structure representing a barrier is defined in the remote_barrier.h file.
     233 * The code implementting the operations is defined in the remote_barrier.c file.
     234 *********************************************************************************************
     235 * @ vaddr     : mutex virtual address in user space == identifier.
     236 * @ operation : MUTEX_INIT / MUTEX_DESTROY / MUTEX_LOCK / MUTEX_UNLOCK
     237 * @ attr      : mutex attributes (non supported yet => must be 0).
     238 * @ return 0 if success / return -1 if failure.
     239 ********************************************************************************************/
     240int sys_mutex( void     * vaddr,
     241               uint32_t   operation,
     242               uint32_t   count );
     243
     244typedef enum
     245{
     246        MUTEX_INIT,
     247        MUTEX_DESTROY,
     248        MUTEX_LOCK,
     249        MUTEX_UNLOCK,
     250}
     251mutex_operation_t;
     252
     253/*********************************************************************************************
     254 * [10] This function block the calling thread on the THREAD_BLOCKED_GLOBAL condition,
     255 * and deschedule.
     256 *********************************************************************************************
     257 * @ return 0 if success / returns -1 if failure.
    145258 ********************************************************************************************/
    146259int sys_thread_sleep();
    147260
    148261/*********************************************************************************************
    149  * [11] This function TODO
     262 * [11] This function unblock the thread identified by its <trdid> from the
     263 * THREAD_BLOCKED_GLOBAL condition.
     264 *********************************************************************************************
     265 * @ trdid  : target thread identifier.
     266 * @ return 0 if success / return -1 if failure.
    150267 ********************************************************************************************/
    151268int sys_thread_wakeup();
    152269
    153270/*********************************************************************************************
    154  * [12] This function TODO
    155  ********************************************************************************************/
    156 int sys_open();
    157 
    158 /*********************************************************************************************
    159  * [13] This function TODO
    160  ********************************************************************************************/
    161 int sys_creat();
    162 
    163 /*********************************************************************************************
    164  * [14] This function TODO
    165  ********************************************************************************************/
    166 int sys_read();
    167 
    168 /*********************************************************************************************
    169  * [15] This function TODO
    170  ********************************************************************************************/
    171 int sys_write();
    172 
    173 /*********************************************************************************************
    174  * [16] This function TODO
    175  ********************************************************************************************/
    176 int sys_lseek();
    177 
    178 /*********************************************************************************************
    179  * [17] This function TODO
    180  ********************************************************************************************/
    181 int sys_close();
    182 
    183 /*********************************************************************************************
    184  * [18] This function TODO
    185  ********************************************************************************************/
    186 int sys_unlink();
    187 
    188 /*********************************************************************************************
    189  * [19] This function TODO
    190  ********************************************************************************************/
    191 int sys_pipe();
    192 
    193 /*********************************************************************************************
    194  * [20] This function TODO
    195  ********************************************************************************************/
    196 int sys_chdir();
    197 
    198 /*********************************************************************************************
    199  * [21] This function TODO
    200  ********************************************************************************************/
    201 int sys_mkdir();
    202 
    203 /*********************************************************************************************
    204  * [22] This function TODO
    205  ********************************************************************************************/
    206 int sys_mkfifo();
    207 
    208 /*********************************************************************************************
    209  * [23] This function TODO
    210  ********************************************************************************************/
    211 int sys_opendir();
    212 
    213 /*********************************************************************************************
    214  * [24] This function TODO
    215  ********************************************************************************************/
    216 int sys_readdir();
    217 
    218 /*********************************************************************************************
    219  * [25] This function TODO
    220  ********************************************************************************************/
    221 int sys_closedir();
    222 
    223 /*********************************************************************************************
    224  * [26] This function TODO
    225  ********************************************************************************************/
    226 int sys_getcwd();
    227 
    228 /*********************************************************************************************
    229  * [27] This function TODO
    230  ********************************************************************************************/
    231 int sys_clock();
    232 
    233 /*********************************************************************************************
    234  * [28] This function TODO
    235  ********************************************************************************************/
    236 int sys_alarm();
    237 
    238 /*********************************************************************************************
    239  * [29] This function TODO
    240  ********************************************************************************************/
    241 int sys_dma_memcpy();
    242 
    243 /*********************************************************************************************
    244  * [30] This function TODO
    245  ********************************************************************************************/
    246 int sys_utls();
    247 
    248 /*********************************************************************************************
    249  * [31] This function TODO
    250  ********************************************************************************************/
    251 int sys_notAvailable();
    252 
    253 /*********************************************************************************************
    254  * [32] This function TODO
    255  ********************************************************************************************/
    256 int sys_signal();
    257 
    258 /*********************************************************************************************
    259  * [33] This function TODO
    260  ********************************************************************************************/
    261 int sys_sigreturn_setup();
     271 * [12] This function open or create a file.
     272 *********************************************************************************************
     273 * @ pathname   : pathname (can be relative or absolute).
     274 * @ flags      : bit vector attributes (see below).
     275 * @ mode       : access rights.
     276 * @ return file descriptor index in fd_array if success / return -1 if failure.
     277 ********************************************************************************************/
     278int sys_open( char    * pathname,
     279              uint32_t  flags,
     280              uint32_t  mode );
     281
     282typedef enum
     283{
     284    O_RDONLY   = 0x0010000,    /*! open file in read-only mode                              */
     285    O_WRONLY   = 0x0020000,    /*! open file in write-only mode                             */
     286    O_RDWR     = 0x0030000,    /*! open file in read/write mode                             */
     287    O_NONBLOCK = 0x0040000,    /*! do not block if data non available                       */
     288    O_APPEND   = 0x0080000,    /*! append on each write                                     */
     289    O_CREAT    = 0x0100000,    /*! create file if it does not exist                         */
     290    O_TRUNC    = 0x0200000,    /*! file length is forced to 0                               */
     291    O_EXCL     = 0x0400000,    /*! error if VFS_O_CREAT and file exist                      */
     292    O_SYNC         = 0x0800000,    /*! synchronize File System on each write                    */
     293    O_CLOEXEC  = 0x1000000,    /*! set the close-on-exec flag in file descriptor            */
     294    O_DIR      = 0x2000000,    /*! new file descriptor is for a directory                   */
     295}
     296open_attributes_t;
     297
     298/*********************************************************************************************
     299 * [13] This function creates a new file as specified by the arguments.
     300 * This function is obsolete, you should use open() with 0_CREATE.
     301 *********************************************************************************************
     302 * @ pathname   : pathname (can be relative or absolute).
     303 * @ mode       : access rights.
     304 ********************************************************************************************/
     305int sys_creat( char     * pathname,
     306               uint32_t   mode );
     307
     308/*********************************************************************************************
     309 * [14] This function read bytes from an open file identified by its file descriptor.
     310 * This file can be a regular file or character oriented device.
     311 *********************************************************************************************
     312 * @ file_id  : open file index in fd_array.
     313 * @ buf      : buffer virtual address in user space.
     314 * @ count    : number of bytes.
     315 * @ return number of bytes actually read if success / returns -1 if failure.
     316 ********************************************************************************************/
     317int sys_read( uint32_t   file_id,
     318              void     * buf,
     319              uint32_t   count );
     320
     321/*********************************************************************************************
     322 * [15] This function writes bytes to an open file identified by its file descriptor.
     323 * This file can be a regular file or character oriented device.
     324 *********************************************************************************************
     325 * @ file_id  : open file index in fd_array.
     326 * @ buf      : buffer virtual address in user space.
     327 * @ count    : number of bytes.
     328 * @ return number of bytes actually written if success / returns -1 if failure.
     329 ********************************************************************************************/
     330int sys_write( uint32_t   file_id,
     331               void     * buf,
     332               uint32_t   count );
     333
     334/*********************************************************************************************
     335 * [16] This function epositions the offset of the file descriptor identified by <file_id>,
     336 * according to the operation type defined by the <whence> and <offset> arguments.
     337 *********************************************************************************************
     338 * @ file_id  : open file index in fd_array.
     339 * @ offset   : buffer virtual address in user space.
     340 * @ whence   : operation type (see below).
     341 * @ return 0 if success / returns -1 if failure.
     342 ********************************************************************************************/
     343int sys_lseek( xptr_t    file_id,
     344               uint32_t  offset,
     345               uint32_t  whence );
     346
     347typedef enum
     348{
     349    SEEK_SET  = 0,     /*! new_offset <= offset                                             */
     350    SEEK_CUR  = 1,     /*! new_offset <= current_offset + offset                            */
     351    SEEK_END  = 2,     /*! new_iffset <= current_size + offset                              */
     352}
     353lseek_operation_t;
     354
     355/*********************************************************************************************
     356 * [17] This function release the memory allocated for the file descriptor identified by
     357 * the <file_id> argument, and remove the fd array_entry in all copies of the process
     358 * descriptor.
     359 *********************************************************************************************
     360  file_id   : file descriptor index in fd_array.
     361 * @ return 0 if success / returns -1 if failure.
     362 ********************************************************************************************/
     363int sys_close( uint32_t file_id );
     364
     365/*********************************************************************************************
     366 * [18] This function removes a directory entry identified by the <pathname> from its
     367 * directory, and decrement the link count of the file referenced by the link.
     368 * If the link count reduces to zero, and no process has the file open, then all resources
     369 * associated with the file are reclaimed.  If one or more process have the file open when
     370 * the last link is removed, the link is removed, but the removal of the file is delayed
     371 * until all references to it have been closed.
     372 *********************************************************************************************
     373 * @ pathname   : pathname (can be relative or absolute).
     374 * @ return 0 if success / returns -1 if failure.
     375 ********************************************************************************************/
     376int sys_unlink( char * pathname );
     377
     378/*********************************************************************************************
     379 * [19] This function creates in the calling thread cluster an unnamed pipe, and two
     380 * (read and write) file descriptors.
     381 *********************************************************************************************
     382 * @ file_id[0] : [out] read only file descriptor index.
     383 * @ file_id[1] : [out] write only file descriptor index.
     384 * @ return 0 if success / return -1 if failure.
     385 ********************************************************************************************/
     386int sys_pipe( uint32_t file_id[2] );
     387
     388/*********************************************************************************************
     389 * [20] This function change the current working directory in reference process descriptor.
     390 *********************************************************************************************
     391 * @ pathname   : pathname (can be relative or absolute).
     392 * @ return 0 if success / returns -1 if failure.
     393 ********************************************************************************************/
     394int sys_chdir( char * pathname );
     395
     396/*********************************************************************************************
     397 * [21] This function creates a new directory in file system.
     398 *********************************************************************************************
     399 * @ pathname   : pathname (can be relative or absolute).
     400 * @ mode       : access rights (as defined in chmod).
     401 * @ return 0 if success / returns -1 if failure.
     402 ********************************************************************************************/
     403int sys_mkdir( char      pathname,
     404               uint32_t  mode );
     405
     406/*********************************************************************************************
     407 * [22] This function creates a named FIFO file in the calling thread cluster.
     408 * The associated read and write file descriptors mut be be  explicitely created
     409 * using the sy_open() function.
     410 *********************************************************************************************
     411 * @ pathname   : pathname (can be relative or absolute).
     412 * @ mode       : access rights (as defined in chmod).
     413 * @ return 0 if success / returns -1 if failure.
     414 ********************************************************************************************/
     415int sys_mkfifo( char     * pathname,
     416                uint32_t   mode );
     417
     418/*********************************************************************************************
     419 * [23] This function open a directory, that must exist in the file system.
     420 *********************************************************************************************
     421 * @ pathname   : pathname (can be relative or absolute).
     422 * @ return file descriptor index in fd_array if success / return -1 if failure.
     423 ********************************************************************************************/
     424int sys_opendir( char * pathname );
     425
     426/*********************************************************************************************
     427 * [24] This function returns in the structure pointed by the <dirent> argument various
     428 * information about an entry of the directory identified by the <file_id> argument.
     429 *********************************************************************************************
     430 * @ file_id   : file descriptor index of the searched directory.
     431 * @ dirent    : pointer on a dirent structure in user space.
     432 * @ return 0 if success / returns -1 if failure.
     433 ********************************************************************************************/
     434int sys_readdir( uint32_t              file_id,
     435                 struct vfs_dirent_s * dirent );
     436
     437/*********************************************************************************************
     438 * [25] This function close the file descriptor previouly open by the opendir() function.
     439 *********************************************************************************************
     440 * @ file_id   : file descriptor index of the searched directory.
     441 * @ return 0 if success / returns -1 if failure.
     442 ********************************************************************************************/
     443int sys_closedir( uint32_t file_id );
     444
     445/*********************************************************************************************
     446 * [26] This function returns the pathname of the current working directory.
     447 *********************************************************************************************
     448 * buf     : buffer addres in user space.
     449 * nbytes  : user buffer size in bytes.
     450 * @ return 0 if success / returns -1 if failure.
     451 ********************************************************************************************/
     452int sys_getcwd( char     * buf,
     453                uint32_t   nbytes );
     454
     455/*********************************************************************************************
     456 * [27] This function returns in a 64 bits user buffer the calling core cycles count.
     457 * It uses both the hardware register and the core descriptor cycles count tos take
     458 * into account a possible harware register overflow  in 32 bits architectures.
     459 *********************************************************************************************
     460 * cyles    : [out] address of buffer in user space.
     461 ********************************************************************************************/
     462int sys_clock( uint64_t * cycles );
     463
     464/*********************************************************************************************
     465 * [28] This function forces the calling thread to sleep, for a fixed number of cycles.
     466 *********************************************************************************************
     467 * cycles   : number of cycles.
     468 ********************************************************************************************/
     469int sys_alarm( uint32_t cycles );
     470
     471/*********************************************************************************************
     472 * [29] This undefined function does nothing.
     473 *********************************************************************************************
     474 * @ pathname   : pathname (can be relative or absolute).
     475 * @ return 0 if success / returns -1 if failure.
     476 ********************************************************************************************/
     477int sys_rmdir( char * pathname );
     478
     479/*********************************************************************************************
     480 * [30] This function implement the operations related to User Thread Local Storage.
     481 * It is actually implemented as an uint32_t variable in the thread descriptor.
     482 *********************************************************************************************
     483 * @ operation  : UTLS operation type as defined below.
     484 * @ value      : argument value for the UTLS_SET operation.
     485 * @ return value for the UTLS_GET and UTLS_GET_ERRNO / return -1 if failure.
     486 ********************************************************************************************/
     487int sys_utls( uint32_t operation,
     488              uint32_t value );
     489
     490typedef enum
     491{
     492    UTLS_SET       = 1,
     493    UTLS_GET       = 2,
     494    UTLS_GET_ERRNO = 3,
     495}
     496utls_operation_t;
     497
     498/*********************************************************************************************
     499 * [31] This function change the acces rights for the file/dir identified by the
     500 * pathname argument.
     501 *********************************************************************************************
     502 * @ pathname   : pathname (can be relative or absolute).
     503 * @ rights     : acces rights.
     504 * @ return 0 if success / returns -1 if failure.
     505 ********************************************************************************************/
     506int sys_chmod( char     * pathname,
     507               uint32_t   rights );
     508
     509/*********************************************************************************************
     510 * [32] This function associate a specific signal handler to a given signal type.
     511 * Tee handlers for the SIGKILL and SIGSTOP signals cannot be redefined.
     512 *********************************************************************************************
     513 * @ sig_id    : index defining signal type (from 1 to 31).
     514 * @ handler   : pointer on fonction implementing the specific handler.
     515 * @ return 0 if success / returns -1 if failure.
     516 ********************************************************************************************/
     517int sys_signal( uint32_t   sig_id,
     518                void     * handler );
     519
     520/*********************************************************************************************
     521 * [33] This function returns in the structure <tv>, defined in the time.h file,
     522 * the current time (in seconds & micro-seconds).
     523 * It is computed from the calling core descriptor.
     524 * The timezone is not supported.
     525 *********************************************************************************************
     526 * @ tv      : pointer on the timeval structure.
     527 * @ tz      : pointer on the timezone structure : must be NULL.       
     528 * @ return 0 if success / returns -1 if failure.
     529 ********************************************************************************************/
     530int sys_gettimeofday( struct timeval  * tv,
     531                      struct timezone * tz );
    262532
    263533/*********************************************************************************************
    264534 * [34] This function implements the "kill" system call.
    265  * It register the signal identified by the <sig> argument in all thread descriptors
    266  * of process identified by the <pid> argument.
     535 * It register the signal defined by the <sig_id> argument in all thread descriptors
     536 * of a target process identified by the <pid> argument. This is done in all clusters
     537 * containing threads for the target process.
     538 * It can be executed by any thread running in any cluster, as this function uses
     539 * remote access to traverse the list of process copies in the owner cluster,
     540 * and the RPC_SIGNAL_RISE to signal the remote threads.
    267541 *********************************************************************************************
    268542 * @ pid      : target process identifier.
    269  * @ sig      : signal index.
     543 * @ sig_id   : index defining the signal type (from 1 to 31).
     544 * @ return 0 if success / returns -1 if failure.
    270545 ********************************************************************************************/
    271546int sys_kill( pid_t    pid,
    272               uint32_t sig );
    273 
    274 /*********************************************************************************************
    275  * [35] This function TODO
     547              uint32_t sig_id );
     548
     549/*********************************************************************************************
     550 * [35] This function implements the "getpid" system call.
     551 *********************************************************************************************
     552 * @ returns the PID for the calling thread.
    276553 ********************************************************************************************/
    277554int sys_getpid();
     
    281558 * The calling process descriptor (parent process), and the associated thread descriptor are
    282559 * replicated in the same cluster as the calling thread, but the new process (child process)
    283  * is registered in another target cluster, that will become the process owner.
     560 * is registered in another target cluster, that is the new process owner.
    284561 * The child process and the associated main thread will be migrated to the target cluster
    285562 * later, when the child process makes an "exec" or any other system call.
     
    295572 * [37] This function implement the "exec" system call.
    296573 * It is executed in the client cluster, but the new process descriptor and main thread
    297  * must be created in a server cluster, that is generally another cluster, using a RPC.
    298  * - If the server_cluster is the client cluster, call directly make_exec() in local
    299  *   mode, to change the process image and launch a new thread in local cluster.
    300  *   finally, the old thread is deleted.
    301  * - If the target_cluster is remote, call rpc_process_exec_client() to execute the
    302  *   make_exec() in remote mode on the remote cluster, to create a new process
    303  *   descriptor and a new thread on remote cluster. Finally, both the local
    304  *   process descriptor and the local thread descriptor are deleted.
     574 * must be created in a server cluster, that is generally another cluster.
     575 * - if the server_cluster is the client cluster, call directly the process_make_exec()
     576 *   function to create a new process, and launch a new thread in local cluster.
     577 * - if the target_cluster is remote, call rpc_process_exec_client() to execute the
     578 *   process_make_exec() on the remote cluster.
    305579 * In both case this function build an exec_info_t structure containing all informations
    306  * required to build the new process descriptor and the associated thread, including
    307  * the mode (local/remote).
     580 * required to build the new process descriptor and the associated thread.
     581 * Finally, the calling process and thread are deleted.
    308582 *********************************************************************************************
    309583 * @ filename : string pointer on .elf filename (virtual pointer in user space)
    310584 * @ argv     : array of strings on process arguments (virtual pointers in user space)
    311585 * @ envp     : array of strings on Renvironment variables (virtual pointers in user space)
    312  * @ returns O if success / returns non-zero if error.
     586 * @ returns O if success / returns -1 if failure.
    313587 ********************************************************************************************/
    314588int sys_exec( char  * filename,
     
    317591
    318592/*********************************************************************************************
    319  * [38] This function TODO
    320  ********************************************************************************************/
    321 int sys_thread_getattr();
    322 
    323 /*********************************************************************************************
    324  * [39] This function implements the ps system call.
    325  ********************************************************************************************/
    326 int sys_ps( uint32_t cmd,
    327             pid_t    pid,
    328             uint32_t tid );
    329 
    330 /*********************************************************************************************
    331  * [40] This function TODO
    332  ********************************************************************************************/
    333 int sys_madvise();
    334 
    335 /*********************************************************************************************
    336  * [41] This function TODO
    337  ********************************************************************************************/
    338 int sys_mcntl();
    339 
    340 /*********************************************************************************************
    341  * [42] This function TODO
    342  ********************************************************************************************/
    343 int sys_stat();
    344 
    345 /*********************************************************************************************
    346  * [43] This function TODO
    347  ********************************************************************************************/
    348 int sys_thread_migrate();
    349 
    350 /*********************************************************************************************
    351  * [44] This function TODO
    352  ********************************************************************************************/
    353 int sys_sbrk();
    354 
    355 /*********************************************************************************************
    356  * [45] This function TODO
    357  ********************************************************************************************/
    358 int sys_rmdir();
    359 
    360 /*********************************************************************************************
    361  * [46] This function TODO
    362  ********************************************************************************************/
    363 int sys_ftime();
    364 
    365 /*********************************************************************************************
    366  * [47] This function TODO
    367  ********************************************************************************************/
    368 int sys_chmod();
    369 
    370 /*********************************************************************************************
    371  * [48] This function TODO
    372  ********************************************************************************************/
    373 int sys_fsync();
    374 
    375 /*********************************************************************************************
    376  * [49] This function TODO
    377  ********************************************************************************************/
    378 int sys_gettimeofday();
    379 
    380 /*********************************************************************************************
    381  * [50] This function TODO
    382  ********************************************************************************************/
    383 int sys_times();
     593 * [38] This function  returns in the <stat> structure, defined in the vfs.h file,
     594 * various informations on the file/directory identified by the <file_id> argument.
     595 *********************************************************************************************
     596 * @ file_id   : file descriptor index in fd_array.
     597 * @ stat      : pointer on the stat structure.
     598 * @ returns O if success / returns -1 if failure.
     599 ********************************************************************************************/
     600int sys_stat( uint32_t            file_id,
     601              struct vfs_stat_s * stat );
     602
     603/*********************************************************************************************
     604 * [39] This function is used to activate / desactivate Rthe trace for a thread
     605 * identified by the <trdid> and <pid> arguments.
     606 * It can be called by any other thread.
     607 *********************************************************************************************
     608 * @ operation  : operation type as defined below.
     609 * @ pid        : process identifier.
     610 * @ trdid      : thread identifier.
     611 * @ returns O if success / returns -1 if failure.
     612 ********************************************************************************************/
     613int sys_trace( uint32_t operation,
     614               pid_t    pid,
     615               uint32_t trdid );
     616
     617typedef enum
     618{
     619    TRACE_ON       = 0,
     620    TRACE_OFF      = 1,
     621}
     622trace_operation_t;
    384623
    385624
Note: See TracChangeset for help on using the changeset viewer.