+ error = KERN_INVALID_ARGUMENT;
+ }
+
+ task_unlock(task);
+ return (error);
+}
+
+void
+task_vtimer_set(
+ task_t task,
+ integer_t which)
+{
+ thread_t thread;
+
+ /* assert(task == current_task()); */ /* bogus assert 4803227 4807483 */
+
+ task_lock(task);
+
+ task->vtimers |= which;
+
+ switch (which) {
+
+ case TASK_VTIMER_USER:
+ queue_iterate(&task->threads, thread, thread_t, task_threads) {
+ thread->vtimer_user_save = timer_grab(&thread->user_timer);
+ }
+ break;
+
+ case TASK_VTIMER_PROF:
+ queue_iterate(&task->threads, thread, thread_t, task_threads) {
+ thread->vtimer_prof_save = timer_grab(&thread->user_timer);
+ thread->vtimer_prof_save += timer_grab(&thread->system_timer);
+ }
+ break;
+
+ case TASK_VTIMER_RLIM:
+ queue_iterate(&task->threads, thread, thread_t, task_threads) {
+ thread->vtimer_rlim_save = timer_grab(&thread->user_timer);
+ thread->vtimer_rlim_save += timer_grab(&thread->system_timer);
+ }
+ break;
+ }
+
+ task_unlock(task);
+}
+
+void
+task_vtimer_clear(
+ task_t task,
+ integer_t which)
+{
+ assert(task == current_task());
+
+ task_lock(task);
+
+ task->vtimers &= ~which;
+
+ task_unlock(task);
+}
+
+void
+task_vtimer_update(
+__unused
+ task_t task,
+ integer_t which,
+ uint32_t *microsecs)
+{
+ thread_t thread = current_thread();
+ uint32_t tdelt;
+ clock_sec_t secs;
+ uint64_t tsum;
+
+ assert(task == current_task());
+
+ assert(task->vtimers & which);
+
+ secs = tdelt = 0;
+
+ switch (which) {
+
+ case TASK_VTIMER_USER:
+ tdelt = (uint32_t)timer_delta(&thread->user_timer,
+ &thread->vtimer_user_save);
+ absolutetime_to_microtime(tdelt, &secs, microsecs);
+ break;
+
+ case TASK_VTIMER_PROF:
+ tsum = timer_grab(&thread->user_timer);
+ tsum += timer_grab(&thread->system_timer);
+ tdelt = (uint32_t)(tsum - thread->vtimer_prof_save);
+ absolutetime_to_microtime(tdelt, &secs, microsecs);
+ /* if the time delta is smaller than a usec, ignore */
+ if (*microsecs != 0)
+ thread->vtimer_prof_save = tsum;
+ break;
+
+ case TASK_VTIMER_RLIM:
+ tsum = timer_grab(&thread->user_timer);
+ tsum += timer_grab(&thread->system_timer);
+ tdelt = (uint32_t)(tsum - thread->vtimer_rlim_save);
+ thread->vtimer_rlim_save = tsum;
+ absolutetime_to_microtime(tdelt, &secs, microsecs);
+ break;