Changeset 469


Ignore:
Timestamp:
Aug 20, 2018, 1:04:16 PM (3 years ago)
Author:
alain
Message:

1) Introduce the libsemaphore library.
2) Introduce a small libmath library, required by the "fft" application..
3) Introduce the multithreaded "fft" application.
4) Fix a bad synchronisation bug in the Copy-On-Write mechanism.

Location:
trunk
Files:
54 added
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/hal/tsar_mips32/core/hal_exception.c

    r459 r469  
    146146
    147147            // restore FPU registers from requesting thread context
    148                 hal_fpu_context_restore( this->fpu_context );
     148                hal_fpu_context_restore( this );
    149149
    150150            // attach the FPU to the requesting thread
     
    155155    {
    156156        // restore FPU registers from requesting thread context
    157             hal_fpu_context_restore( this->fpu_context );
     157            hal_fpu_context_restore( this );
    158158
    159159        // attach the FPU to the requesting thread
     
    218218if( DEBUG_HAL_EXCEPTIONS < cycle )
    219219printk("\n[DBG] %s : thread %x in process %x enter / is_ins %d / %s / vaddr %x / cycle %d\n",
    220 __FUNCTION__, this->trdid, process->pid, is_ins, hal_mmu_exception_str(excp_code), bad_vaddr, cycle);
     220__FUNCTION__, this->trdid, process->pid,
     221is_ins, hal_mmu_exception_str(excp_code), bad_vaddr, cycle);
    221222#endif
    222223
     
    235236            if( error )   
    236237            {
    237                 printk("\n[ERROR] in %s for thread %x : cannot map vaddr = %x\n",
    238                 __FUNCTION__ , this->trdid , bad_vaddr );
     238                printk("\n[USER ERROR] in %s for thread %x in process %x\n"
     239                "   cannot map vaddr = %x / is_ins %d / epc %x\n",
     240                __FUNCTION__, this->trdid, this->process->pid, bad_vaddr, is_ins, excPC );
    239241
    240242                        return EXCP_USER_ERROR;
     
    256258        case MMU_READ_PRIVILEGE_VIOLATION:
    257259        {
    258             printk("\n[ERROR] in %s for thread %x : illegal user access to vaddr = %x\n",
    259             __FUNCTION__ , this->trdid , bad_vaddr );
     260            printk("\n[USER ERROR] in %s for thread %x in process %x\n"
     261            "   illegal user access to vaddr = %x / is_ins %d / epc %x\n",
     262            __FUNCTION__, this->trdid, this->process->pid, bad_vaddr, is_ins, excPC );
    260263
    261264            return EXCP_USER_ERROR;
     
    275278                if( error )
    276279                {
    277                     printk("\n[ERROR] in %s for thread %x : cannot cow vaddr = %x\n",
    278                     __FUNCTION__ , this->trdid , bad_vaddr );
     280                    printk("\n[USER ERROR] in %s for thread %x in process %x\n"
     281                    "   cannot cow vaddr = %x / is_ins %d / epc %x\n",
     282                    __FUNCTION__, this->trdid, this->process->pid, bad_vaddr, is_ins, excPC );
    279283
    280284                            return EXCP_USER_ERROR;
     
    295299            else                             // non writable user error
    296300            {
    297                 printk("\n[ERROR] in %s for thread %x : non-writable vaddr = %x\n",
    298                 __FUNCTION__ , this->trdid , bad_vaddr );
     301                printk("\n[USER ERROR] in %s for thread %x in process %x\n"
     302                "   non-writable vaddr = %x / is_ins %d / epc %x\n",
     303                __FUNCTION__, this->trdid, this->process->pid, bad_vaddr, is_ins, excPC );
    299304
    300305                return EXCP_USER_ERROR;
     
    303308        case MMU_READ_EXEC_VIOLATION:        // user error
    304309        {
    305             printk("\n[ERROR] in %s for thread %x : read to non-executable vaddr = %x\n",
    306             __FUNCTION__ , this->trdid , bad_vaddr );
     310            printk("\n[USER_ERROR] in %s for thread %x in process %x\n"
     311            "   non-executable vaddr = %x / is_ins %d / epc %x\n",
     312            __FUNCTION__, this->trdid, this->process->pid, bad_vaddr, is_ins, excPC );
    307313
    308314            return EXCP_USER_ERROR;
    309315        }
    310         default:                             // this is a kernel error => panic    
    311         {
    312             assert( false , __FUNCTION__ ,
    313             "thread %x in process %x / epc %x / badvaddr %x / cycle %d\n",
    314             this->trdid, this->process->pid, excPC, bad_vaddr, (uint32_t)hal_get_cycles() );
     316        default:                             // this is a kernel error    
     317        {
     318            printk("\n[KERNEL ERROR] in %s for thread %x in process %x\n"
     319            "  epc %x / badvaddr %x / is_ins %d\n",
     320            __FUNCTION__, this->trdid, this->process->pid, excPC, bad_vaddr, is_ins );
    315321
    316322            return EXCP_KERNEL_PANIC;
     
    353359    else
    354360    {
    355         nolock_printk("\n=== KERNEL PANIC / trdid %x / pid %x / core[%x,%d] / cycle %d ===\n",
     361        nolock_printk("\n=== KERNEL ERROR / trdid %x / pid %x / core[%x,%d] / cycle %d ===\n",
    356362        this->trdid, process->pid, local_cxy, core->lid , (uint32_t)hal_get_cycles() );
    357363    }
     
    415421        switch(excCode)
    416422        {
    417         case XCODE_DBE:     // can be non fatal
     423        case XCODE_DBE:     // Data Bus Error : can be non fatal if page fault
    418424        {
    419425                    error = hal_mmu_exception( this , excPC , false );  // data MMU exception
    420426            break;
    421427        }
    422             case XCODE_IBE:     // can be non fatal
     428            case XCODE_IBE:     // Instruction Bus Error : can be non fatal if page fault
    423429        {
    424430                    error = hal_mmu_exception( this , excPC , true );   // ins MMU exception
    425431                    break;
    426432        }
    427             case XCODE_CPU:    // can be non fatal
    428         {
    429             if( ((uzone[UZ_CR] >> 28) & 0x3) == 1 ) // FPU
     433            case XCODE_CPU:    // Coprocessor unavailable : can be non fatal if FPU
     434        {
     435            if( ((uzone[UZ_CR] >> 28) & 0x3) == 1 )             // FPU
    430436            {
    431                 error = hal_fpu_exception( this );              // FPU exception
     437                error = hal_fpu_exception( this );
    432438            }
    433             else
     439            else                                                // undefined coprocessor
    434440            {
     441                printk("\n[USER_ERROR] in %s for thread %x in process %x\n"
     442                "   undefined coprocessor / epc %x\n",
     443                __FUNCTION__, this->trdid, this->process->pid, excPC );
     444
    435445                        error = EXCP_USER_ERROR;
    436446            }
    437447                    break;
    438448        }
    439         case XCODE_OVR:    // user fatal error
    440         case XCODE_RI:     // user fatal error
     449        case XCODE_OVR:    // Arithmetic Overflow : user fatal error
     450        {
     451            printk("\n[USER_ERROR] in %s for thread %x in process %x\n"
     452            "   arithmetic overflow / epc %x\n",
     453            __FUNCTION__, this->trdid, this->process->pid, excPC );
     454
     455                    error = EXCP_USER_ERROR;
     456                break;
     457        }
     458        case XCODE_RI:     // Reserved Instruction : user fatal error
     459        {
     460            printk("\n[USER_ERROR] in %s for thread %x in process %x\n"
     461            "   reserved instruction / epc %x\n",
     462            __FUNCTION__, this->trdid, this->process->pid, excPC );
     463
     464                    error = EXCP_USER_ERROR;
     465                break;
     466        }
    441467        case XCODE_ADEL:   // user fatal error
    442         case XCODE_ADES:   // user fatal error
    443         {
     468        {
     469            printk("\n[USER_ERROR] in %s for thread %x in process %x\n"
     470            "   illegal data load address / epc %x\n",
     471            __FUNCTION__, this->trdid, this->process->pid, excPC );
     472
     473                    error = EXCP_USER_ERROR;
     474                break;
     475        }
     476        case XCODE_ADES:   //   user fatal error
     477        {
     478            printk("\n[USER_ERROR] in %s for thread %x in process %x\n"
     479            "   illegal data store address / epc %x\n",
     480            __FUNCTION__, this->trdid, this->process->pid, excPC );
     481
    444482                    error = EXCP_USER_ERROR;
    445483                break;
     
    462500        hal_exception_dump( this , uzone , error );
    463501
    464         assert( false , __FUNCTION__ , "thread %x in process %x on core [%x,%d]",
    465         this , this->process->pid , local_cxy , this->core->lid );
     502        assert( false , __FUNCTION__ , "core[%x,%d] blocked\n", local_cxy, this->core->lid );
    466503    }
    467504
  • trunk/kernel/kern/printk.c

    r459 r469  
    407407
    408408        // call nolock_printk to print core, function_name, and cycle
    409         nolock_printk("\n[PANIC] on core[%x,%d] in %s at cycle %d : " ,
    410         local_cxy, CURRENT_THREAD->core->lid, function_name, (uint32_t)hal_get_cycles() );
     409        nolock_printk("\n[PANIC] in %s => core[%x,%d] blocked at cycle %d : " ,
     410        function_name, local_cxy, CURRENT_THREAD->core->lid, (uint32_t)hal_get_cycles() );
    411411
    412412        // call kernel_printf on TXT0, in busy waiting to print format
  • trunk/kernel/kern/process.c

    r459 r469  
    11631163    }
    11641164
    1165 #if DEBUG_PROCESS_MAKE_FORK
     1165#if( DEBUG_PROCESS_MAKE_FORK & 1 )
    11661166cycle = (uint32_t)hal_get_cycles();
    11671167if( DEBUG_PROCESS_MAKE_FORK < cycle )
     
    12401240    "main thread must have LTID == 0\n" );
    12411241
    1242 #if( DEBUG_PROCESS_MAKE_FORK & 1 )
     1242//#if( DEBUG_PROCESS_MAKE_FORK & 1 )
     1243#if DEBUG_PROCESS_MAKE_FORK
    12431244cycle = (uint32_t)hal_get_cycles();
    12441245if( DEBUG_PROCESS_MAKE_FORK < cycle )
    1245 printk("\n[DBG] %s : thread %x in process %x created main thread %x on core[%x,%d] / cycle %d\n",
    1246 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid,
    1247 thread, local_cxy, thread->core->lid, cycle );
     1246printk("\n[DBG] %s : thread %x in process %x created main thread %x / cycle %d\n",
     1247__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, thread, cycle );
    12481248#endif
    12491249
     
    13421342
    13431343#if (DEBUG_PROCESS_MAKE_EXEC & 1)
     1344cycle = (uint32_t)hal_get_cycles();
    13441345if( DEBUG_PROCESS_MAKE_EXEC < cycle )
    1345 printk("\n[DBG] %s : open file <%s>\n", __FUNCTION__, path );
     1346printk("\n[DBG] %s : thread %x in process %x opened file <%s> / cycle %d\n",
     1347__FUNCTION__, thread->trdid, pid, path, cycle );
    13461348#endif
    13471349
     
    13491351    process_sigaction( pid , DELETE_ALL_THREADS );
    13501352
     1353#if (DEBUG_PROCESS_MAKE_EXEC & 1)
     1354cycle = (uint32_t)hal_get_cycles();
     1355if( DEBUG_PROCESS_MAKE_EXEC < cycle )
     1356printk("\n[DBG] %s : thread %x in process %x deleted all threads / cycle %d\n",
     1357__FUNCTION__, thread->trdid, pid, cycle );
     1358#endif
     1359
    13511360    // reset local process VMM
    13521361    vmm_destroy( process );
     
    13551364cycle = (uint32_t)hal_get_cycles();
    13561365if( DEBUG_PROCESS_MAKE_EXEC < cycle )
    1357 printk("\n[DBG] %s : thread %x in process %x / reset VMM / cycle %d\n",
     1366printk("\n[DBG] %s : thread %x in process %x reset VMM / cycle %d\n",
    13581367__FUNCTION__, thread->trdid, pid, cycle );
    13591368#endif
     
    14001409    if( error )
    14011410    {
    1402         printk("\n[ERROR] in %s : cannot reset main thread for %s\n", __FUNCTION__ , path );
     1411        printk("\n[ERROR] in %s : cannot update main thread for %s\n", __FUNCTION__ , path );
    14031412        vfs_close( file_xp , file_id );
    14041413        // FIXME restore old process VMM
  • trunk/kernel/kern/scheduler.c

    r462 r469  
    6363    list_root_init( &sched->k_root );
    6464
     65    // init spinlock
     66    spinlock_init( &sched->lock );
     67
    6568    sched->req_ack_pending = false;             // no pending request
    6669    sched->trace           = false;             // context switches trace desactivated
  • trunk/kernel/kern/thread.c

    r457 r469  
    8686    // return pointer on new thread descriptor
    8787    xptr_t base_xp = ppm_page2base( XPTR(local_cxy , page ) );
    88     return (thread_t *)GET_PTR( base_xp );
     88    return GET_PTR( base_xp );
    8989
    9090}  // end thread_alloc()
     
    419419uint32_t cycle = (uint32_t)hal_get_cycles();
    420420if( DEBUG_THREAD_USER_FORK < cycle )
    421 printk("\n[DBG] %s : thread %x enter / child_process %x / cycle %d\n",
    422 __FUNCTION__, CURRENT_THREAD, child_process->pid, cycle );
     421printk("\n[DBG] %s : thread %x in process %x enter / child_process %x / cycle %d\n",
     422__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, child_process->pid, cycle );
    423423#endif
    424424
     
    428428    // get cluster and local pointer on parent thread descriptor
    429429    parent_cxy = GET_CXY( parent_thread_xp );
    430     parent_ptr = (thread_t *)GET_PTR( parent_thread_xp );
     430    parent_ptr = GET_PTR( parent_thread_xp );
    431431
    432432    // get relevant fields from parent thread
     
    538538        if( mapped )
    539539        {
     540            // get pointers on the page descriptor
    540541            xptr_t   page_xp  = ppm_ppn2page( ppn );
    541542            cxy_t    page_cxy = GET_CXY( page_xp );
    542             page_t * page_ptr = (page_t *)GET_PTR( page_xp );
     543            page_t * page_ptr = GET_PTR( page_xp );
     544
     545            // get extended pointers on forks and lock fields
     546            xptr_t forks_xp = XPTR( page_cxy , &page_ptr->forks );
     547            xptr_t lock_xp  = XPTR( page_cxy , &page_ptr->lock );
     548
     549            // increment the forks counter
     550            remote_spinlock_lock( lock_xp ); 
    543551            hal_remote_atomic_add( XPTR( page_cxy , &page_ptr->forks ) , 1 );
     552            remote_spinlock_unlock( lock_xp ); 
    544553
    545554#if (DEBUG_THREAD_USER_FORK & 1)
    546555cycle = (uint32_t)hal_get_cycles();
    547556if( DEBUG_THREAD_USER_FORK < cycle )
    548 printk("\n[DBG] %s : thread %x copied stack PTE to child GPT : vpn %x\n",
    549 __FUNCTION__, CURRENT_THREAD, vpn );
     557printk("\n[DBG] %s : thread %x in process %x copied one PTE to child GPT : vpn %x / forks %d\n",
     558__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, vpn,
     559hal_remote_lw( XPTR( page_cxy , &page_ptr->forks) ) );
    550560#endif
    551561
     
    561571cycle = (uint32_t)hal_get_cycles();
    562572if( DEBUG_THREAD_USER_FORK < cycle )
    563 printk("\n[DBG] %s : thread %x exit / child_process %x / child_thread %x / cycle %d\n",
    564 __FUNCTION__, CURRENT_THREAD, child_process->pid, child_ptr, cycle );
     573printk("\n[DBG] %s : thread %x in process %x exit / child_thread %x / cycle %d\n",
     574__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, child_ptr, cycle );
    565575#endif
    566576
     
    631641    }
    632642
    633     // update user stack in stack descriptor
     643    // update user stack in thread descriptor
    634644    thread->u_stack_base = vseg->min;
    635645    thread->u_stack_size = vseg->max - vseg->min;
     
    11721182    {
    11731183        target_process_xp  = XLIST_ELEMENT( iter , process_t , local_list );
    1174         target_process_ptr = (process_t *)GET_PTR( target_process_xp );
     1184        target_process_ptr = GET_PTR( target_process_xp );
    11751185        target_process_pid = hal_remote_lw( XPTR( target_cxy , &target_process_ptr->pid ) );
    11761186        if( target_process_pid == pid )
  • trunk/kernel/kernel_config.h

    r459 r469  
    123123#define DEBUG_SYSCALLS_ERROR           2
    124124
    125 #define DEBUG_SYS_CLOSE                2
     125#define DEBUG_SYS_CLOSE                0
    126126#define DEBUG_SYS_DISPLAY              0
    127127#define DEBUG_SYS_EXEC                 0
    128 #define DEBUG_SYS_EXIT                 1
     128#define DEBUG_SYS_EXIT                 0
    129129#define DEBUG_SYS_FG                   0
    130130#define DEBUG_SYS_FORK                 0
     
    133133#define DEBUG_SYS_IS_FG                0
    134134#define DEBUG_SYS_KILL                 0
    135 #define DEBUG_SYS_OPEN                 2
     135#define DEBUG_SYS_OPEN                 0
    136136#define DEBUG_SYS_MMAP                 0
    137137#define DEBUG_SYS_READ                 0
     
    189189
    190190#define CONFIG_KERNEL_IDENTITY_MAP          true       // True for 32 bits cores             
    191 #define CONFIG_MAX_CLUSTER                  256        // max number of clusters
     191#define CONFIG_MAX_CLUSTERS                 256        // max number of clusters
    192192#define CONFIG_MAX_LOCAL_CORES              4          // max number of cores per cluster
    193193#define CONFIG_MAX_INT_DEV                  4          // max number of internal peripherals
     
    206206#define CONFIG_MAX_DMA_CHANNELS             4          // max number of DMA device channels
    207207#define CONFIG_MAX_NIC_CHANNELS             4          // max number of NIC device channels
    208 
    209 #define CONFIG_MAX_CLUSTERS                 256        // max number of clusters
    210208
    211209#define CONFIG_TXT_ECHO_MODE                1          // echo mode for TXT peripheral
  • trunk/kernel/libk/remote_sem.c

    r457 r469  
    4343    // get cluster and local pointer on reference process
    4444    cxy_t          ref_cxy = GET_CXY( ref_xp );
    45     process_t    * ref_ptr = (process_t *)GET_PTR( ref_xp );
     45    process_t    * ref_ptr = GET_PTR( ref_xp );
    4646
    4747    // get extended pointer on root of semaphores list
     
    6060        sem_xp  = XLIST_ELEMENT( iter_xp , remote_sem_t , list );
    6161        sem_cxy = GET_CXY( sem_xp );
    62         sem_ptr = (remote_sem_t *)GET_PTR( sem_xp );
     62        sem_ptr = GET_PTR( sem_xp );
    6363        ident   = (intptr_t)hal_remote_lpt( XPTR( sem_cxy , &sem_ptr->ident ) );   
     64
    6465        if( ident == vaddr )
    6566        {
  • trunk/kernel/mm/page.h

    r457 r469  
    5656 * This structure defines a physical page descriptor.
    5757 * Size is 64 bytes for a 32 bits core...
     58 * The spinlock is used to test/modify the forks counter.
    5859 * TODO : the list of waiting threads seems to be unused [AG]
    59  $ TODO : the spinlock use has to be clarified [AG]
     60 * TODO : the refcount use has to be clarified
    6061 ************************************************************************************/
    6162
     
    7071        uint32_t          refcount;       /*! reference counter                    (4)  */
    7172        uint32_t          forks;          /*! number of pending forks              (4)  */
    72         spinlock_t        lock;           /*! To Be Defined [AG]                   (16) */
     73        spinlock_t        lock;           /*! protect the forks field              (4) */
    7374}
    7475page_t;
  • trunk/kernel/mm/vmm.c

    r457 r469  
    411411                page_t   * page_ptr;
    412412                xptr_t     forks_xp;
     413                xptr_t     lock_xp;
    413414
    414415                // update flags in remote GPT
     
    433434                        if( attr & GPT_MAPPED )
    434435                        {
     436                            // get pointers and cluster on page descriptor
    435437                            page_xp  = ppm_ppn2page( ppn );
    436438                            page_cxy = GET_CXY( page_xp );
    437439                            page_ptr = GET_PTR( page_xp );
     440
     441                            // get extended pointers on "forks" and "lock"
    438442                            forks_xp = XPTR( page_cxy , &page_ptr->forks );
     443                            lock_xp  = XPTR( page_cxy , &page_ptr->lock );
     444
     445                            // increment "forks"
     446                            remote_spinlock_lock( lock_xp );
    439447                            hal_remote_atomic_add( forks_xp , 1 );
     448                            remote_spinlock_unlock( lock_xp );
    440449                        }
    441450                    }   // end loop on vpn
     
    473482    vpn_t       vpn_base;
    474483    vpn_t       vpn_size;
    475     xptr_t      page_xp;
     484    xptr_t      page_xp;        // extended pointer on page descriptor
    476485    page_t    * page_ptr;
    477486    cxy_t       page_cxy;
     487    xptr_t      forks_xp;       // extended pointer on forks counter in page descriptor
     488    xptr_t      lock_xp;        // extended pointer on lock protecting the forks counter
    478489    xptr_t      parent_root_xp;
    479490    bool_t      mapped;
     
    592603                    if( mapped )
    593604                    {
    594                         page_xp = ppm_ppn2page( ppn );
     605                        // get pointers and cluster on page descriptor
     606                        page_xp  = ppm_ppn2page( ppn );
    595607                        page_cxy = GET_CXY( page_xp );
    596608                        page_ptr = GET_PTR( page_xp );
    597                         hal_remote_atomic_add( XPTR( page_cxy , &page_ptr->forks ) , 1 );
     609
     610                        // get extended pointers on "forks" and "lock"
     611                        forks_xp = XPTR( page_cxy , &page_ptr->forks );
     612                        lock_xp  = XPTR( page_cxy , &page_ptr->lock );
     613
     614                        // increment "forks"
     615                        remote_spinlock_lock( lock_xp );
     616                        hal_remote_atomic_add( forks_xp , 1 );
     617                        remote_spinlock_unlock( lock_xp );
    598618
    599619#if DEBUG_VMM_FORK_COPY
     
    603623__FUNCTION__ , CURRENT_THREAD , vpn , cycle );
    604624#endif
    605 
    606625                    }
    607626                }
     
    670689if( DEBUG_VMM_DESTROY < cycle )
    671690printk("\n[DBG] %s : thread %x enter for process %x in cluster %x / cycle %d\n",
    672 __FUNCTION__ , CURRENT_THREAD , process->pid , local_cxy , cycle );
     691__FUNCTION__, CURRENT_THREAD->trdid, process->pid, local_cxy, cycle );
    673692#endif
    674693
     
    695714        vseg    = GET_PTR( vseg_xp );
    696715
    697 #if( DEBUG_VMM_DESTROY & 1 )
    698 if( DEBUG_VMM_DESTROY < cycle )
    699 printk("\n[DBG] %s : found %s vseg / vpn_base %x / vpn_size %d\n",
    700 __FUNCTION__ , vseg_type_str( vseg->type ), vseg->vpn_base, vseg->vpn_size );
    701 #endif
    702716        // unmap and release physical pages
    703717        vmm_unmap_vseg( process , vseg );
     
    751765if( DEBUG_VMM_DESTROY < cycle )
    752766printk("\n[DBG] %s : thread %x exit for process %x in cluster %x / cycle %d\n",
    753 __FUNCTION__ , CURRENT_THREAD , process->pid , local_cxy , cycle );
     767__FUNCTION__, CURRENT_THREAD->trdid, process->pid, local_cxy , cycle );
    754768#endif
    755769
     
    10691083    page_t    * page_ptr;   // page descriptor pointer
    10701084    xptr_t      forks_xp;   // extended pointer on pending forks counter
    1071     uint32_t    count;      // actual number of pendinf forks
     1085    xptr_t      lock_xp;    // extended pointer on lock protecting forks counter
     1086    uint32_t    forks;      // actual number of pendinf forks
    10721087
    10731088#if DEBUG_VMM_UNMAP_VSEG
     
    11151130                page_ptr = GET_PTR( page_xp );
    11161131
    1117                 // FIXME lock the physical page
     1132                // get extended pointers on forks and lock fields
     1133                forks_xp = XPTR( page_cxy , &page_ptr->forks );
     1134                lock_xp  = XPTR( page_cxy , &page_ptr->lock );
     1135
     1136                // get lock protecting page descriptor
     1137                remote_spinlock_lock( lock_xp );
    11181138
    11191139                // get pending forks counter
    1120                 count = hal_remote_lw( XPTR( page_cxy , &page_ptr->forks ) );
     1140                forks = hal_remote_lw( forks_xp );
    11211141               
    1122                 if( count )  // decrement pending forks counter
     1142                if( forks )  // decrement pending forks counter
    11231143                {
    1124                     forks_xp = XPTR( page_cxy , &page_ptr->forks );
    11251144                    hal_remote_atomic_add( forks_xp , -1 );
    11261145                } 
     
    11391158                }
    11401159
    1141                 // FIXME unlock the physical page
     1160                // release lock protecting page descriptor
     1161                remote_spinlock_unlock( lock_xp );
    11421162            }
    11431163        }
     
    14181438#if DEBUG_VMM_GET_ONE_PPN
    14191439thread_t * this = CURRENT_THREAD;
    1420 // if( DEBUG_VMM_GET_ONE_PPN < (uint32_t)hal_get_cycles() )
    1421 if( (vpn == 0x403) && ((local_cxy == 0) || (this->type == THREAD_RPC)) )
     1440if( DEBUG_VMM_GET_ONE_PPN < (uint32_t)hal_get_cycles() )
    14221441printk("\n[DBG] %s : thread %x enter for vpn = %x / type = %s / index = %d\n",
    14231442__FUNCTION__, this, vpn, vseg_type_str(type), index );
     
    14821501
    14831502#if (DEBUG_VMM_GET_ONE_PPN & 0x1)
    1484 if( (vpn == 0x403) && ((local_cxy == 0) || (this->type == THREAD_RPC)) )
    1485 // if( DEBUG_VMM_GET_ONE_PPN < (uint32_t)hal_get_cycles() )
     1503if( DEBUG_VMM_GET_ONE_PPN < (uint32_t)hal_get_cycles() )
    14861504printk("\n[DBG] %s : thread %x for vpn = %x / elf_offset = %x\n",
    14871505__FUNCTION__, this, vpn, elf_offset );
     
    14991517
    15001518#if (DEBUG_VMM_GET_ONE_PPN & 0x1)
    1501 // if( DEBUG_VMM_GET_ONE_PPN < (uint32_t)hal_get_cycles() )
    1502 if( (vpn == 0x403) && ((local_cxy == 0) || (this->type == THREAD_RPC)) )
     1519if( DEBUG_VMM_GET_ONE_PPN < (uint32_t)hal_get_cycles() )
    15031520printk("\n[DBG] %s : thread%x for vpn = %x / fully in BSS\n",
    15041521__FUNCTION__, this, vpn );
     
    15191536
    15201537#if (DEBUG_VMM_GET_ONE_PPN & 0x1)
    1521 // if( DEBUG_VMM_GET_ONE_PPN < (uint32_t)hal_get_cycles() )
    1522 if( (vpn == 0x403) && ((local_cxy == 0) || (this->type == THREAD_RPC)) )
     1538if( DEBUG_VMM_GET_ONE_PPN < (uint32_t)hal_get_cycles() )
    15231539printk("\n[DBG] %s : thread %x, for vpn = %x / fully in mapper\n",
    15241540__FUNCTION__, this, vpn );
     
    15511567
    15521568#if (DEBUG_VMM_GET_ONE_PPN & 0x1)
    1553 // if( DEBUG_VMM_GET_ONE_PPN < (uint32_t)hal_get_cycles() )
    1554 if( (vpn == 0x403) && ((local_cxy == 0) || (this->type == THREAD_RPC)) )
     1569if( DEBUG_VMM_GET_ONE_PPN < (uint32_t)hal_get_cycles() )
    15551570printk("\n[DBG] %s : thread %x for vpn = %x / both mapper & BSS\n"
    15561571"      %d bytes from mapper / %d bytes from BSS\n",
     
    15991614
    16001615#if DEBUG_VMM_GET_ONE_PPN
    1601 // if( DEBUG_VMM_GET_ONE_PPN < (uint32_t)hal_get_cycles() )
    1602 if( (vpn == 0x403) && ((local_cxy == 0) || (this->type == THREAD_RPC)) )
     1616if( DEBUG_VMM_GET_ONE_PPN < (uint32_t)hal_get_cycles() )
    16031617printk("\n[DBG] %s : thread %x exit for vpn = %x / ppn = %x\n",
    16041618__FUNCTION__ , this , vpn , *ppn );
     
    16281642#if DEBUG_VMM_GET_PTE
    16291643uint32_t   cycle = (uint32_t)hal_get_cycles();
    1630 // if( DEBUG_VMM_GET_PTE < cycle )
    1631 if( (vpn == 0x403) && ((local_cxy == 0) || (this->type == THREAD_RPC)) )
    1632 printk("\n[DBG] %s : thread %x enter / vpn %x / process %x / cow %d / cycle %d\n",
    1633 __FUNCTION__ , this , vpn , process->pid , cow , cycle );
     1644if( DEBUG_VMM_GET_PTE < cycle )
     1645printk("\n[DBG] %s : thread %x in process %x enter / vpn %x / cow %d / cycle %d\n",
     1646__FUNCTION__, this->trdid, process->pid, vpn, cow, cycle );
    16341647#endif
    16351648
     
    16441657    // vseg has been checked by the vmm_handle_page_fault() function
    16451658    assert( (vseg != NULL) , __FUNCTION__,
    1646     "vseg undefined / vpn %x / thread %x / process %x / core[%x,%d] / cycle %d\n",
    1647     vpn, this, process->pid, local_cxy, this->core->lid,
     1659    "vseg undefined / vpn %x / thread %x in process %x / core[%x,%d] / cycle %d\n",
     1660    vpn, this->trdid, process->pid, local_cxy, this->core->lid,
    16481661    (uint32_t)hal_get_cycles() );
    16491662
     
    16581671
    16591672        assert( (old_attr & GPT_MAPPED), __FUNCTION__,
    1660         "PTE unmapped for a COW exception / vpn %x / thread %x / process %x / cycle %d\n",
     1673        "PTE unmapped for a COW exception / vpn %x / thread %x in process %x / cycle %d\n",
    16611674        vpn, this, process->pid, (uint32_t)hal_get_cycles() );
    16621675
    16631676#if( DEBUG_VMM_GET_PTE & 1 )
    1664 // if( DEBUG_VMM_GET_PTE < cycle )
    1665 if( (vpn == 0x403) && ((local_cxy == 0) || (this->type == THREAD_RPC)) )
    1666 printk("\n[DBG] %s : thread %x handling COW for vpn %x in process %x\n",
    1667 __FUNCTION__, this, vpn, process->pid );
     1677if( DEBUG_VMM_GET_PTE < cycle )
     1678printk("\n[DBG] %s : thread %x in process %x handling COW for vpn %x\n",
     1679__FUNCTION__, this->trdid, process->pid, vpn );
    16681680#endif
    16691681
     
    16731685        page_t * page_ptr = GET_PTR( page_xp );
    16741686
     1687        // get extended pointers on forks and lock field in page descriptor
     1688        xptr_t forks_xp = XPTR( page_cxy , &page_ptr->forks );
     1689        xptr_t lock_xp  = XPTR( page_cxy , &page_ptr->lock );
     1690
     1691        // take lock protecting page descriptor
     1692        remote_spinlock_lock( lock_xp );
     1693
    16751694        // get number of pending forks in page descriptor
    1676         uint32_t forks = hal_remote_lw( XPTR( page_cxy , &page_ptr->forks ) );
     1695        uint32_t forks = hal_remote_lw( forks_xp );
    16771696
    16781697        if( forks )        // pending fork => allocate a new page, copy old to new
     
    16961715                    GET_PTR( old_base_xp ),
    16971716                    CONFIG_PPM_PAGE_SIZE );
     1717
     1718             // decrement pending forks counter in page descriptor
     1719             hal_remote_atomic_add( forks_xp , -1 );
    16981720        }             
    1699         else               // no pending fork => keep the existing page, reset COW
     1721        else               // no pending fork => keep the existing page
    17001722        {
    17011723            new_ppn = old_ppn;
    17021724        }
    17031725
     1726        // release lock protecting page descriptor
     1727        remote_spinlock_unlock( lock_xp );
     1728
    17041729        // build new_attr : reset COW and set WRITABLE,
    17051730        new_attr = (old_attr | GPT_WRITABLE) & (~GPT_COW);
     
    17071732        // update GPT[vpn] for all GPT copies
    17081733        vmm_global_update_pte( process, vpn, new_attr, new_ppn );
    1709 
    1710         // decrement pending forks counter in page descriptor
    1711         hal_remote_atomic_add( XPTR( page_cxy , &page_ptr->forks ) , -1 );
    17121734    }
    17131735    else        //////////// page_fault request ///////////////////////////
     
    17241746
    17251747#if( DEBUG_VMM_GET_PTE & 1 )
    1726 // if( DEBUG_VMM_GET_PTE < cycle )
    1727 if( (vpn == 0x403) && ((local_cxy == 0) || (this->type == THREAD_RPC)) )
    1728 printk("\n[DBG] %s : thread %x handling page fault for vpn %x in process %x\n",
    1729 __FUNCTION__, this, vpn, process->pid );
     1748if( DEBUG_VMM_GET_PTE < cycle )
     1749printk("\n[DBG] %s : thread %x in process %x handling page fault for vpn %x\n",
     1750__FUNCTION__, this->trdid, process->pid, vpn );
    17301751#endif
    17311752            // allocate new_ppn, and initialize the new page
     
    17671788#if DEBUG_VMM_GET_PTE
    17681789cycle = (uint32_t)hal_get_cycles();
    1769 // if( DEBUG_VMM_GET_PTE < cycle )
    1770 if( (vpn == 0x403) && (local_cxy == 0) )
    1771 printk("\n[DBG] %s : thread %x exit / vpn %x in process %x / ppn %x / attr %x / cycle %d\n",
    1772 __FUNCTION__, this, vpn, process->pid, new_ppn, new_attr, cycle );
     1790if( DEBUG_VMM_GET_PTE < cycle )
     1791printk("\n[DBG] %s : thread %x in process %x exit / vpn %x / ppn %x / attr %x / cycle %d\n",
     1792__FUNCTION__, this->trdid, process->pid, vpn, new_ppn, new_attr, cycle );
    17731793#endif
    17741794
     
    17971817#if DEBUG_VMM_HANDLE_PAGE_FAULT
    17981818uint32_t cycle = (uint32_t)hal_get_cycles();
    1799 // if( DEBUG_VMM_HANDLE_PAGE_FAULT < cycle )
    1800 if( (vpn == 0x403) && (local_cxy == 0) )
     1819if( DEBUG_VMM_HANDLE_PAGE_FAULT < cycle )
    18011820printk("\n[DBG] %s : thread %x in process %x enter for vpn %x / core[%x,%d] / cycle %d\n",
    18021821__FUNCTION__, this, process->pid, vpn, local_cxy, this->core->lid, cycle );
     
    18361855
    18371856#if DEBUG_VMM_HANDLE_PAGE_FAULT
    1838 // if( DEBUG_VMM_HANDLE_PAGE_FAULT < cycle )
    1839 if( (vpn == 0x403) && (local_cxy == 0) )
     1857if( DEBUG_VMM_HANDLE_PAGE_FAULT < cycle )
    18401858printk("\n[DBG] %s : thread %x in process %x call RPC_VMM_GET_PTE\n",
    18411859__FUNCTION__, this, process->pid );
     
    18701888#if DEBUG_VMM_HANDLE_PAGE_FAULT
    18711889cycle = (uint32_t)hal_get_cycles();
    1872 // if( DEBUG_VMM_HANDLE_PAGE_FAULT < cycle )
    1873 if( (vpn == 0x403) && (local_cxy == 0) )
     1890if( DEBUG_VMM_HANDLE_PAGE_FAULT < cycle )
    18741891printk("\n[DBG] %s : thread %x in process %x exit for vpn %x / core[%x,%d] / cycle %d\n",
    18751892__FUNCTION__, this, process->pid, vpn, local_cxy, this->core->lid, cycle );
  • trunk/kernel/mm/vmm.h

    r457 r469  
    166166 *   valid GPT entries in parent GPT are copied to the child GPT. The COW flag is not set.
    167167 * - no STACK vseg is copied from  parent VMM to child VMM, because the child STACK vseg
    168  *   must be copied from the cluster containing the user thread requesting the fork().
     168 *   must be copied later from the cluster containing the user thread requesting the fork().
    169169 *********************************************************************************************
    170170 * @ child_process     : local pointer on local child process descriptor.
  • trunk/kernel/syscalls/sys_read.c

    r459 r469  
    231231tm_end = hal_get_cycles();
    232232if( DEBUG_SYS_READ < tm_end )
    233 printk("\n[DBG] %s : thread %x in process %x exit / cycle %d\n"
    234 "nbytes %d / file_id %d / cost %d\n",
    235 __FUNCTION__ , this->trdid, process->pid,
    236 (uint32_t)tm_start , nbytes , file_id , (uint32_t)(tm_end - tm_start) );
     233printk("\n[DBG] %s : thread %x in process %x exit / cycle %d / cost %d\n",
     234__FUNCTION__ , this->trdid, process->pid, (uint32_t)tm_start, (uint32_t)(tm_end - tm_start) );
    237235#endif
    238236
  • trunk/kernel/syscalls/sys_sem.c

    r457 r469  
    7474
    7575#if DEBUG_SYSCALLS_ERROR
    76 printk("\n[ERROR] in %s : unmapped semaphore pointer %x / thread %x in process %x\n",
    77 __FUNCTION__ , (intptr_t)vaddr, this->trdid, process->pid );
     76printk("\n[ERROR] in %s : unmapped semaphore pointer %x / thread %x in process %x / cycle %d\n",
     77__FUNCTION__ , (intptr_t)vaddr, this->trdid, process->pid, (uint32_t)hal_get_cycles() );
    7878vmm_display( process , false );
    7979#endif
     
    9797
    9898#if DEBUG_SYSCALLS_ERROR
    99 printk("\n[ERROR] in %s : cannot create semaphore / thread %x in process %x\n",
    100 __FUNCTION__, this->trdid, process->pid );
     99printk("\n[ERROR] in %s INIT: cannot create semaphore / thread %x in process %x / cycle %d\n",
     100__FUNCTION__, this->trdid, process->pid, (uint32_t)hal_get_cycles() );
    101101#endif
    102102                this->errno = ENOMEM;
     
    115115
    116116#if DEBUG_SYSCALLS_ERROR
    117 printk("\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 );
     117printk("\n[ERROR] in %s GETVALUE: unmapped target buffer %x / thread %x in process %x / cycle %d\n",
     118__FUNCTION__ , (intptr_t)current_value, this->trdid, process->pid, (uint32_t)hal_get_cycles() );
    119119vmm_display( process , false );
    120120#endif
     
    131131
    132132#if DEBUG_SYSCALLS_ERROR
    133 printk("\n[ERROR] in %s : semaphore %x not registered / thread %x in process %x\n",
    134 __FUNCTION__ , (intptr_t)vaddr, this->trdid, process->pid );
     133printk("\n[ERROR] in %s GETVALUE: semaphore %x not found / thread %x in process %x / cycle %d\n",
     134__FUNCTION__ , (intptr_t)vaddr, this->trdid, process->pid, (uint32_t)hal_get_cycles() );
    135135#endif
    136136                this->errno = EINVAL;
     
    157157
    158158#if DEBUG_SYSCALLS_ERROR
    159 printk("\n[ERROR] in %s : semaphore %x not registered / thread %x in process %x\n",
    160 __FUNCTION__ , (intptr_t)vaddr, this->trdid, process->pid );
     159printk("\n[ERROR] in %s WAIT: semaphore %x not found / thread %x in process %x / cycle %d\n",
     160__FUNCTION__ , (intptr_t)vaddr, this->trdid, process->pid, (uint32_t)hal_get_cycles() );
     161vmm_display( process , true );
    161162#endif
    162163                this->errno = EINVAL;
     
    180181
    181182#if DEBUG_SYSCALLS_ERROR
    182 printk("\n[ERROR] in %s : semaphore %x not registered / thread %x in process %x\n",
    183 __FUNCTION__ , (intptr_t)vaddr, this->trdid, process->pid );
     183printk("\n[ERROR] in %s POST: semaphore %x not found / thread %x in process %x / cycle %d\n",
     184__FUNCTION__ , (intptr_t)vaddr, this->trdid, process->pid, (uint32_t)hal_get_cycles() );
    184185#endif
    185186                this->errno = EINVAL;
     
    203204
    204205#if DEBUG_SYSCALLS_ERROR
    205 printk("\n[ERROR] in %s : semaphore %x not registered / thread %x in process %x\n",
    206 __FUNCTION__ , (intptr_t)vaddr, this->trdid, process->pid );
     206printk("\n[ERROR] in %s DESTROY: semaphore %x not found / thread %x in process %x / cycle %d\n",
     207__FUNCTION__ , (intptr_t)vaddr, this->trdid, process->pid, (uint32_t)hal_get_cycles() );
    207208#endif
    208209                this->errno = EINVAL;
     
    220221
    221222#if DEBUG_SYSCALLS_ERROR
    222 printk("\n[ERROR] in %s : undefined operation type %d / thread %x in process %x\n",
    223 __FUNCTION__ , operation, this->trdid, process->pid );
     223printk("\n[ERROR] in %s : undefined operation type %d / thread %x in process %x / cycle %d\n",
     224__FUNCTION__ , operation, this->trdid, process->pid, (uint32_t)hal_get_cycles() );
    224225#endif
    225226            this->errno = EINVAL;
  • trunk/kernel/syscalls/sys_write.c

    r459 r469  
    6161    reg_t        save_sr;         // required to enable IRQs during syscall
    6262
    63 #if (DEBUG_SYS_WRITE & 1)
    64 enter_sys_write = (uint32_t)tm_start;
    65 #endif
    66 
    6763        thread_t   * this = CURRENT_THREAD;
    6864        process_t  * process = this->process;
     
    7773#endif
    7874 
     75#if (DEBUG_SYS_WRITE & 1)
     76enter_sys_write = (uint32_t)tm_start;
     77#endif
     78
    7979    // check file_id argument
    8080        if( file_id >= CONFIG_PROCESS_FILE_MAX_NR )
     
    195195tm_end = hal_get_cycles();
    196196if( DEBUG_SYS_WRITE < tm_end )
    197 printk("\n[DBG] %s : thread %x in process %x exit / cycle %d\n"
    198 "nbytes %d / file_id %d / cost %d\n",
    199 __FUNCTION__, this->trdid, process->pid, (uint32_t)tm_start,
    200 nbytes, file_id , (uint32_t)(tm_end - tm_start) );
     197printk("\n[DBG] %s : thread %x in process %x exit / cycle %d / cost %d\n",
     198__FUNCTION__, this->trdid, process->pid, (uint32_t)tm_start, (uint32_t)(tm_end - tm_start) );
    201199#endif
    202200 
  • trunk/user/ksh/ksh.c

    r459 r469  
    1 ///////////////////////////////////////////////////////////////////////////////
     1/////////////////////////////////////////////////////////////////////////////////////////
    22// File   :  ksh.c
    33// Date   :  October 2017
    44// Author :  Alain Greiner
    5 ///////////////////////////////////////////////////////////////////////////////
     5/////////////////////////////////////////////////////////////////////////////////////////
    66// This application implements a minimal shell for ALMOS-MKH.
    77//
    88// This user KSH process contains two POSIX threads:
    99// - the "main" thread contains the infinite loop implementing
    10 //   the children processes termination monitoring using the wait syscall.
    11 // - the "interactive" thread contains the infinite loop implementing
    12 //   the command interpreter attached to the TXT terminal.
    13 //   This "interactive" thread block and deschedules when the KSH process
    14 //   loses the TXT terminal ownership. It is reactivated when the KSH
    15 //   process returns in background.
     10//   the children processes termination monitoring, using the wait syscall.
     11// - the "interactive" thread contains the infinite loop implementing the command
     12//   interpreter attached to the TXT terminal, and handling one KSH command
     13//   per iteration.
    1614//
    17 // Note: the children processes are created by the <load> command, and are
     15// The children processes are created by the <load> command, and are
    1816// attached to the same TXT terminal as the KSH process itself.
    19 // . A child process can be lauched in foreground: the KSH process loses
    20 //   the TXT terminal ownership, that is transfered to the new process.
    21 // . A child process can be lauched in background: the KSH process keeps
    22 //   the TXT terminal ownership. that is transfered to the new process.
    23 ///////////////////////////////////////////////////////////////////////////////
     17// A child process can be lauched in foreground or in background:
     18// . when the child process is running in foreground, the KSH process loses
     19//   the TXT terminal ownership, that is transfered to the child process.
     20// . when the child process is running in background: the KSH process keeps
     21//   the TXT terminal ownership.
     22//
     23// A semaphore is used to synchronize the two KSH threads. At each iteration,
     24// the interactive thread check the semaphore (with a sem_wait). It blocks
     25// and deschedules, if the KSH process loosed the TXT ownership (after a load,
     26// or for any other cause. It unblocks with the following policy:
     27// . if the command is "not a load", the semaphore is incremented by the
     28//   cmd_***() function when the command is completed, to allow the KSH interactive()
     29//   function to get the next command in the while loop.   
     30// . if the command is a "load without &", the TXT is given to the NEW process by the
     31//   execve() syscall, and is released to the KSH process when NEW process terminates.
     32//   The KSH process is notified and the KSH main() function increments the semahore
     33//   to allow the KSH interactive() function to handle commands.
     34// . if the command is a "load with &", the cmd_load() function returns the TXT
     35//   to the KSH process and increment the semaphore, when the parent KSH process
     36//   returns from the fork() syscall.
     37/////////////////////////////////////////////////////////////////////////////////////////
    2438
    2539#include <stdio.h>
     
    3751#define FIFO_SIZE      (1024)   // FIFO depth for recursive ls
    3852
    39 #define KSH_DEBUG      0
    40 
    41 ////////////////////////////////////////////////////////////////////////////////
     53#define KSH_DEBUG           0
     54#define CMD_LOAD_DEBUG      0
     55
     56//////////////////////////////////////////////////////////////////////////////////////////
    4257//         Structures
    43 ////////////////////////////////////////////////////////////////////////////////
     58//////////////////////////////////////////////////////////////////////////////////////////
    4459
    4560// one entry in the registered commands array
     
    6176
    6277
    63 ////////////////////////////////////////////////////////////////////////////////
     78//////////////////////////////////////////////////////////////////////////////////////////
    6479//         Global Variables
    65 ////////////////////////////////////////////////////////////////////////////////
     80//////////////////////////////////////////////////////////////////////////////////////////
    6681
    6782ksh_cmd_t       cmd[];                    // array of supported commands
     
    7691sem_t           semaphore;                // block interactive thread when zero
    7792
    78 ////////////////////////////////////////////////////////////////////////////////
     93//////////////////////////////////////////////////////////////////////////////////////////
    7994//         Shell  Commands
    80 ////////////////////////////////////////////////////////////////////////////////
     95//////////////////////////////////////////////////////////////////////////////////////////
    8196
    8297/////////////////////////////////////////////
     
    454469        if( (argc < 2) || (argc > 3) ) 
    455470    {
    456                 printf("  usage: %s pathname [&]\n", argv[0] );
     471                printf("  usage: %s pathname [&] / argc = %d\n", argv[0], argc );  // @@@
    457472                return;
    458473        }
     
    466481    ksh_pid = getpid();
    467482
    468 #if KSH_DEBUG
    469 printf("\n[KSH_DEBUG] in %s : ksh PID %x / path %s / background %d\n",
    470 __FUNCTION__, ksh_pid, argv[1], background );
     483#if CMD_LOAD_DEBUG
     484long long unsigned cycle;
     485get_cycle( &cycle );
     486printf("\n@@@ %s : KSH PID %x before fork / path %s / background %d / cycle %d\n",
     487__FUNCTION__, ksh_pid, argv[1], background, (int)cycle );
    471488#endif
    472489
     
    481498    else if (ret_fork == 0) // it is the CHILD process
    482499    {
     500
     501#if CMD_LOAD_DEBUG
     502get_cycle( &cycle );
     503printf("\n@@@ %s : CHILD_PID %x after fork, before exec / cycle %d\n",
     504__FUNCTION__ , getpid(), (int)cycle );
     505#endif
     506
    483507        // CHILD process exec NEW process
    484508        ret_exec = execve( pathname , NULL , NULL );
     509
     510#if CMD_LOAD_DEBUG
     511get_cycle( &cycle );
     512printf("\n@@@ %s : CHILD_PID %x after exec / ret_exec %d / cycle %d\n",
     513__FUNCTION__ , getpid(), ret_exec, (int)cycle );
     514#endif
    485515
    486516        // this is only executed in case of exec failure
     
    494524    {
    495525
    496 #if KSH_DEBUG
    497 int sem_value;
    498 sem_getvalue( &semaphore , &sem_value );
    499 printf("\n[KSH_DEBUG] in %s : child PID %x / background %d / sem_value %d\n",
    500 ret_fork, background, sem_value  );
     526#if CMD_LOAD_DEBUG
     527get_cycle( &cycle );
     528printf("\n@@@ %s : KSH_PID %x after fork / ret_fork %x / cycle %d\n",
     529__FUNCTION__, getpid(), ret_fork, (int)cycle );
    501530#endif
    502531
    503         if( background )        // child in background =>  KSH keeps TXT ownership
     532        if( background )    // child in background =>  KSH must keep TXT ownership
    504533        {
    505534            // execve() tranfered TXT ownership to child => give it back to KSH
     
    734763// This function analyses one command (with arguments), executes it, and returns.
    735764////////////////////////////////////////////////////////////////////////////////////
    736 static void parse( char * buf )
     765static void __attribute__ ((noinline)) parse( char * buf )
    737766{
    738767        int argc = 0;
     
    758787        }
    759788
     789    // analyse command type
    760790        if (argc > 0)
    761791    {
     
    765795
    766796                // try to match typed command
    767                 for (i = 0; cmd[i].name; i++)
     797                for (i = 0 ; cmd[i].name ; i++)
    768798        {
    769799                        if (strcmp(argv[0], cmd[i].name) == 0)
     
    788818static void interactive()
    789819{
    790         char         c;                                           // read character
    791         char         buf[CMD_MAX_SIZE];           // buffer for one command
    792     unsigned int end_command;             // last character found in a command
    793         unsigned int count;                               // pointer in command buffer
    794         unsigned int i;                                           // index for loops
    795         unsigned int state;                   // escape sequence state
    796 
    797 // @@@
    798 // parse( "load /bin/user/fft.elf" );
    799 // @@@
     820        char           c;                                               // read character
     821        char           buf[CMD_MAX_SIZE];               // buffer for one command
     822    unsigned int   end_command;             // last character found in a command
     823        unsigned int   count;                   // pointer in command buffer
     824        unsigned int   i;                                               // index for loops
     825        unsigned int   state;                   // escape sequence state
     826
     827/* This can be used to remove interactive mode
     828
     829for( i=1 ; 1 ; i += 2)
     830{
     831    if( sem_wait( &semaphore ) )
     832    {
     833        printf("\n[ksh error] cannot found semafore\n" );
     834        exit( 1 );
     835    }
     836    else
     837    {
     838        printf("\n[ksh] %d for sort\n", i );
     839    }
     840    strcpy( buf , "load /bin/user/sort.elf" );
     841    parse( buf );
     842
     843    if( sem_wait( &semaphore ) )
     844    {
     845        printf("\n[ksh error] cannot found semafore\n" );
     846        exit( 1 );
     847    }
     848    else
     849    {
     850        printf("\n[ksh] %d for fft\n", i+1 );
     851    }
     852    strcpy( buf , "load /bin/user/fft.elf" );
     853    parse( buf );
     854}
     855
     856*/
    800857
    801858        enum fsm_states
     
    826883            state = NORMAL;
    827884
    828         // block if the KSH process is not the TXT owner
    829         // - if the command is not a "load"
    830         //   the semaphore must be released by the cmd_***()
    831         // - if the command is a load, it depends on
    832         //   the "background" argument
    833         sem_wait( &semaphore );
     885        // decrement semaphore, and block if the KSH process is not the TXT owner
     886        if ( sem_wait( &semaphore ) )
     887        {
     888            printf("\n[ksh error] cannot found semafore\n" );
     889            exit( 1 );
     890        }
    834891
    835892        // display prompt on a new line
     
    9911048    int          status;          // child process termination status
    9921049    int          child_pid;       // child process identifier
    993     int          parent_pid;      // parent process identifier
    994     pthread_t    trdid;           // kernel allocated index for interactive thread
     1050    int          parent_pid;      // parent process identifier (i.e. this process)
     1051    pthread_t    trdid;           // interactive thread identifier (unused)
    9951052    unsigned int is_owner;        // non-zero if KSH process is TXT owner
    9961053
     
    10051062
    10061063    // initializes the semaphore used to unblock the interactive thread
    1007     sem_init( &semaphore , 0 , 1 );
     1064    if ( sem_init( &semaphore , 0 , 1 ) )
     1065    {
     1066        printf("\n[KSH ERROR] cannot initialize semaphore\n" );
     1067        exit( 1 );
     1068    }
     1069
     1070printf("\n@@@ in KSH %s : &semaphore = %x\n", __FUNCTION__, &semaphore );
    10081071
    10091072    // initialize interactive thread attributes
  • trunk/user/sort/sort.c

    r459 r469  
    2828#include <hal_macros.h>
    2929
    30 #define ARRAY_LENGTH        0x400    // 1024 values
     30#define ARRAY_LENGTH        0x100    // 256 values
    3131
    3232#define MAX_THREADS         1024     // 16 * 16 * 4
     
    250250    }
    251251
    252     get_cycle( &cycle );
    253     printf("\n\n[SORT] main starts on core[%x,%d] / %d threads / %d values / cycle %d\n",
    254     main_cxy, main_lid, threads, ARRAY_LENGTH, (unsigned int)cycle );
     252    printf("\n[SORT] main starts on core[%x,%d] / %d thread(s) / %d values\n",
     253    main_cxy, main_lid, threads, ARRAY_LENGTH );
    255254
    256255    // Barrier initialization
Note: See TracChangeset for help on using the changeset viewer.