//Instrucción privilegiada void signal(char* id){ t_semaforo* semaforo = get_semaforo_by_ID(semaforo_control_list, id); semaforo->sem_value ++; PCB* nextPcb; //TODO: Guti - TESTEAR if(!queue_is_empty(semaforo->blocked_process_queue)){ //Poner en cola de ready al próximo proceso bloqueado nextPcb = queue_pop(semaforo->blocked_process_queue); if(is_program_alive(nextPcb->processId)){ set_pcb_READY(nextPcb); } else{ umc_notificarFinDePrograma(nextPcb->processId); while(!queue_is_empty(semaforo->blocked_process_queue)){ if(!is_program_alive(nextPcb->processId)){ free_pcb(nextPcb); nextPcb = queue_pop(semaforo->blocked_process_queue); } else{ set_pcb_READY(nextPcb); break; } } } } }
/* * The scheduler must be called within a critical section since it * changes global state, and since dispatch() needs to be called * within a critical section. Disable_count for current_running is * checked to see that it's != 0. The scheduler also handles saving * the current interrupt controller mask (which is later restored in * setup_current_running()). */ void scheduler(void) { unsigned long long t; /* * Save hardware interrupt mask in the pcb struct. The mask * will be restored in setup_current_running() */ current_running->int_controller_mask = ((uint16_t)inb(0x21)) | (((uint16_t)inb(0xa1)) << 8); ASSERT(current_running->disable_count != 0); do { switch (current_running->status) { case SLEEPING: t = get_timer(); if (current_running->wakeup_time < t) current_running->status = RUNNING; /* FALLTHROUGH */ case RUNNING: /* pick the next job to run */ current_running = current_running->next; break; case BLOCKED: /* if no more jobs, halt */ if (current_running->next == current_running) { HALT("No more jobs."); } current_running = current_running->next; /* Remove the job from the ready queue */ remove_job(current_running->previous); break; case EXITED: /* if no more jobs, loop forever */ if (current_running->next == current_running) { HALT("No more jobs."); } current_running = current_running->next; /* * Remove pcb from the ready queue and insert * it into the free_pcb queue */ free_pcb(current_running->previous); break; default: HALT("Invalid job status."); break; } } while (current_running->status != RUNNING); /* .. and run it */ dispatch(); }
/** * This function will inform the application that phone is either * 1. restarting or * 2. failing over/ falling back * * @note detection of CCM reboot will be handled by PUBLISH ETag mechanism. * * @param[in] none * * @return none */ void publish_reset (void) { ccsip_publish_cb_t *pcb_p; pcb_p = (ccsip_publish_cb_t *)sll_next(s_PCB_list, NULL); while (pcb_p != NULL) { send_resp_to_app(PUBLISH_FAILED_RESET, pcb_p->pub_handle, pcb_p->app_handle, pcb_p->callback_task, pcb_p->resp_msg_id); free_pcb(pcb_p); pcb_p = (ccsip_publish_cb_t *)sll_next(s_PCB_list, NULL); } }
//Toma el primer programa de la cola de READY y lo envía a cpu para su ejecución void set_next_pcb_RUNNING(int cpu_id){ t_CPU* cpu = get_CPU_by_socket(cpu_id); //TODO: Guti - TESTEAR PCB* pcbCandidate = queue_pop(READY_Process_Queue); while(!is_program_alive(pcbCandidate->processId)){ free_pcb(pcbCandidate); pcbCandidate = queue_pop(READY_Process_Queue); } cpu->PID = pcbCandidate->processId; //Asigno a la estructura CPU el id del proceso que va a ejecutar list_add(RUNNING_Process_List, pcbCandidate); cpu_sendPCB(pcbCandidate, cpu->cpuSocket); }
//Ejecuta TODAS las IO encoladas del dispositivo y las encola en READY void attend_blocked_processes(t_IO_Device* io_device){ PCB* pcb; while(queue_size(io_device->BlockedProcessesQueue) > 0){ pcb = queue_pop(io_device->BlockedProcessesQueue); if(is_program_alive(pcb->processId)){ execute_process_IO(io_device->sleepTime * pcb->sleepUnits); set_pcb_READY(pcb); } else{ free_pcb(pcb); log_warning(nucleo_logger, "Programa %d no ejecuta E/S por desconexión de consola", pcb->processId); } } }
/** * This function will process the response to PUBLISH request sent by us. * * @param[in] pSipMessage - pointer to received SIP response msg * * @return SIP_OK if it successfully processes the response. * SIP_ERROR if it fails to process the response. * * @pre (pSipMessage != NULL) */ int publish_handle_ev_sip_response (sipMessage_t *pSipMessage) { static const char fname[] = "publish_handle_ev_sip_response"; const char *callID_p = NULL; int response_code = 0; const char *expires = NULL; const char *sip_etag = NULL; long expiry_time; pub_req_t *msg_p; ccsip_publish_cb_t *pcb_p; int entity_tag_size; callID_p = sippmh_get_cached_header_val(pSipMessage, CALLID); if (!callID_p) { CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Cannot obtain SIP Call ID.\n", fname); return SIP_ERROR; } /* * Find PCB by Call-ID. The Call-IDs generated by the phone ae unique. */ pcb_p = find_pcb_by_sip_callid(callID_p); if (pcb_p == NULL) { CCSIP_DEBUG_ERROR(SIP_F_PREFIX"No matching PCB found\n", fname); return SIP_ERROR; } /* * Cancel the retry_timer and set the retx_flag to FALSE. */ sip_platform_msg_timer_subnot_stop(&(pcb_p->retry_timer)); pcb_p->hb.retx_flag = FALSE; // Parse the return code (void) sipGetResponseCode(pSipMessage, &response_code); if (response_code >= 200) { pcb_p->outstanding_trxn = FALSE; } if ((response_code == SIP_CLI_ERR_UNAUTH) || (response_code == SIP_CLI_ERR_PROXY_REQD)) { CCSIP_DEBUG_TASK(DEB_F_PREFIX"Authentication Required\n", DEB_F_PREFIX_ARGS(SIP_PUB, fname)); if (ccsip_common_util_generate_auth(pSipMessage, &pcb_p->hb, SIP_METHOD_PUBLISH, response_code, pcb_p->full_ruri) == TRUE) { if (sipSPISendPublish(pcb_p, TRUE) == TRUE) { pcb_p->outstanding_trxn = TRUE; CCSIP_DEBUG_TASK(DEB_F_PREFIX"sent request with Auth header\n", DEB_F_PREFIX_ARGS(SIP_PUB, fname)); return SIP_OK; } } /* * Since we failed to resend the PUBLISH request, free up the PCB and let the app know. */ send_resp_to_app(PUBLISH_FAILED_SEND, pcb_p->pub_handle, pcb_p->app_handle, pcb_p->callback_task, pcb_p->resp_msg_id); free_pcb (pcb_p); CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to respond to auth challenge\n", fname); return SIP_ERROR; } /* * if response code is 423, grab Min-Expires and send new PUBLISH with new expires value */ if (response_code == SIP_CLI_ERR_INTERVAL_TOO_SMALL) { expires = sippmh_get_header_val(pSipMessage, (const char *)SIP_HEADER_MIN_EXPIRES, NULL); if (expires) { expiry_time = strtoul(expires, NULL, 10); //ensure new Min-Expires is > what we set before in Expires if ((long) expiry_time > pcb_p->hb.expires) { pcb_p->hb.expires = expiry_time; pcb_p->hb.orig_expiration = expiry_time; } if (sipSPISendPublish(pcb_p, FALSE) == TRUE) { pcb_p->outstanding_trxn = TRUE; CCSIP_DEBUG_TASK(DEB_F_PREFIX"sent request with increased expires\n", DEB_F_PREFIX_ARGS(SIP_PUB, fname)); return SIP_OK; } } /* * Since we failed to resend the PUBLISH request, free up the PCB and let the app know. */ send_resp_to_app(PUBLISH_FAILED_SEND, pcb_p->pub_handle, pcb_p->app_handle, pcb_p->callback_task, pcb_p->resp_msg_id); free_pcb (pcb_p); CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to respond to 423\n", fname); return SIP_ERROR; } /* * if the response_code is > 299, free up the PCB and let the app know. */ if (response_code > 299) { send_resp_to_app(response_code, pcb_p->pub_handle, pcb_p->app_handle, pcb_p->callback_task, pcb_p->resp_msg_id); free_pcb (pcb_p); CCSIP_DEBUG_TASK(DEB_F_PREFIX"received %d response\n", DEB_F_PREFIX_ARGS(SIP_PUB, fname), response_code); return SIP_OK; } /* * if the response is < 200, do nothing. */ if (response_code < 200) { CCSIP_DEBUG_TASK(DEB_F_PREFIX"received %d response\n", DEB_F_PREFIX_ARGS(SIP_PUB, fname), response_code); return SIP_OK; } /* * If it is PUBLISH remove operation, free up PCB */ if (pcb_p->hb.orig_expiration == 0) { send_resp_to_app(response_code, pcb_p->pub_handle, pcb_p->app_handle, pcb_p->callback_task, pcb_p->resp_msg_id); free_pcb (pcb_p); CCSIP_DEBUG_TASK(DEB_F_PREFIX"removed PCB as this was a terminating PUBLISH\n", DEB_F_PREFIX_ARGS(SIP_PUB, fname)); return SIP_OK; } /* * extract Expires and SIP-ETag headers and save them. */ expires = sippmh_get_header_val(pSipMessage, SIP_HEADER_EXPIRES, NULL); if (expires) { expiry_time = strtoul(expires, NULL, 10); pcb_p->hb.expires = expiry_time; } sip_etag = sippmh_get_header_val(pSipMessage, SIP_HEADER_SIPETAG, NULL); if (sip_etag != NULL) { cpr_free(pcb_p->entity_tag); entity_tag_size = strlen(sip_etag) + 1; pcb_p->entity_tag = cpr_malloc(entity_tag_size); if (pcb_p->entity_tag != NULL) { sstrncpy(pcb_p->entity_tag, sip_etag, entity_tag_size); } else { free_pcb (pcb_p); send_resp_to_app(PUBLISH_FAILED_NORESOURCE, pcb_p->pub_handle, pcb_p->app_handle, pcb_p->callback_task, pcb_p->resp_msg_id); CCSIP_DEBUG_ERROR(SIP_F_PREFIX"memory allocation failed\n", fname); return SIP_ERROR; } } /* * If there are no pending requests, provide the response to the application. */ msg_p = (pub_req_t *)sll_next(pcb_p->pending_reqs, NULL); if (msg_p != NULL) { (void)sll_remove(pcb_p->pending_reqs, msg_p); (void)publish_handle_ev_app_publish(msg_p); cpr_free(msg_p); return SIP_OK; } send_resp_to_app(response_code, pcb_p->pub_handle, pcb_p->app_handle, pcb_p->callback_task, pcb_p->resp_msg_id); CCSIP_DEBUG_TASK(DEB_F_PREFIX"sent response %d to app\n", DEB_F_PREFIX_ARGS(SIP_PUB, fname), response_code); return SIP_OK; }
/** * This function will handle retry-timer expiration * * @param[in] handle - handle to PCB * * @return 0 if it is successful in handling the timer * Otherwise, -1 is returned * * @pre (handle != 0) */ int publish_handle_retry_timer_expire (uint32_t handle) { static const char fname[] = "publish_handle_retry_timer_expire"; pub_handle_t pub_handle = handle; ccsip_publish_cb_t *pcb_p; uint32_t max_retx = 0; uint32_t time_t1 = 0; uint32_t time_t2 = 0; uint32_t timeout = 0; /* * find the PCB */ pcb_p = find_pcb(pub_handle); if (pcb_p == NULL) { /* No PCB. So do nothing. */ return 0; } if (pcb_p->hb.retx_flag == FALSE) { /* probably we got some response. so do nothing */ return 0; } config_get_value(CFGID_SIP_RETX, &max_retx, sizeof(max_retx)); if (max_retx > MAX_NON_INVITE_RETRY_ATTEMPTS) { max_retx = MAX_NON_INVITE_RETRY_ATTEMPTS; } if (pcb_p->hb.retx_counter < max_retx) { pcb_p->hb.retx_counter++; config_get_value(CFGID_TIMER_T1, &time_t1, sizeof(time_t1)); timeout = time_t1 * (1 << pcb_p->hb.retx_counter); config_get_value(CFGID_TIMER_T2, &time_t2, sizeof(time_t2)); if (timeout > time_t2) { timeout = time_t2; } CCSIP_DEBUG_TASK(DEB_F_PREFIX"Resending message #%d\n", DEB_F_PREFIX_ARGS(SIP_PUB, fname), pcb_p->hb.retx_counter); if (sipTransportSendMessage(NULL, pcb_p->retry_timer.message_buffer, pcb_p->retry_timer.message_buffer_len, pcb_p->retry_timer.message_type, &(pcb_p->retry_timer.ipaddr), pcb_p->retry_timer.port, FALSE, TRUE, timeout, pcb_p) < 0) { /* free up PCB and respond with error */ send_resp_to_app(PUBLISH_FAILED_SEND, pcb_p->pub_handle, pcb_p->app_handle, pcb_p->callback_task, pcb_p->resp_msg_id); free_pcb (pcb_p); CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to send message", fname); return (-1); } } else { /* * send timeout response and free up PCB */ send_resp_to_app(SIP_CLI_ERR_REQ_TIMEOUT, pcb_p->pub_handle, pcb_p->app_handle, pcb_p->callback_task, pcb_p->resp_msg_id); free_pcb (pcb_p); CCSIP_DEBUG_ERROR(SIP_F_PREFIX"reached MAX retries", fname); } return 0; }
/** * This function will process SIPSPI_EV_CC_PUBLISH posted by applications. * If there is an outstanding transaction, it will hold the request in the pending list. * * @param[in] buf - inter-process message buffer. * * @return SIP_OK if it successfully processes the request. * SIP_ERROR if it fails to process the request. * SIP_DEFER if it defers the processing. * * @note This will not free buf. * * @pre (buf != NULL) */ int publish_handle_ev_app_publish (cprBuffer_t buf) { static const char fname[] = "publish_handle_ev_app_publish"; pub_req_t *msg_p = (pub_req_t *)buf; ccsip_publish_cb_t *pcb_p; /* * If this is initial PUBLISH, allocate a PCB. * Otherwise, look up for PCB based on pub_handle. */ if (msg_p->pub_handle != NULL_PUBLISH_HANDLE) { pcb_p = find_pcb(msg_p->pub_handle); if (pcb_p == NULL) { send_resp_to_app(PUBLISH_FAILED_NOCONTEXT, msg_p->pub_handle, msg_p->app_handle, msg_p->callback_task, msg_p->resp_msg_id); free_event_data(msg_p->event_data_p); CCSIP_DEBUG_ERROR(SIP_F_PREFIX "Modification PUBLISH cannot be sent as the PCB is missing\n", fname); return SIP_ERROR; } /* * Check if there is an outstanding transaction. * if so, put the request in pending request queue. */ if (pcb_p->outstanding_trxn == TRUE) { if (append_pending_reqs(pcb_p, msg_p) == TRUE) { CCSIP_DEBUG_TASK(DEB_F_PREFIX"deffering as there is an outstanding transaction\n", DEB_F_PREFIX_ARGS(SIP_PUB, fname)); return SIP_DEFER; } /* free up PCB and respond with error */ free_pcb (pcb_p); send_resp_to_app(PUBLISH_FAILED_NORESOURCE, msg_p->pub_handle, msg_p->app_handle, msg_p->callback_task, msg_p->resp_msg_id); free_event_data(msg_p->event_data_p); CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Queueing outgoing PUBLISH request failed\n", fname); return SIP_ERROR; } /* * if event_data_p is NULL, this is terminating PUBLISH. * otherwise, it is a modifying PUBLISH. */ free_event_data(pcb_p->hb.event_data_p); pcb_p->hb.event_data_p = msg_p->event_data_p; if ((msg_p->event_data_p == NULL) && (msg_p->expires == 0)) { // removing PUBLISH pcb_p->hb.orig_expiration = 0; } } else { pcb_p = get_new_pcb(); if (pcb_p == NULL) { send_resp_to_app(PUBLISH_FAILED_NORESOURCE, msg_p->pub_handle, msg_p->app_handle, msg_p->callback_task, msg_p->resp_msg_id); free_event_data(msg_p->event_data_p); CCSIP_DEBUG_ERROR(SIP_F_PREFIX"PCB allocation failed\n", fname); return SIP_ERROR; } pcb_p->app_handle = msg_p->app_handle; sstrncpy(pcb_p->ruri, msg_p->ruri, MAX_URI_LENGTH); sstrncpy(pcb_p->esc, msg_p->esc, MAX_URI_LENGTH); pcb_p->hb.orig_expiration = msg_p->expires; pcb_p->hb.event_type = msg_p->event_type; pcb_p->hb.event_data_p = msg_p->event_data_p; pcb_p->callback_task = msg_p->callback_task; pcb_p->resp_msg_id = msg_p->resp_msg_id; } pcb_p->hb.authen.cred_type = 0; if (sipSPISendPublish(pcb_p, FALSE) == TRUE) { pcb_p->outstanding_trxn = TRUE; outgoingPublishes++; CCSIP_DEBUG_TASK(DEB_F_PREFIX"PUBLISH request sent successfully\n", DEB_F_PREFIX_ARGS(SIP_PUB, fname)); return SIP_OK; } /* free up PCB and respond with error */ free_pcb (pcb_p); send_resp_to_app(PUBLISH_FAILED_SEND, msg_p->pub_handle, msg_p->app_handle, msg_p->callback_task, msg_p->resp_msg_id); CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Failed to send PUBLISH request\n", fname); return SIP_ERROR; }
//Finalizar un proceso void end_process(int PID){ PCB* pcb = remove_pcb_by_ID(General_Process_List, PID); remove_pcb_by_ID(RUNNING_Process_List, PID); free_pcb(pcb); }
/** Procedure: commandCleanup Purpose: Free Memory that is still allocated Parameters: None Return value: None Calls: sys_free_mem, errorCheck Globals: error Errors: None **/ void commandCleanup(){ //int error = sys_free_mem(userCommand); //!NOTE! - Display Errors //error = errorCheck(error); //printf("The error number is %d.\n", error); //test3------------------------------------------ LLitem * tempCurr; int queueInt= 0; if(queueInt == 0 || queueInt == 4){ tempCurr = head4; if(tempCurr != NULL){ do{ error = remove_pcb(tempCurr->val); if(error !=0){ break; } else{ error = free_pcb(tempCurr->val); if(error != 0){ break; } else{ tempCurr = tempCurr->next; } } }while(tempCurr != head4 && tempCurr != NULL); } } if(queueInt == 0 || queueInt == 5){ tempCurr = head5; if(tempCurr != NULL){ do{ error = remove_pcb(tempCurr->val); if(error !=0){ break; } else{ error = free_pcb(tempCurr->val); if(error != 0){ break; } else{ tempCurr = tempCurr->next; } } }while(tempCurr != head5&& tempCurr != NULL); } } if(queueInt == 0 || queueInt == 6){ tempCurr = head6; if(tempCurr != NULL){ do{ error = remove_pcb(tempCurr->val); if(error !=0){ break; } else{ error = free_pcb(tempCurr->val); if(error != 0){ break; } else{ tempCurr = tempCurr->next; } } }while(tempCurr != head6&& tempCurr != NULL); } } if(queueInt == 0 || queueInt == 7){ tempCurr = head7; if(tempCurr != NULL){ do{ error = remove_pcb(tempCurr->val); if(error !=0){ break; } else{ error = free_pcb(tempCurr->val); if(error != 0){ break; } else{ tempCurr = tempCurr->next; } } }while(tempCurr != head7&& tempCurr != NULL); } } }//end commandCleanup