static void get_cpu_itimer(struct task_struct *tsk, unsigned int clock_id, struct itimerval *const value) { u64 val, interval; struct cpu_itimer *it = &tsk->signal->it[clock_id]; spin_lock_irq(&tsk->sighand->siglock); val = it->expires; interval = it->incr; if (val) { struct task_cputime cputime; u64 t; thread_group_cputimer(tsk, &cputime); if (clock_id == CPUCLOCK_PROF) t = cputime.utime + cputime.stime; else /* CPUCLOCK_VIRT */ t = cputime.utime; if (val < t) /* about to fire */ val = TICK_NSEC; else val -= t; } spin_unlock_irq(&tsk->sighand->siglock); value->it_value = ns_to_timeval(val); value->it_interval = ns_to_timeval(interval); }
static void set_cpu_itimer(struct task_struct *tsk, unsigned int clock_id, const struct itimerval *const value, struct itimerval *const ovalue) { u64 oval, nval, ointerval, ninterval; struct cpu_itimer *it = &tsk->signal->it[clock_id]; /* * Use the to_ktime conversion because that clamps the maximum * value to KTIME_MAX and avoid multiplication overflows. */ nval = ktime_to_ns(timeval_to_ktime(value->it_value)); ninterval = ktime_to_ns(timeval_to_ktime(value->it_interval)); spin_lock_irq(&tsk->sighand->siglock); oval = it->expires; ointerval = it->incr; if (oval || nval) { if (nval > 0) nval += TICK_NSEC; set_process_cpu_timer(tsk, clock_id, &nval, &oval); } it->expires = nval; it->incr = ninterval; trace_itimer_state(clock_id == CPUCLOCK_VIRT ? ITIMER_VIRTUAL : ITIMER_PROF, value, nval); spin_unlock_irq(&tsk->sighand->siglock); if (ovalue) { ovalue->it_value = ns_to_timeval(oval); ovalue->it_interval = ns_to_timeval(ointerval); } }
/* Locking: Caller holds q->vb_lock */ static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b, struct videobuf_buffer *vb, enum v4l2_buf_type type) { MAGIC_CHECK(vb->magic, MAGIC_BUFFER); MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); b->index = vb->i; b->type = type; b->memory = vb->memory; switch (b->memory) { case V4L2_MEMORY_MMAP: b->m.offset = vb->boff; b->length = vb->bsize; break; case V4L2_MEMORY_USERPTR: b->m.userptr = vb->baddr; b->length = vb->bsize; break; case V4L2_MEMORY_OVERLAY: b->m.offset = vb->boff; break; case V4L2_MEMORY_DMABUF: /* DMABUF is not handled in videobuf framework */ break; } b->flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; if (vb->map) b->flags |= V4L2_BUF_FLAG_MAPPED; switch (vb->state) { case VIDEOBUF_PREPARED: case VIDEOBUF_QUEUED: case VIDEOBUF_ACTIVE: b->flags |= V4L2_BUF_FLAG_QUEUED; break; case VIDEOBUF_ERROR: b->flags |= V4L2_BUF_FLAG_ERROR; /* fall through */ case VIDEOBUF_DONE: b->flags |= V4L2_BUF_FLAG_DONE; break; case VIDEOBUF_NEEDS_INIT: case VIDEOBUF_IDLE: /* nothing */ break; } b->field = vb->field; b->timestamp = ns_to_timeval(vb->ts); b->bytesused = vb->size; b->sequence = vb->field_count >> 1; }
void get_dilated_time(struct task_struct * task,struct timeval* tv) { s64 temp_past_physical_time; do_gettimeofday(tv); if(task->virt_start_time != 0){ if (task->group_leader != task) { //use virtual time of the leader thread task = task->group_leader; } s64 now = timeval_to_ns(tv); s32 rem; s64 real_running_time; s64 dilated_running_time; //spin_lock(&task->dialation_lock); if(task->freeze_time == 0){ real_running_time = now - task->virt_start_time; } else{ real_running_time = task->freeze_time - task->virt_start_time; } //real_running_time = now - task->virt_start_time; //if (task->freeze_time != 0) // temp_past_physical_time = task->past_physical_time + (now - task->freeze_time); //else temp_past_physical_time = task->past_physical_time; if (task->dilation_factor > 0) { dilated_running_time = div_s64_rem( (real_running_time - temp_past_physical_time)*1000 ,task->dilation_factor,&rem) + task->past_virtual_time; now = dilated_running_time + task->virt_start_time; } else if (task->dilation_factor < 0) { dilated_running_time = div_s64_rem( (real_running_time - temp_past_physical_time)*(task->dilation_factor*-1),1000,&rem) + task->past_virtual_time; now = dilated_running_time + task->virt_start_time; } else { dilated_running_time = (real_running_time - temp_past_physical_time) + task->past_virtual_time; now = dilated_running_time + task->virt_start_time; } if(task->freeze_time == 0){ task->past_physical_time = real_running_time; task->past_virtual_time = dilated_running_time; } //spin_unlock(&task->dialation_lock); *tv = ns_to_timeval(now); } return; }
static void sec_gpu_utilization_handler(void *arg) { u64 time_now = get_time_ns(); struct timeval working_time; struct timeval period_time; mutex_lock(&time_data_lock); if (total_work_time == 0) { if (!hw_start_time) { mutex_unlock(&time_data_lock); sec_gpu_dvfs_handler(0); return; } } if (hw_start_time != 0) { total_work_time += (time_now - hw_start_time); hw_start_time = time_now; } /* changed way to compute the utilization */ working_time = (struct timeval)ns_to_timeval(total_work_time); period_time = (struct timeval)ns_to_timeval(time_now - period_start_time); sgx_gpu_utilization = (normalize_time(working_time) * 256) / normalize_time(period_time); total_work_time = 0; period_start_time = time_now; mutex_unlock(&time_data_lock); sec_gpu_dvfs_handler(sgx_gpu_utilization); }
static int cpia2_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) { struct camera_data *cam = video_drvdata(file); int frame; if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || buf->memory != V4L2_MEMORY_MMAP) return -EINVAL; frame = find_earliest_filled_buffer(cam); if(frame < 0 && file->f_flags&O_NONBLOCK) return -EAGAIN; if(frame < 0) { /* Wait for a frame to become available */ struct framebuf *cb=cam->curbuff; mutex_unlock(&cam->v4l2_lock); wait_event_interruptible(cam->wq_stream, !video_is_registered(&cam->vdev) || (cb=cam->curbuff)->status == FRAME_READY); mutex_lock(&cam->v4l2_lock); if (signal_pending(current)) return -ERESTARTSYS; if (!video_is_registered(&cam->vdev)) return -ENOTTY; frame = cb->num; } buf->index = frame; buf->bytesused = cam->buffers[buf->index].length; buf->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE | V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; buf->field = V4L2_FIELD_NONE; buf->timestamp = ns_to_timeval(cam->buffers[buf->index].ts); buf->sequence = cam->buffers[buf->index].seq; buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer; buf->length = cam->frame_size; buf->reserved2 = 0; buf->request_fd = 0; memset(&buf->timecode, 0, sizeof(buf->timecode)); DBG("DQBUF #%d status:%d seq:%d length:%d\n", buf->index, cam->buffers[buf->index].status, buf->sequence, buf->bytesused); return 0; }
int __init ns_to_timeval_init(void) { struct timeval tv; //声明变量,用于保存函数执行结果 const s64 nsec=1001000000; //-1001000000,定义64位有符号整数,作为函数的参数 printk("<0>ns_to_timeval begin.\n"); tv=ns_to_timeval(nsec);//调用函数,将参数表示的时间转换成用timeval表示的时间 printk("the value of the struct timeval is:\n"); printk("the tv_sec value is:%ld\n",tv.tv_sec);//秒数 printk("the tv_usec value is:%ld\n",tv.tv_usec);//微秒数 printk("<0>ns_to_timeval over.\n"); return 0; }
static int cpia2_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf) { struct camera_data *cam = video_drvdata(file); if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || buf->index >= cam->num_frames) return -EINVAL; buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer; buf->length = cam->frame_size; buf->memory = V4L2_MEMORY_MMAP; if(cam->mmapped) buf->flags = V4L2_BUF_FLAG_MAPPED; else buf->flags = 0; buf->flags |= V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; switch (cam->buffers[buf->index].status) { case FRAME_EMPTY: case FRAME_ERROR: case FRAME_READING: buf->bytesused = 0; buf->flags = V4L2_BUF_FLAG_QUEUED; break; case FRAME_READY: buf->bytesused = cam->buffers[buf->index].length; buf->timestamp = ns_to_timeval(cam->buffers[buf->index].ts); buf->sequence = cam->buffers[buf->index].seq; buf->flags = V4L2_BUF_FLAG_DONE; break; } DBG("QUERYBUF index:%d offset:%d flags:%d seq:%d bytesused:%d\n", buf->index, buf->m.offset, buf->flags, buf->sequence, buf->bytesused); return 0; }
/** * __fill_v4l2_buffer() - fill in a struct v4l2_buffer with information to be * returned to userspace */ static void __fill_v4l2_buffer(struct vb2_buffer *vb, void *pb) { struct v4l2_buffer *b = pb; struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); struct vb2_queue *q = vb->vb2_queue; unsigned int plane; /* Copy back data such as timestamp, flags, etc. */ b->index = vb->index; b->type = vb->type; b->memory = vb->memory; b->bytesused = 0; b->flags = vbuf->flags; b->field = vbuf->field; b->timestamp = ns_to_timeval(vb->timestamp); b->timecode = vbuf->timecode; b->sequence = vbuf->sequence; b->reserved2 = 0; b->reserved = 0; if (q->is_multiplanar) { /* * Fill in plane-related data if userspace provided an array * for it. The caller has already verified memory and size. */ b->length = vb->num_planes; for (plane = 0; plane < vb->num_planes; ++plane) { struct v4l2_plane *pdst = &b->m.planes[plane]; struct vb2_plane *psrc = &vb->planes[plane]; pdst->bytesused = psrc->bytesused; pdst->length = psrc->length; if (q->memory == VB2_MEMORY_MMAP) pdst->m.mem_offset = psrc->m.offset; else if (q->memory == VB2_MEMORY_USERPTR) pdst->m.userptr = psrc->m.userptr; else if (q->memory == VB2_MEMORY_DMABUF) pdst->m.fd = psrc->m.fd; pdst->data_offset = psrc->data_offset; memset(pdst->reserved, 0, sizeof(pdst->reserved)); } } else { /* * We use length and offset in v4l2_planes array even for * single-planar buffers, but userspace does not. */ b->length = vb->planes[0].length; b->bytesused = vb->planes[0].bytesused; if (q->memory == VB2_MEMORY_MMAP) b->m.offset = vb->planes[0].m.offset; else if (q->memory == VB2_MEMORY_USERPTR) b->m.userptr = vb->planes[0].m.userptr; else if (q->memory == VB2_MEMORY_DMABUF) b->m.fd = vb->planes[0].m.fd; } /* * Clear any buffer state related flags. */ b->flags &= ~V4L2_BUFFER_MASK_FLAGS; b->flags |= q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK; if (!q->copy_timestamp) { /* * For non-COPY timestamps, drop timestamp source bits * and obtain the timestamp source from the queue. */ b->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK; b->flags |= q->timestamp_flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK; } switch (vb->state) { case VB2_BUF_STATE_QUEUED: case VB2_BUF_STATE_ACTIVE: b->flags |= V4L2_BUF_FLAG_QUEUED; break; case VB2_BUF_STATE_ERROR: b->flags |= V4L2_BUF_FLAG_ERROR; /* fall through */ case VB2_BUF_STATE_DONE: b->flags |= V4L2_BUF_FLAG_DONE; break; case VB2_BUF_STATE_PREPARED: b->flags |= V4L2_BUF_FLAG_PREPARED; break; case VB2_BUF_STATE_PREPARING: case VB2_BUF_STATE_DEQUEUED: case VB2_BUF_STATE_REQUEUEING: /* nothing */ break; } if (vb2_buffer_in_use(q, vb)) b->flags |= V4L2_BUF_FLAG_MAPPED; if (!q->is_output && b->flags & V4L2_BUF_FLAG_DONE && b->flags & V4L2_BUF_FLAG_LAST) q->last_buffer_dequeued = true; }
/** * drm_calc_vbltimestamp_from_scanoutpos - helper routine for kms * drivers. Implements calculation of exact vblank timestamps from * given drm_display_mode timings and current video scanout position * of a crtc. This can be called from within get_vblank_timestamp() * implementation of a kms driver to implement the actual timestamping. * * Should return timestamps conforming to the OML_sync_control OpenML * extension specification. The timestamp corresponds to the end of * the vblank interval, aka start of scanout of topmost-leftmost display * pixel in the following video frame. * * Requires support for optional dev->driver->get_scanout_position() * in kms driver, plus a bit of setup code to provide a drm_display_mode * that corresponds to the true scanout timing. * * The current implementation only handles standard video modes. It * returns as no operation if a doublescan or interlaced video mode is * active. Higher level code is expected to handle this. * * @dev: DRM device. * @crtc: Which crtc's vblank timestamp to retrieve. * @max_error: Desired maximum allowable error in timestamps (nanosecs). * On return contains true maximum error of timestamp. * @vblank_time: Pointer to struct timeval which should receive the timestamp. * @flags: Flags to pass to driver: * 0 = Default. * DRM_CALLED_FROM_VBLIRQ = If function is called from vbl irq handler. * @refcrtc: drm_crtc* of crtc which defines scanout timing. * * Returns negative value on error, failure or if not supported in current * video mode: * * -EINVAL - Invalid crtc. * -EAGAIN - Temporary unavailable, e.g., called before initial modeset. * -ENOTSUPP - Function not supported in current display mode. * -EIO - Failed, e.g., due to failed scanout position query. * * Returns or'ed positive status flags on success: * * DRM_VBLANKTIME_SCANOUTPOS_METHOD - Signal this method used for timestamping. * DRM_VBLANKTIME_INVBL - Timestamp taken while scanout was in vblank interval. * */ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc, int *max_error, struct timeval *vblank_time, unsigned flags, struct drm_crtc *refcrtc) { struct timeval stime, etime; #ifdef notyet struct timeval mono_time_offset; #endif struct drm_display_mode *mode; int vbl_status, vtotal, vdisplay; int vpos, hpos, i; s64 framedur_ns, linedur_ns, pixeldur_ns, delta_ns, duration_ns; bool invbl; if (crtc < 0 || crtc >= dev->num_crtcs) { DRM_ERROR("Invalid crtc %d\n", crtc); return -EINVAL; } /* Scanout position query not supported? Should not happen. */ if (!dev->driver->get_scanout_position) { DRM_ERROR("Called from driver w/o get_scanout_position()!?\n"); return -EIO; } mode = &refcrtc->hwmode; vtotal = mode->crtc_vtotal; vdisplay = mode->crtc_vdisplay; /* Durations of frames, lines, pixels in nanoseconds. */ framedur_ns = refcrtc->framedur_ns; linedur_ns = refcrtc->linedur_ns; pixeldur_ns = refcrtc->pixeldur_ns; /* If mode timing undefined, just return as no-op: * Happens during initial modesetting of a crtc. */ if (vtotal <= 0 || vdisplay <= 0 || framedur_ns == 0) { DRM_DEBUG("crtc %d: Noop due to uninitialized mode.\n", crtc); return -EAGAIN; } /* Get current scanout position with system timestamp. * Repeat query up to DRM_TIMESTAMP_MAXRETRIES times * if single query takes longer than max_error nanoseconds. * * This guarantees a tight bound on maximum error if * code gets preempted or delayed for some reason. */ for (i = 0; i < DRM_TIMESTAMP_MAXRETRIES; i++) { /* Disable preemption to make it very likely to * succeed in the first iteration even on PREEMPT_RT kernel. */ #ifdef notyet preempt_disable(); #endif /* Get system timestamp before query. */ getmicrouptime(&stime); /* Get vertical and horizontal scanout pos. vpos, hpos. */ vbl_status = dev->driver->get_scanout_position(dev, crtc, &vpos, &hpos); /* Get system timestamp after query. */ getmicrouptime(&etime); #ifdef notyet if (!drm_timestamp_monotonic) mono_time_offset = ktime_get_monotonic_offset(); preempt_enable(); #endif /* Return as no-op if scanout query unsupported or failed. */ if (!(vbl_status & DRM_SCANOUTPOS_VALID)) { DRM_DEBUG("crtc %d : scanoutpos query failed [%d].\n", crtc, vbl_status); return -EIO; } duration_ns = timeval_to_ns(&etime) - timeval_to_ns(&stime); /* Accept result with < max_error nsecs timing uncertainty. */ if (duration_ns <= (s64) *max_error) break; } /* Noisy system timing? */ if (i == DRM_TIMESTAMP_MAXRETRIES) { DRM_DEBUG("crtc %d: Noisy timestamp %d us > %d us [%d reps].\n", crtc, (int) duration_ns/1000, *max_error/1000, i); } /* Return upper bound of timestamp precision error. */ *max_error = (int) duration_ns; /* Check if in vblank area: * vpos is >=0 in video scanout area, but negative * within vblank area, counting down the number of lines until * start of scanout. */ invbl = vbl_status & DRM_SCANOUTPOS_INVBL; /* Convert scanout position into elapsed time at raw_time query * since start of scanout at first display scanline. delta_ns * can be negative if start of scanout hasn't happened yet. */ delta_ns = (s64) vpos * linedur_ns + (s64) hpos * pixeldur_ns; /* Is vpos outside nominal vblank area, but less than * 1/100 of a frame height away from start of vblank? * If so, assume this isn't a massively delayed vblank * interrupt, but a vblank interrupt that fired a few * microseconds before true start of vblank. Compensate * by adding a full frame duration to the final timestamp. * Happens, e.g., on ATI R500, R600. * * We only do this if DRM_CALLED_FROM_VBLIRQ. */ if ((flags & DRM_CALLED_FROM_VBLIRQ) && !invbl && ((vdisplay - vpos) < vtotal / 100)) { delta_ns = delta_ns - framedur_ns; /* Signal this correction as "applied". */ vbl_status |= 0x8; } #ifdef notyet if (!drm_timestamp_monotonic) etime = ktime_sub(etime, mono_time_offset); #endif /* Subtract time delta from raw timestamp to get final * vblank_time timestamp for end of vblank. */ *vblank_time = ns_to_timeval(timeval_to_ns(&etime) - delta_ns); DPRINTF("crtc %d : v %d p(%d,%d)@ %lld.%ld -> %lld.%ld [e %d us, %d rep]\n", crtc, (int)vbl_status, hpos, vpos, (long long)etime.tv_sec, (long)etime.tv_usec, (long long)vblank_time->tv_sec, (long)vblank_time->tv_usec, (int)duration_ns/1000, i); vbl_status = DRM_VBLANKTIME_SCANOUTPOS_METHOD; if (invbl) vbl_status |= DRM_VBLANKTIME_INVBL; return vbl_status; }