//----------------------------------------------------------------------------------------------------// // @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; }
//----------------------------------------------------------------------------------------------------// // @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 ; }