void erts_do_exit_process(ErlProcess* p, Eterm reason) { #if (DEBUG_OP == 1) char buf[45]; sprintf(buf, "process %d exited with reason %d\n", p->id, reason); debug(buf); #endif p->flags |= F_EXITING; //cancel timer; erts_cancel_timer(&p->timer); //delete potential interrupts delete_interrupt(p->id); //propagate information if(reason != atom_normal) { ErtsLink* link = p->links; Eterm* hp = (Eterm*)pvPortMalloc(4*sizeof(Eterm)); hp[0] = make_arityval(3); hp[1] = atom_EXIT; hp[2] = p->id; hp[3] = reason; Eterm exit_message = make_tuple(hp); while(link != NULL) { ErlProcess* linked = (ErlProcess*)&proc_tab[pid2pix(link->pid)]; if(!(linked->flags & F_EXITING)) { erts_remove_link(&linked->links, p->id); } if(linked->flags & F_TRAP_EXIT && reason != atom_kill) { erts_send_message(p, link->pid, exit_message, 0); } else { if(!(linked->flags & F_EXITING)) { erts_do_exit_process(linked, reason); } } link = link->next; } vPortFree(hp); } //clean flags since they will be reused free_process(p); suspended++; vTaskSuspend(*(p->handle)); continued++; }
/* Execute one instruction from each running context. */ void ke_run(void) { struct ctx_t *ctx, *ctx_trav; int flag = 0; /* Run an instruction from every running process */ for (ctx = ke->running_list_head; ctx; ctx = ctx->running_next) { int i; //printf ("out - %p\n", ctx); for ( i = 0 ; i < ctx->instr_slice ; ++i) { if((no_instructions == get_least_interrupt_time()) && least_interrupt!=NULL){ struct interrupt_t* curr_interrupt = get_least_interrupt(); curr_interrupt->details->p_ctx->blocked = 0; printf("program with pid %d unblocked at %d\n",curr_interrupt->details->p_ctx->pid,no_instructions); delete_interrupt(curr_interrupt); } if(!ctx->blocked){ ctx_execute_inst(ctx); no_instructions++; printf("%d,%d\n",ctx->pid,no_instructions); } if (ctx!=ke->running_list_head) break; } } /* Free finished contexts */ while (ke->finished_list_head) ctx_free(ke->finished_list_head); /* Process list of suspended contexts */ ke_process_events(); }