Ignore:
Timestamp:
Dec 20, 2017, 4:51:09 PM (4 years ago)
Author:
alain
Message:

Fix bugs in exec

File:
1 edited

Legend:

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

    r408 r409  
    11/*
    2  * sys_thread_exit.c - terminates the execution of current thread
     2 * sys_thread_exit.c - terminates the execution of calling thread
    33 *
    4  * Authors       Ghassan Almaless (2008,2009,2010,2011,2012)
    5  *               Alain Greiner (2016,2017)
     4 * Authors   Alain Greiner (2016,2017)
    65 *
    76 * Copyright (c) UPMC Sorbonne Universites
     
    2423
    2524#include <hal_types.h>
    26 #include <hal_irqmask.h>
    2725#include <thread.h>
    2826#include <core.h>
     27#include <vmm.h>
    2928#include <scheduler.h>
    3029#include <printk.h>
    31 
    3230
    3331////////////////////////////////////////
    3432int sys_thread_exit( void * exit_value )
    3533{
    36         thread_t  * this = CURRENT_THREAD;
    37     core_t    * core = this->core;
    38     reg_t       irq_state;
     34    paddr_t      paddr;
     35    error_t          error;
    3936
    40     // register the exit_value pointer in thread descriptor
    41     this->exit_value = exit_value;
     37#if CONFIG_SYSCALL_DEBUG
     38uint32_t     tm_start;
     39uint32_t     tm_end;
     40tm_start = hal_get_cycles();
     41#endif
    4242
    43     // enter the join loop to wait the join if thread is joinable
    44     if( (this->flags & THREAD_FLAG_DETACHED) == 0 )
     43        thread_t  * this    = CURRENT_THREAD;
     44    process_t * process = this->process;
     45
     46    // check all locks released
     47        if( !thread_can_yield() )
     48        {
     49        printk("\n[ERROR] in %s : locks not released / thread %x in process %x\n",
     50        __FUNCTION__, this->trdid, process->pid );
     51        this->errno = EINVAL;
     52        return -1;
     53    }
     54
     55    // register the exit_value pointer in this thread descriptor
     56    this->join_value = exit_value;
     57
     58    if( (this->flags & THREAD_FLAG_DETACHED) == 0 )    // this thread is joinable
    4559    {
    46             while( 1 )
    47             {
    48             // take the lock protecting the flags
    49                 remote_spinlock_lock( XPTR( local_cxy, &this->flags_lock ) );
     60        // check exit_value in user space
     61        error = vmm_v2p_translate( false , exit_value , &paddr );
     62            if( error )
     63        {
     64            printk("\n[ERROR] in %s : illegal pointer = %x / thread %x in process %x\n",
     65            __FUNCTION__ , (intptr_t)exit_value, this->trdid , process->pid );
     66            this->errno = EINVAL;
     67            return -1;
     68        }
    5069
    51             // check the JOIN flag
    52             if( this->flags & THREAD_FLAG_JOIN )       // parent made a join
    53             {
    54                 // unblock the parent thread
    55                 thread_unblock( this->parent , THREAD_BLOCKED_JOIN );
     70        // take the lock protecting the join
     71        remote_spinlock_lock( XPTR( local_cxy, &this->join_lock ) );
    5672
    57                 // release the lock protecting the flags
    58                     remote_spinlock_unlock( XPTR( local_cxy, &this->flags_lock ) );
     73        if( this->flags & THREAD_FLAG_JOIN_DONE )       // parent thread arrived first
     74        {
     75            // unblock the parent thread
     76            thread_unblock( this->join_xp , THREAD_BLOCKED_EXIT );
    5977
    60                 // exit while
    61                 break;
    62             }
    63             else                                       // no join done by parent thread
    64             {
    65                 // set the EXIT flag
    66                 this->flags |= THREAD_FLAG_EXIT;
     78            // reset the JOIN_DONE flag in this thread
     79            this->flags &= ~THREAD_FLAG_JOIN_DONE;
    6780
    68                 // block this thread
    69                 thread_block( this , THREAD_BLOCKED_EXIT );
     81            // release the lock protecting the flags
     82                remote_spinlock_unlock( XPTR( local_cxy, &this->join_lock ) );
     83        }
     84        else                                           // this thread arrived first
     85        {
     86            // block this thread
     87            thread_block( this , THREAD_BLOCKED_JOIN );
    7088
    71                 // release the lock protecting the flags
    72                     remote_spinlock_unlock( XPTR( local_cxy, &this->flags_lock ) );
     89            // release the lock protecting the flags
     90                remote_spinlock_unlock( XPTR( local_cxy, &this->join_lock ) );
    7391
    74                 // deschedule
    75                 sched_yield("waiting parent join");
    76             }     
    77         }
    78         }
     92            // deschedule
     93            sched_yield( "WAITING JOIN" );
     94        }     
     95    }
    7996
    80         // Release FPU if required
    81         hal_disable_irq( &irq_state );
    82         if( core->fpu_owner == this )  core->fpu_owner = NULL;
    83         hal_restore_irq( irq_state );
     97#if CONFIG_SYSCALL_DEBUG
     98tm_end = hal_get_cycles();
     99syscall_dmsg("\n[DBG] %s : core[%x,%d] / thread %x in process %x / cycle %d\n"
     100"thread %x killed / cost = %d\n",
     101__FUNCTION__ , local_cxy , this->core->lid , this->trdid , this->process->pid , tm_start ,
     102this->trdid , (uint32_t)(tm_end - tm_start) );
     103#endif
    84104
    85         // suicide
    86     thread_kill( this );
    87         return 0;       
     105    // suicide using a rpc because  a thread cannot kill itself
     106    rpc_thread_kill_client( local_cxy , this );
    88107
    89 }  // end sys_thread_exit()
     108    return 0;   // never executed but required by compiler
     109
     110}  // end sys_thread exit
Note: See TracChangeset for help on using the changeset viewer.