s32 sys_spu_thread_group_terminate(u32 id, s32 value) { sys_spu.warning("sys_spu_thread_group_terminate(id=0x%x, value=0x%x)", id, value); LV2_LOCK; // seems the id can be either SPU Thread Group or SPU Thread const auto thread = idm::get<SPUThread>(id); const auto group = thread ? thread->tg.lock() : idm::get<lv2_spu_group_t>(id); if (!group && !thread) { return CELL_ESRCH; } if (thread) { for (auto& t : group->threads) { // find primary (?) thread and compare it with the one specified if (t) { if (t == thread) { break; } else { return CELL_EPERM; } } } } if (group->state <= SPU_THREAD_GROUP_STATUS_INITIALIZED || group->state == SPU_THREAD_GROUP_STATUS_WAITING || group->state == SPU_THREAD_GROUP_STATUS_WAITING_AND_SUSPENDED) { return CELL_ESTAT; } for (auto& thread : group->threads) { if (thread) { thread->state += cpu_flag::stop; thread->lock_notify(); } } group->state = SPU_THREAD_GROUP_STATUS_INITIALIZED; group->exit_status = value; group->join_state |= SPU_TGJSF_TERMINATED; group->cv.notify_one(); return CELL_OK; }
PRIVATE void exp_timer(TIMER** tl,int time) { while(*tl!=0&&(*tl)->exptime<time) { printf("%s's Timer expire<%d>",pid2proc((*tl)->pid)->name,ticks); lock_notify(TASK_CLOCK,(*tl)->pid); (*tl)=(*tl)->next; } }
/** * <Ring 0> Interrupt handler. * * @param irq IRQ nr of the disk interrupt. *****************************************************************************/ PUBLIC void hd_handler(int irq) { /* * Interrupts are cleared when the host * - reads the Status Register, * - issues a reset, or * - writes to the Command Register. */ hd_status = in_byte(REG_STATUS); lock_notify(INTERRUPT,TASK_HD); //inform_int(TASK_HD); }
s32 _sys_timer_start(u32 timer_id, u64 base_time, u64 period) { sys_timer.warning("_sys_timer_start(timer_id=0x%x, base_time=0x%llx, period=0x%llx)", timer_id, base_time, period); const u64 start_time = get_system_time(); LV2_LOCK; const auto timer = idm::get<lv2_timer_t>(timer_id); if (!timer) { return CELL_ESRCH; } if (timer->state != SYS_TIMER_STATE_STOP) { return CELL_EBUSY; } if (!period) { // oneshot timer (TODO: what will happen if both args are 0?) if (start_time >= base_time) { return CELL_ETIMEDOUT; } } else { // periodic timer if (period < 100) { return CELL_EINVAL; } } if (timer->port.expired()) { return CELL_ENOTCONN; } // sys_timer_start_periodic() will use current time (TODO: is it correct?) timer->expire = base_time ? base_time : start_time + period; timer->period = period; timer->state = SYS_TIMER_STATE_RUN; timer->lock_notify(); return CELL_OK; }
PUBLIC void clock_handler(int irq) { ticks++; p_proc_ready->ticks--; if(ticks%100==0) { printf("!"); } if(ticks==300) { lock_notify(INTERRUPT,TASK_FS); } //if(k_reenter!=0) //{ //disp_int(k_reenter); //return; //} //printf("send notify"); //printf("%s %d",p_proc_ready->name,p_proc_ready->ticks); if(p_proc_ready->ticks<=0||nextexpiretime<ticks) { //printf("%s",p_proc_ready->name); lock_notify(INTERRUPT,TASK_CLOCK); }//schedule(); // p_proc_ready++; // if(p_proc_ready>=proc_table+NR_TASKS) // {proc_table[1].priority=5; // p_proc_ready = proc_table; // } }
void pagefault(struct proc *pr, int trap_errno) { int s; vir_bytes ph; u32_t pte; if(pagefault_count != 1) minix_panic("recursive pagefault", pagefault_count); /* Don't schedule this process until pagefault is handled. */ if(RTS_ISSET(pr, PAGEFAULT)) minix_panic("PAGEFAULT set", pr->p_endpoint); RTS_LOCK_SET(pr, PAGEFAULT); if(pr->p_endpoint <= INIT_PROC_NR) { /* Page fault we can't / don't want to * handle. */ kprintf("pagefault for process %d ('%s'), pc = 0x%x\n", pr->p_endpoint, pr->p_name, pr->p_reg.pc); proc_stacktrace(pr); minix_panic("page fault in system process", pr->p_endpoint); return; } /* Save pagefault details, suspend process, * add process to pagefault chain, * and tell VM there is a pagefault to be * handled. */ pr->p_pagefault.pf_virtual = pagefault_cr2; pr->p_pagefault.pf_flags = trap_errno; pr->p_nextpagefault = pagefaults; pagefaults = pr; lock_notify(HARDWARE, VM_PROC_NR); pagefault_count = 0; #if 0 kprintf("pagefault for process %d ('%s'), pc = 0x%x\n", pr->p_endpoint, pr->p_name, pr->p_reg.pc); proc_stacktrace(pr); #endif return; }
int mconsole_notify(char *sock_name, int type, const void *data, int len) { struct sockaddr_un target; struct mconsole_notify packet; int n, err = 0; lock_notify(); if (notify_sock < 0) { notify_sock = socket(PF_UNIX, SOCK_DGRAM, 0); if (notify_sock < 0) { err = -errno; printk(UM_KERN_ERR "mconsole_notify - socket failed, " "errno = %d\n", errno); } } unlock_notify(); if (err) return err; target.sun_family = AF_UNIX; strcpy(target.sun_path, sock_name); packet.magic = MCONSOLE_MAGIC; packet.version = MCONSOLE_VERSION; packet.type = type; len = (len > sizeof(packet.data)) ? sizeof(packet.data) : len; packet.len = len; memcpy(packet.data, data, len); err = 0; len = sizeof(packet) + packet.len - sizeof(packet.data); n = sendto(notify_sock, &packet, len, 0, (struct sockaddr *) &target, sizeof(target)); if (n < 0) { err = -errno; printk(UM_KERN_ERR "mconsole_notify - sendto failed, " "errno = %d\n", errno); } return err; }
void cpu_thread::on_stop() { state += cpu_flag::exit; lock_notify(); }
void cpu_thread::run() { state -= cpu_flag::stop; lock_notify(); }