//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;
				}
			}
		}
	}
}
예제 #2
0
파일: scheduler.c 프로젝트: robertsami/proj
/*
 * 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();
}
예제 #3
0
/**
 * 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);
}
예제 #5
0
//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);
		}
	}
}
예제 #6
0
/**
 * 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;
}
예제 #7
0
/**
 * 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;
}
예제 #8
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);
}
예제 #10
0
파일: MODR1.C 프로젝트: fhamilt1/cs450
/**
	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