/* * Copy in the relative timeout provided by the application and convert it * to an absolute timeout. */ static int get_timeout(void *lx_timeout, timestruc_t *timeout) { timestruc_t now; if (get_udatamodel() == DATAMODEL_NATIVE) { if (copyin(lx_timeout, timeout, sizeof (timestruc_t))) return (EFAULT); } #ifdef _SYSCALL32_IMPL else { timestruc32_t timeout32; if (copyin(lx_timeout, &timeout32, sizeof (timestruc32_t))) return (EFAULT); timeout->tv_sec = (time_t)timeout32.tv_sec; timeout->tv_nsec = timeout32.tv_nsec; } #endif gethrestime(&now); if (itimerspecfix(timeout)) return (EINVAL); timespecadd(timeout, &now); return (0); }
/* * Helper function for semop - copies in the provided timespec and * computes the absolute future time after which we must return. */ static int compute_timeout(timespec_t **tsp, timespec_t *ts, timespec_t *now, timespec_t *timeout) { model_t datamodel = get_udatamodel(); if (datamodel == DATAMODEL_NATIVE) { if (copyin(timeout, ts, sizeof (timespec_t))) return (EFAULT); } else { timespec32_t ts32; if (copyin(timeout, &ts32, sizeof (timespec32_t))) return (EFAULT); TIMESPEC32_TO_TIMESPEC(ts, &ts32) } if (itimerspecfix(ts)) return (EINVAL); /* * Convert the timespec value into absolute time. */ timespecadd(ts, now); *tsp = ts; return (0); }
int lwp_timer_copyin(lwp_timer_t *lwptp, timespec_t *tsp) { timespec_t now; int error = 0; if (tsp == NULL) /* not really an error, just need to bzero() */ goto err; lwptp->lwpt_timecheck = timechanged; /* do this before gethrestime() */ gethrestime(&now); /* do this before copyin() */ if (curproc->p_model == DATAMODEL_NATIVE) { if (copyin(tsp, &lwptp->lwpt_rqtime, sizeof (timespec_t))) { error = EFAULT; goto err; } } else { timespec32_t ts32; if (copyin(tsp, &ts32, sizeof (timespec32_t))) { error = EFAULT; goto err; } TIMESPEC32_TO_TIMESPEC(&lwptp->lwpt_rqtime, &ts32); } if (itimerspecfix(&lwptp->lwpt_rqtime)) { error = EINVAL; goto err; } /* * Unless the requested timeout is zero, * get the precise future (absolute) time at * which we are to time out and return ETIME. * We must not return ETIME before that time. */ if (lwptp->lwpt_rqtime.tv_sec == 0 && lwptp->lwpt_rqtime.tv_nsec == 0) { bzero(lwptp, sizeof (lwp_timer_t)); lwptp->lwpt_imm_timeout = 1; } else { lwptp->lwpt_thread = curthread; lwptp->lwpt_tsp = tsp; lwptp->lwpt_time_error = 0; lwptp->lwpt_id = 0; lwptp->lwpt_imm_timeout = 0; timespecadd(&lwptp->lwpt_rqtime, &now); } return (0); err: bzero(lwptp, sizeof (lwp_timer_t)); lwptp->lwpt_time_error = error; return (error); }