_WCRTLINK _NORETURN void __fatal_runtime_error( char _WCI86FAR *msg, unsigned retcode ) { if( __EnterWVIDEO( msg ) ) _sys_exit( retcode ); __exit_with_msg( msg, retcode ); // never return }
/* __inline bsn_t* bsn_create( S32 val ) Creates a binary search tree node (bsn) with a specified value. Parameters: S32 val A value to be assigned to the node. */ __inline bsn_t* bsn_create( S32 val ) { bsn_t* tmp = malloc(sizeof(bsn_t)); if (!tmp) _sys_exit(EXIT_FAILURE); tmp->val = val; tmp->left = NULL; tmp->right = NULL; return tmp; }
_WCRTLINK _NORETURN void __exit_with_msg( char _WCI86FAR *msg, unsigned retcode ) { char newline; write( STDERR_FILENO, msg, strlen( msg ) ); newline = '\n'; write( STDERR_FILENO, &newline, 1 ); _sys_exit( retcode ); // never return }
unsigned exc_handler(uint32_t exc_num, volatile struct intr_ctx ctx) { static const char * const tname[] = { "UNKNOWN", "fault", "trap", "abort condition", }; if ( exc[exc_num].handler ) { (*exc[exc_num].handler)((struct intr_ctx *)&ctx); return return_from_intr(&ctx); } if ( (ctx.cs & __CPL3) == __CPL3 ) { _sys_exit(~0); } cli(); printk("%s: %s @ 0x%.8lx", tname[exc[exc_num].type], exc[exc_num].name, ctx.eip); if ( exc[exc_num].err_code ) { if ( ctx.err_code & 0x1 ) printk(" EXT"); switch ( ctx.err_code & 0x6 ) { case 0: printk(" GDT"); break; case 2: printk(" IDT"); break; case 4: printk(" LDT"); break; } printk(" selector=0x%.lx", ctx.err_code & 0xfff8); } printk("\n"); ctx_dump((struct intr_ctx *)&ctx); idle_task_func(); }
static void page_fault(struct intr_ctx *ctx) { if ( 0 == (ctx->err_code & (PAGEFAULT_PROTECTION)) ) { unsigned prot; if ( (ctx->err_code & PAGEFAULT_WRITE) ) prot = PROT_WRITE; else prot = PROT_READ; if ( !mm_pagefault(__this_task, pf_address(), prot) ) return; } if ( ctx->err_code & PAGEFAULT_USER ) _sys_exit(~0); else{ struct pagefault_fixup *fix; for(fix = &__rodata_pagefault; fix < &__rodata_pagefault_end; fix++) { if ( fix->fault_addr == ctx->eip ) { ctx->eip = fix->fixup_addr; return; } } } cli(); printk("Unhandled #PF in %s mode: %s fault_addr=0x%.8lx/%s%s\n", (ctx->err_code & PAGEFAULT_USER) ? "user" : "supervisor", (ctx->err_code & PAGEFAULT_PROTECTION) ? "PROTECTION_VIOLATION" : "NONPRESENT", pf_address(), (ctx->err_code & PAGEFAULT_WRITE) ? "WRITE" : "READ", (ctx->err_code & PAGEFAULT_RESERVED_BIT) ? " RESERVED_BIT" : ""); ctx_dump(ctx); idle_task_func(); }
/*-------------------------------------------- | Name: _syscall_exit | Description: | Parameters: none | Return Type: none | Comments: | See: ----------------------------------------------*/ int _syscall_exit(kernel_pthread_t* pthread_ptr, pid_t pid, void* data){ pid_t ppid = process_lst[pid]->ppid; exit_t* exit_dt=(exit_t*)data; if(process_lst[pid]->pthread_ptr->parent_pthread_ptr && process_lst[pid]->pthread_ptr->parent_pthread_ptr->stat&PTHREAD_STATUS_FORK ) { kernel_pthread_t* parent_pthread_ptr= process_lst[pid]->pthread_ptr; fork_t* fork_dt; //close all process(pid) file descriptor //must be execute before __atomic_in() and __stop_sched() //because in some _vfs_close() operation on driver, this operation need inter pthread communication to be completed //(ex: lwip_sock_close() deadlock risk); _close_process_fd(pid); //atomic code no task switching __atomic_in(); //wakeup locked process _sys_unlockw(); //warning all!!! micro-kernel operation is not advised. __stop_sched(); fork_dt=(fork_t*)pthread_ptr->parent_pthread_ptr->reg.data; //restore father context _sys_vfork_exit(pthread_ptr,exit_dt->status); //restart father fork_dt->pid=pid; __flush_syscall(pthread_ptr); __restart_sched(); __flush_syscall(parent_pthread_ptr); //cancel the pthread //_sys_pthread_cancel(process_lst[pid]->pthread_ptr, pid); //free(process_lst[pid]->pthread_ptr); //wake up dad on waitpid //__kernel_ret_int(parent_pthread_ptr);//father } else { //close all process(pid) file descriptor //must be execute before __atomic_in() and __stop_sched() //because in some _vfs_close() operation on driver, this operation need inter pthread communication to be completed //(ex: lwip_sock_close() deadlock risk); _close_process_fd(exit_dt->pid); //atomic code no task switching __atomic_in(); //_close_process_fd(exit_dt->pid); //wakeup locked process _sys_unlockw(); //warning!!! all micro-kernel operation is not advised. __stop_sched(); // _sys_exit(exit_dt->pid,exit_dt->status); // __flush_syscall(pthread_ptr); __atomic_out(); //ppid threads are on waitpid()? if( ppid) { //get main thread of father process kernel_pthread_t* _pthread_ptr=process_lst[ppid]->pthread_ptr; //walking on threads chained list in parent process while(_pthread_ptr) { //is thread blocked on waitpid()? if(_pthread_ptr->stat&PTHREAD_STATUS_STOP && _pthread_ptr->reg.syscall== _SYSCALL_WAITPID) { waitpid_t* waitpid_dt = (waitpid_t*)_pthread_ptr->reg.data; _syscall_waitpid(_pthread_ptr,ppid,waitpid_dt); } _pthread_ptr=_pthread_ptr->next; } //send signal to one pthread father processus if no one are in WAITPID and STOP state _sys_kill(process_lst[ppid]->pthread_ptr,SIGCHLD,1); _sys_pthread_cancel_for_exit(pthread_ptr, pid); } else{ pid_t _pid; //it's a daemon process //free process // free(process_lst[pid]); // process_lst[pid]= 0; // //printf("_syscall_exit\r\n"); //checkif it's the last process for(_pid=1; _pid<=PROCESS_MAX; _pid++) if(process_lst[_pid]) { free(process_lst[pid]); process_lst[pid]= 0; goto end; } return -1; //in this case stop all } // } end: __restart_sched(); __atomic_out(); return 0; }
/* this function is used by the QP embedded systems-friendly assertions */ void Q_onAssert(char const * const file, int line) { printf("Assertion failed in %s, line %d", file, line); fflush(stdout); _sys_exit(-1); }
/*..........................................................................*/ void BSP_boom(void) { printf("BOOM!!!"); fflush(stdout); _sys_exit(0); }
_WCRTLINK _NORETURN void __exit( unsigned ret_code ) { __FiniRtns( 0, FINI_PRIORITY_EXIT - 1 ); _sys_exit( ret_code ); // never return }
void exit(int status) { _exitcs(); _sys_exit(status); }