예제 #1
0
//----------------------------------------------------------------------------------------------------//
//  @func - sys_sleep
//! @desc 
//!   Suspend current process for specified number of ticks
//!   1 tick = one timer interrupt received by the kernel
//! @param
//!   - ms is the number of milliseconds to sleep this task.
//! @return
//!   - Number of milliseconds unslept for. 0 - complete success
//! @note
//!   - None
//----------------------------------------------------------------------------------------------------//
unsigned sys_sleep (unsigned int ms)
{
    pid_t cpid = sys_get_currentPID();
    
    if (add_tmr (cpid, ms) == -1)
        return ms;

    current_process->state = PROC_DELAY;
    suspend ();

    // Awaken here after timeout

    return 0;
}
예제 #2
0
//----------------------------------------------------------------------------------------------------//
//  @func - sys_sem_timedwait
//! @desc
//!   Semaphore timedwait operation
//!   - Decrement semaphore value
//!   - If value < 0, block with a timeout, as specified by the second parameters 'ms'
//! @param
//!   - sem is the semaphore reference
//!   - ms is the amount of time to be blocked on the semaphore in milliseconds
//! @return
//!   - 0 on success, -1 on failure
//!     errno set to,
//!     EINVAL - If the semaphore identifier does not refer to a valid semaphore
//!     ETIMEDOUT - The semaphore could not be locked before the specified timeout expired.
//!     EIDRM - If the semaphore was forcibly removed from the system
//! @note
//!   - Depends on CONFIG_TIME being true
//----------------------------------------------------------------------------------------------------//
int sys_sem_timedwait (sem_t* sem, unsigned int ms)
{
    sem_info_t* seminfo = get_sem_by_semt (sem);
    process_struct *self;

    if (seminfo == NULL) {
        kerrno = EINVAL;
	return -1;
    }

    seminfo->sem_value-- ;                                              // Decrement the resource count
    if (seminfo->sem_value < 0)  {                                      // If resource unavailable
        self = current_process;
        add_tmr (self->pid, ms);                                        // Add a timer for self
        process_block (&(seminfo->sem_wait_q), PROC_TIMED_WAIT);

                                                                        // Return here on unblock
        if (self->timeout) {                                            // Timeout during semaphore wait. Return with error
            seminfo->sem_value++;                                       // Restore sem value
            self->timeout = 0;
            kerrno = ETIMEDOUT;
            return -1;
        } else {
            remove_tmr (self->pid);                                     // We managed to acquire the semaphore. Remove associated timer
        }
    }

    // Special. Not part of posix specification. If the semaphore was force_destroy'ed
    // then the process has not really acquired the semaphore when it was unblocked,
    // but rather it is in an interrupted situation. Signal error in this case

    if (seminfo->sem_id == -1) {                                        // If sem invalidated by now
        kerrno = EIDRM;
	return -1;
    }

    return 0 ;
}