Ignore:
Timestamp:
Aug 2, 2018, 11:47:13 AM (6 years ago)
Author:
alain
Message:

This version modifies the exec syscall and fixes a large number of small bugs.
The version number has been updated (0.1)

File:
1 edited

Legend:

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

    r440 r457  
    2222 */
    2323
    24 #include <hal_types.h>
     24#include <hal_kernel_types.h>
    2525#include <hal_uspace.h>
     26#include <shared_semaphore.h>
    2627#include <errno.h>
    2728#include <thread.h>
     
    3132#include <syscalls.h>
    3233
     34#if DEBUG_SYS_SEM
     35//////////////////////////////////////////////////
     36static char * sys_sem_op_str( uint32_t operation )
     37{
     38        if     ( operation == SEM_INIT     ) return "INIT";
     39        else if( operation == SEM_WAIT     ) return "WAIT";
     40        else if( operation == SEM_POST     ) return "POST";
     41        else if( operation == SEM_GETVALUE ) return "GETVALUE";
     42        else if( operation == SEM_DESTROY  ) return "DESTROY";
     43        else                                 return "undefined";
     44}
     45#endif
     46
    3347//////////////////////////////////
    34 int sys_sem( void         * vaddr,        // semaphore virtual  address
    35              uint32_t       operation,    // requested operation type
    36              uint32_t     * value )       // pointer on in/out argument
     48int sys_sem( void         * vaddr,            // semaphore virtual  address
     49             uint32_t       operation,        // requested operation type
     50             uint32_t       init_value,       // initial value
     51             uint32_t     * current_value )   // pointer on current value buffer
    3752{
    38         uint32_t         data;   
    3953        vseg_t         * vseg;
    4054    error_t          error;
     55    uint32_t         current;     // semaphore current value
     56    xptr_t           sem_xp;      // extended pointer on semaphore
    4157
    4258    thread_t       * this    = CURRENT_THREAD;
    4359    process_t      * process = this->process;
     60
     61#if DEBUG_SYS_SEM
     62uint64_t    tm_start;
     63uint64_t    tm_end;
     64tm_start = hal_get_cycles();
     65if( DEBUG_SYS_SEM < tm_start )
     66printk("\n[DBG] %s : thread %x in process %x enter for %s / cycle %d\n",
     67__FUNCTION__, this->trdid, process->pid, sys_sem_op_str( operation ), (uint32_t)tm_start );
     68#endif
    4469
    4570    // check vaddr in user vspace
     
    4974
    5075#if DEBUG_SYSCALLS_ERROR
    51 printk("\n[ERROR] in %s : unmapped semaphore %x / thread %x / process %x\n",
    52 __FUNCTION__ , (intptr_t)vaddr, this->trdid, process->pid );
    53 vmm_display( process , false );
    54 #endif
    55         this->errno = EINVAL;
    56         return -1;
    57     }
    58 
    59     // check value in user vspace
    60         error = vmm_get_vseg( process , (intptr_t)value , &vseg );
    61         if( error )
    62     {
    63 
    64 #if DEBUG_SYSCALLS_ERROR
    65 printk("\n[ERROR] in %s : unmapped value %x / thread %x / process %x\n",
     76printk("\n[ERROR] in %s : unmapped semaphore pointer %x / thread %x in process %x\n",
    6677__FUNCTION__ , (intptr_t)vaddr, this->trdid, process->pid );
    6778vmm_display( process , false );
     
    7788            case SEM_INIT:
    7889        {
    79             // get argument
    80                     hal_copy_from_uspace( &data , value , sizeof(uint32_t) );
    81 
    82             // call init function
    83             error = remote_sem_create( (intptr_t)vaddr , data );
     90            // call relevant kernel function to initialize semaphore
     91            error = remote_sem_create( (intptr_t)vaddr ,
     92                                       init_value,
     93                                       XPTR( local_cxy , &sem_xp ) );
    8494
    8595            if ( error )
    8696            {
    87                 printk("\n[ERROR] in %s : cannot create semaphore = %x\n",
    88                        __FUNCTION__ , (intptr_t)value );
    89                 this->errno = error;
    90                 return -1;
    91             }
     97
     98#if DEBUG_SYSCALLS_ERROR
     99printk("\n[ERROR] in %s : cannot create semaphore / thread %x in process %x\n",
     100__FUNCTION__, this->trdid, process->pid );
     101#endif
     102                this->errno = ENOMEM;
     103                return -1;
     104            }
     105
    92106            break;
    93107        }
     
    95109        case SEM_GETVALUE:
    96110        {
    97             // get extended pointer on remote semaphore
    98             xptr_t sem_xp = remote_sem_from_vaddr( (intptr_t)vaddr );
    99 
    100             if( sem_xp == XPTR_NULL )     // user error
    101             {
    102 
    103 #if DEBUG_SYSCALLS_ERROR
    104 printk("\n[ERROR] in %s : semaphore %x not registered / thread %x / process %x\n",
    105 __FUNCTION__ , (intptr_t)value, this->trdid, process->pid );
    106 #endif
    107                 this->errno = EINVAL;
    108                 return -1;
    109             }
    110             else                          // success
    111             {
    112                 // get semaphore current value
    113                         remote_sem_get_value( sem_xp , &data );
     111            // check current_value buffer in user vspace
     112                error = vmm_get_vseg( process , (intptr_t)current_value , &vseg );
     113            if( error )
     114            {
     115
     116#if DEBUG_SYSCALLS_ERROR
     117printk("\n[ERROR] in %s : unmapped buffer for current value %x / thread %x in process %x\n",
     118__FUNCTION__ , (intptr_t)current_value, this->trdid, process->pid );
     119vmm_display( process , false );
     120#endif
     121                this->errno = EINVAL;
     122                return -1;
     123            }
     124
     125            // get extended pointer on remote semaphore
     126            sem_xp = remote_sem_from_vaddr( (intptr_t)vaddr );
     127
     128            // check semaphore registered
     129            if( sem_xp == XPTR_NULL )
     130            {
     131
     132#if DEBUG_SYSCALLS_ERROR
     133printk("\n[ERROR] in %s : semaphore %x not registered / thread %x in process %x\n",
     134__FUNCTION__ , (intptr_t)vaddr, this->trdid, process->pid );
     135#endif
     136                this->errno = EINVAL;
     137                return -1;
     138            }
     139
     140            // call relevant kernel function to get semaphore current value
     141                    remote_sem_get_value( sem_xp , &current );
    114142 
    115                 // return value to user
    116                 hal_copy_to_uspace( value , &data , sizeof(uint32_t) );
    117             }
     143            // return value to user
     144            hal_copy_to_uspace( current_value , &current , sizeof(uint32_t) );
     145
    118146            break;
    119147        }
     
    122150        { 
    123151            // get extended pointer on remote semaphore
    124             xptr_t sem_xp = remote_sem_from_vaddr( (intptr_t)vaddr );
    125 
    126             if( sem_xp == XPTR_NULL )     // user error
    127             {
    128 
    129 #if DEBUG_SYSCALLS_ERROR
    130 printk("\n[ERROR] in %s : semaphore %x not registered / thread %x / process %x\n",
    131 __FUNCTION__ , (intptr_t)value, this->trdid, process->pid );
    132 #endif
    133                 this->errno = EINVAL;
    134                 return -1;
    135             }
    136             else                          // success
    137             {
    138                 // wait semaphore available
    139                 remote_sem_wait( sem_xp );
    140             }
     152            sem_xp = remote_sem_from_vaddr( (intptr_t)vaddr );
     153
     154            // check semaphore registered
     155            if( sem_xp == XPTR_NULL )
     156            {
     157
     158#if DEBUG_SYSCALLS_ERROR
     159printk("\n[ERROR] in %s : semaphore %x not registered / thread %x in process %x\n",
     160__FUNCTION__ , (intptr_t)vaddr, this->trdid, process->pid );
     161#endif
     162                this->errno = EINVAL;
     163                return -1;
     164            }
     165
     166            // call relevant kernel function to wait semaphore available
     167            remote_sem_wait( sem_xp );
     168           
    141169            break;
    142170        }
     
    145173        {
    146174            // get extended pointer on remote semaphore
    147             xptr_t sem_xp = remote_sem_from_vaddr( (intptr_t)vaddr );
    148 
    149             if( sem_xp == XPTR_NULL )     // user error
    150             {
    151 
    152 #if DEBUG_SYSCALLS_ERROR
    153 printk("\n[ERROR] in %s : semaphore %x not registered / thread %x / process %x\n",
    154 __FUNCTION__ , (intptr_t)value, this->trdid, process->pid );
    155 #endif
    156                 this->errno = EINVAL;
    157                 return -1;
    158             }
    159             else                          // success
    160             {
    161                 // release semaphore
    162                 remote_sem_post( sem_xp );
    163             }
     175            sem_xp = remote_sem_from_vaddr( (intptr_t)vaddr );
     176
     177            // check semaphore registered
     178            if( sem_xp == XPTR_NULL )
     179            {
     180
     181#if DEBUG_SYSCALLS_ERROR
     182printk("\n[ERROR] in %s : semaphore %x not registered / thread %x in process %x\n",
     183__FUNCTION__ , (intptr_t)vaddr, this->trdid, process->pid );
     184#endif
     185                this->errno = EINVAL;
     186                return -1;
     187            }
     188
     189            // call relevant kernel function to release semaphore
     190            remote_sem_post( sem_xp );
     191
    164192                        break;
    165193        }
     
    168196        {
    169197            // get extended pointer on remote semaphore
    170             xptr_t sem_xp = remote_sem_from_vaddr( (intptr_t)vaddr );
    171 
    172             if( sem_xp == XPTR_NULL )     // user error
    173             {
    174 
    175 #if DEBUG_SYSCALLS_ERROR
    176 printk("\n[ERROR] in %s : semaphore %x not registered / thread %x / process %x\n",
    177 __FUNCTION__ , (intptr_t)value, this->trdid, process->pid );
    178 #endif
    179                 this->errno = EINVAL;
    180                 return -1;
    181             }
    182             else                          // success
    183             {
    184                 // destroy semaphore
    185                 remote_sem_destroy( sem_xp );
    186             }
     198            sem_xp = remote_sem_from_vaddr( (intptr_t)vaddr );
     199
     200            // check semaphore registered
     201            if( sem_xp == XPTR_NULL )
     202            {
     203
     204#if DEBUG_SYSCALLS_ERROR
     205printk("\n[ERROR] in %s : semaphore %x not registered / thread %x in process %x\n",
     206__FUNCTION__ , (intptr_t)vaddr, this->trdid, process->pid );
     207#endif
     208                this->errno = EINVAL;
     209                return -1;
     210            }
     211
     212            // destroy semaphore
     213            remote_sem_destroy( sem_xp );
     214
    187215            break;
    188216            }   
     
    190218            default:  // undefined operation                       
    191219        {
    192             printk("\n[PANIC] in %s : illegal operation type\n", __FUNCTION__ );
    193             hal_core_sleep();
     220
     221#if DEBUG_SYSCALLS_ERROR
     222printk("\n[ERROR] in %s : undefined operation type %d / thread %x in process %x\n",
     223__FUNCTION__ , operation, this->trdid, process->pid );
     224#endif
     225            this->errno = EINVAL;
     226            return -1;
    194227        }
    195228        }
    196229
     230    hal_fence();
     231
     232#if DEBUG_SYS_SEM
     233tm_end = hal_get_cycles();
     234if( DEBUG_SYS_SEM < tm_end )
     235{
     236    cxy_t          sem_cxy = GET_CXY( sem_xp );
     237    remote_sem_t * sem_ptr = GET_PTR( sem_xp );
     238    uint32_t       value   = hal_remote_lw( XPTR( sem_cxy , &sem_ptr->count ) );
     239    printk("\n[DBG] %s : thread %x in process %x exit for %s / value %d / cost = %d / cycle %d\n",
     240    __FUNCTION__, this->trdid, process->pid, sys_sem_op_str( operation ), value,
     241    (uint32_t)(tm_end - tm_start), (uint32_t)tm_end );
     242}
     243#endif
     244
    197245    return 0;
    198246
Note: See TracChangeset for help on using the changeset viewer.