SYSCALL_DEFINE3(lseek, int, fd, off_t, offset, int, whence) { int r; print_info(">> lseek %d %d %d\n", fd, offset, whence); r = file_lseek(fd, offset, whence); return SYSCALL_RETURN(r); }
off_t sys_lseek(int fd, off_t offset, int whence) { struct file *file = fd_get_file(fd); if (!file) return -1; offset = file_lseek(file, offset, whence); put_file(file); return offset; }
ssize_t sys_lseek(int fd, size_t ptr, int dir) { ssize_t r = -EBADF; file_t* f = file_get(fd); if (f) { r = file_lseek(f, ptr, dir); file_decref(f); } return r; }
int CFileOp::seek(int offset, int whence) { OFF_TYPE rc; OFF_TYPE real_offset = offset; real_offset *= m_chunk_size; rc = file_lseek(m_fd, real_offset, whence); if(rc == OFF_TYPE(-1)) { sprintf(m_buf, "Error in lseek to chunk %d(" OFF_T_PRINTF ")", offset, real_offset); perror(m_buf); return rc; } return 0; }
void vma_nopage(vma_t *vma, u32int vaddr) { if (!vma) return; /*printk("cr2 %p\n", current_task->dir->addr);*/ /*MAGIC_BREAK();*/ alloc_frame(get_page(vaddr, 1, current_task->dir), 1, vma->flags & VMA_WRITE); switch_page_directory(current_task->dir); if (vma->flags & VMA_ANON) { if (vma->flags & VMA_STACK) { vma->vm->end_stack -= 0x1000; vma->start -= 0x1000; } return; } if (vma->flags & VMA_FILE) { file_mapping_t *f_map = (file_mapping_t*)vma->priv; u32int size = 0x1000; u32int off = vaddr - vma->start; if (off >= f_map->size) { memset((void*)vaddr, 0, size); } else { file_lseek(f_map->file, f_map->offset + off, SEEK_SET); if (off + size > f_map->size) { /*printk("file_read: %p, size: %d\n", vaddr, f_map->size - off);*/ /*printk("memset: %p, size: %d\n", vma->start+f_map->size, size + off - f_map->size);*/ file_read(f_map->file, (u8int*)vaddr, f_map->size - off); memset((void*)(vma->start + f_map->size), 0, size + off - f_map->size); } else { /*printk("file_read: %p, size: %d\n", vaddr, size);*/ file_read(f_map->file, (u8int*)vaddr, size); } } } }
int file_open(filedes *file,const char *path, int flags) { if(Fat_open(file,path)<0) { errno=ENOENT; return -1; //没有找到对应的目录项,返回 } else { file->isused=1; file->offset=0; file->curnode=file->startnode; file->type=NOMAL_FILE; file->flags=flags; file->accesstime=kernel_getnowtime(); if(flags & O_TRUNC) { file->length=0; file->updatetime=kernel_getnowtime(); Fat_cut(file->curnode); } if(flags & O_APPEND) { file_lseek(file,0,SEEK_END); } return 0; //成功返回 } }
// Read/write a block of data double ZcavRead::access_data(int skip) { #ifdef _LARGEFILE64_SOURCE if(skip) { OFF_TYPE real_offset = OFF_TYPE(skip) * OFF_TYPE(m_block_size) * OFF_TYPE(1<<20); if(file_lseek(m_fd, real_offset, SEEK_CUR) == OFF_TYPE(-1)) return -1.0; } #endif m_dur.start(); for(int i = 0; i < m_block_size; i+= m_chunk_size) { int access_size = m_chunk_size; if(i + m_chunk_size > m_block_size) access_size = m_block_size - i; int rc = access_all(access_size); if(rc != access_size) return -1.0; } return m_dur.stop(); }
int ZcavRead::Read(int max_loops, int max_size, int writeCom, int skip_rate, int start_offset) { bool exiting = false; if(max_loops == 1) fprintf(m_log, "#block offset (GiB), MiB/s, time\n"); for(int loops = 0; !exiting && loops < max_loops; loops++) { int i = 0; #ifdef _LARGEFILE64_SOURCE if(start_offset) { OFF_TYPE real_offset = OFF_TYPE(start_offset) * OFF_TYPE(m_block_size) * OFF_TYPE(1<<20); if(file_lseek(m_fd, real_offset, SEEK_CUR) == OFF_TYPE(-1)) { fprintf(stderr, "Can't lseek().\n"); writeStatus(writeCom, eSEEK); return 1; } i = start_offset; } else #endif if(lseek(m_fd, 0, SEEK_SET)) { fprintf(stderr, "Can't lseek().\n"); writeStatus(writeCom, eSEEK); return 1; } // i is block index double total_read_time = 0.0; bool nextLoop = false; for( ; !nextLoop && (!max_size || i < max_size) && (loops == 0 || (m_times[i] && m_times[i][0] != -1.0)) && (!max_size || i < max_size); i++) { double read_time = access_data(i ? skip_rate - 1 : 0); if(read_time < 0.0) { if(i == 0) { fprintf(stderr, "Data file/device \"%s\" too small.\n", m_name); writeStatus(writeCom, eSIZE); return 1; } nextLoop = true; break; } total_read_time += read_time; if(max_loops == 1) { printavg(i * skip_rate, read_time, m_block_size); } else { if(loops == 0) { m_times.push_back(new double[max_loops]); m_count.push_back(0); } m_times[i][loops] = read_time; m_count[i]++; } } // end loop for reading blocks time_t now = time(NULL); struct tm *cur_time = localtime(&now); fprintf(stderr, "# Finished loop %d, on device %s at %d:%02d:%02d\n" , loops + 1, m_name, cur_time->tm_hour, cur_time->tm_min , cur_time->tm_sec); fprintf(m_log, "# Read %d megs in %d seconds, %d megabytes per second.\n" , i * m_block_size, int(total_read_time) , int(double(i * m_block_size) / total_read_time)); if(exiting) return 1; } // end loop for multiple disk reads if(max_loops > 1) { fprintf(m_log, "#loops: %d\n", max_loops); fprintf(m_log, "#block offset (GiB), MiB/s, time\n"); for(int i = 0; m_times[i]; i++) printavg(i * skip_rate, average(m_times[i], m_count[i]), m_block_size); } writeStatus(writeCom, eEND); return 0; }
void syscall_handler(){ switch (current_tcb->stack->r7) { case 0x1: /* fork */ if (task_count == TASK_LIMIT) { /* Cannot create a new task, return error */ current_tcb->stack->r0 = -1; } else { /* Compute how much of the stack is used */ size_t used = stacks[current_task] + STACK_SIZE - (unsigned int*)current_tcb->stack; /* New stack is END - used */ tasks[task_count].stack = (void*)(stacks[task_count] + STACK_SIZE - used); /* Copy only the used part of the stack */ memcpy(tasks[task_count].stack, current_tcb->stack, used * sizeof(unsigned int)); /* Set PID */ tasks[task_count].pid = task_count; /* Set priority, inherited from forked task */ tasks[task_count].priority = current_tcb->priority; /* Set return values in each process */ current_tcb->stack->r0 = task_count; tasks[task_count].stack->r0 = 0; list_init(&tasks[task_count].list); list_push(&ready_list[tasks[task_count].priority], &tasks[task_count].list); /* There is now one more task */ task_count++; } break; case 0x2: /* getpid */ current_tcb->stack->r0 = current_task; break; case 0x3: /* write */ { /* Check fd is valid */ int fd = current_tcb->stack->r0; if (fd < FILE_LIMIT && files[fd]) { /* Prepare file request, store reference in r0 */ requests[current_task].task = current_tcb; requests[current_task].buf = (void*)current_tcb->stack->r1; requests[current_task].size = current_tcb->stack->r2; current_tcb->stack->r0 = (int)&requests[current_task]; /* Write */ file_write(files[fd], &requests[current_task], &event_monitor); } else { current_tcb->stack->r0 = -1; } } break; case 0x4: /* read */ { /* Check fd is valid */ int fd = current_tcb->stack->r0; if (fd < FILE_LIMIT && files[fd]) { /* Prepare file request, store reference in r0 */ requests[current_task].task = current_tcb; requests[current_task].buf = (void*)current_tcb->stack->r1; requests[current_task].size = current_tcb->stack->r2; current_tcb->stack->r0 = (int)&requests[current_task]; /* Read */ file_read(files[fd], &requests[current_task], &event_monitor); } else { current_tcb->stack->r0 = -1; } } break; case 0x5: /* interrupt_wait */ /* Enable interrupt */ NVIC_EnableIRQ(current_tcb->stack->r0); /* Block task waiting for interrupt to happen */ event_monitor_block(&event_monitor, INTR_EVENT(current_tcb->stack->r0), current_tcb); current_tcb->status = TASK_WAIT_INTR; break; case 0x6: /* getpriority */ { int who = current_tcb->stack->r0; if (who > 0 && who < (int)task_count) current_tcb->stack->r0 = tasks[who].priority; else if (who == 0) current_tcb->stack->r0 = current_tcb->priority; else current_tcb->stack->r0 = -1; } break; case 0x7: /* setpriority */ { int who = current_tcb->stack->r0; int value = current_tcb->stack->r1; value = (value < 0) ? 0 : ((value > PRIORITY_LIMIT) ? PRIORITY_LIMIT : value); if (who > 0 && who < (int)task_count) { tasks[who].priority = value; if (tasks[who].status == TASK_READY) list_push(&ready_list[value], &tasks[who].list); } else if (who == 0) { current_tcb->priority = value; list_unshift(&ready_list[value], ¤t_tcb->list); } else { current_tcb->stack->r0 = -1; break; } current_tcb->stack->r0 = 0; } break; case 0x8: /* mknod */ current_tcb->stack->r0 = file_mknod(current_tcb->stack->r0, current_tcb->pid, files, current_tcb->stack->r2, &memory_pool, &event_monitor); break; case 0x9: /* sleep */ if (current_tcb->stack->r0 != 0) { current_tcb->stack->r0 += tick_count; event_monitor_block(&event_monitor, TIME_EVENT, current_tcb); current_tcb->status = TASK_WAIT_TIME; } break; case 0xa: /* lseek */ { /* Check fd is valid */ int fd = current_tcb->stack->r0; if (fd < FILE_LIMIT && files[fd]) { /* Prepare file request, store reference in r0 */ requests[current_task].task = current_tcb; requests[current_task].buf = NULL; requests[current_task].size = current_tcb->stack->r1; requests[current_task].whence = current_tcb->stack->r2; current_tcb->stack->r0 = (int)&requests[current_task]; /* Read */ file_lseek(files[fd], &requests[current_task], &event_monitor); } else { current_tcb->stack->r0 = -1; } } break; case 0xb: /* task_block */ { event_monitor_block(&event_monitor, TASK_EVENT(current_tcb->stack->r0), current_tcb); current_tcb->status = TASK_WAIT_TASK; } break; case 0xc: /* mutex_lock */ { unsigned int mutex_addr = current_tcb->stack->r0; /* search if mutex exist */ for(int i = 0; i < MUTEX_LIMIT; i++) { if(__mutex.addr[i] == mutex_addr) { event_monitor_block(&event_monitor, MUTEX_EVENT(i), current_tcb); current_tcb->status = TASK_WAIT_MUTEX; current_tcb->stack->r0 = 0; return; } } int empty_mutex = 0; for(; empty_mutex < MUTEX_LIMIT; empty_mutex++) { if(list_empty(&event_monitor.events[MUTEX_EVENT(empty_mutex)].list)) { break; } } event_monitor_block(&event_monitor, MUTEX_EVENT(empty_mutex), current_tcb); current_tcb->status = TASK_WAIT_MUTEX; __mutex.addr[empty_mutex] = mutex_addr; __mutex.count++; current_tcb->stack->r0 = 0; } break; case 0xd: /* mutex_unlock */ { unsigned int mutex_addr = current_tcb->stack->r0; /* search if mutex exist */ for(int i = 0; i < MUTEX_LIMIT; i++) { if(__mutex.addr[i] == mutex_addr) { event_monitor_release(&event_monitor, MUTEX_EVENT(i)); current_tcb->stack->r0 = 0; __mutex.count--; return; } } current_tcb->stack->r0 = -1; } break; default: break; } }