잘하는 다른 동기 분에게 어떻게 문제에 접근했는지 물어봄. 시간이 없어서 많이 못 들음
코드 주석 + 디버깅 문구 스타일 따라해보기
ATA(IDE) 컨트롤러는 하드 디스크나 CD-ROM 드라이브와 같은 저장 장치를 제어하는 데 사용되는 장치입니다. 시스템이 저장 장치와 데이터를 주고받기 위해 필요한 명령어와 신호를 주고받는 역할을 합니다.
ATA-3는 ATA 표준의 세 번째 버전으로, 하드 디스크 드라이브 인터페이스의 개선 사항을 포함합니다.
open할 때 file_deny_write(real_file);
close할 때 file_allow_write(file);
두 줄 추가했더니 open하고 close가 터지기 시작함
순서 좀 바꾸고 보호 구문 추가해줌. 통과는 했는데 write 테케들이 통과 안 함.
실행 파일만 deny해야지 open할 때마다 deny하면 안된다고 함.
분명 헤더 파일도 추가했고 file을 멀쩡하게 사용하고 있는데 왜 -> 문법을 사용하면 에러를 일으키는 거지?
file.h에 struct file이 정의되지 않아서 그랬던 것. file.c에만 struct file이 정의돼있어 file.c 이외의 파일에선 struct file의 내부 요소를 사용할 수 없었다.
file.h에 struct file 정의 추가했더니 컴파일 오류.
file.c에 있는 struct file 정의 삭제했더니 해결됨.
왜 load에서 deny_write를 했는데 막상 write하려고 보면 deny_write가 0으로 초기화돼있는거지?
filesys.c\filesys_open()에서 dir_lookup으로
같은 파일이 아니기 때문. open할 때마다 아이노드만 갖고 파일은 다르다. 라고 생각했는데
내가 지금 디버깅 찍어서 어 왜 똑같지 분명 바꿔줬는데 라고 생각하는 부분이 inode...
file도 똑같은 것으로 판명됨. 진짜 뭐지?????
그러니까 file이 같은 file이긴 함. open을 하고 난 뒤에 file의 정보가 달라짐. filesys_open의 비밀을 알아내야 함.
file의 정보가 어딘가에서 유실된다는 현상의 원인 알아내기.
마음 가다듬고 침착하게 보니까 의외로 금방 찾음.
file_open할 때마다 deny_write를 false로 바꿔줌.
filesys_open 중에 idnoe_open도 호출되는데 이때 reopen이 아니면 deny_write_cnt가 initialize가 된다.
그런데 실행파일은 분명 이미 열려있는 파일일테도 indoe_reopen이 아니라 inode_open만 호출됨. (reopen은 inode->open_cnt++;만 하고 inode 그대로 반환함)
filesys_open을 하면 무조건 list_push_front(&open_inodes, &inode->elem);이 호출된다. 따라서 같은 파일을 연다면 open_inodes가 있을 테니 reopen을 해야 함.
근데도 안된다는 건 file에 대한 정보가 뭔가 복사가 안됐다거나?
일단 우회 방법을 떠올려보면 실행 파일인지 아닌지 확인한 다음 실행 파일이면 write를 안 하는 방법이 있는데 그게 가능한가?
단순히 deny_write의 위치의 문제라는건?
rox-simple이 시작된 후 open_inode 리스트가 초기화됐다.
할만큼 했다 답지 보자
우려했던 상황이 일어남
답지 봤는데 나랑 똑같은 곳에 deny_write 했음
그니까 다른 사람들은 open_inode 리스트가 멀쩡히 복사된다는 거임.
다시 생각해보니 그건 아님.
open_inode 리스트가 초기화 되는 건 맞는 절차임.
각 프로세스마다 열고 있는 파일의 리스트가 다를 테니까.
앞에서 봤듯이 file의 정보가 초기화되는 것도 정상임. 원래 함수가 그렇게 생겨먹음.
inode에 집착하지 말고 실행 파일에 deny_write를 먹이는 방법에 집중하자.
필요없는 inode 디버깅 다 지움.
bdgin 전후에 무슨 일이 벌어지는지 찾아볼 것.
ad-hoc 1 : 쓰레드에 실행 파일 이름을 담아둔 뒤 open할 때마다 실행 파일 이름하고 비교해서 deny_write 값
ad-hoc 2 : 파일 이름에 .
들어가면 실행 파일 아닌 걸로 간주
근데 이건 너무 말도 안되고
thread에 file struct를 추가해야되는구나.
이 방법이면 가능할듯.
"keep opening file"은 뭔 소린지 모르겠음
load할 때 실행 파일의 file struct를 쓰레드에 저장해두고
init_thread()할 때 해당 file의 deny_write를 true로 변경해주면 될듯!
아니 근데 load할 쓰레드에 실행 파일 정보를 건네줄 방법이 없지 않나?
일단 load에서 thread_current()에 넣어보기.
아 그렇게 하니까 page fault 뜸...
thread_current()에 넣는다고 해서 전달이 되는게 아님.
"keep opening file"이 대충 뭔 말인지 알 것 같음.
process.c에 전역 변수로 list를 선언해놓고
load 실행될 때마다 실행 파일 넣어주고
open할 때마다 실행 파일 리스트 훑으면서 같은 놈 있으면 deny_write true로 바꿔줘야됨
닫을 땐 어떡하냐 그러면
리스트 순회하면서 같은 놈이 있으면 삭제해줘야지 page fault 안 나는거임?
실행파일인지 아닌지는 간단하게 구분 불가능하니까?
/* An open file. */
struct file
{
struct inode *inode; /* File's inode. */
off_t pos; /* Current position. */
bool deny_write; /* Has file_deny_write() been called? */
};
아니 주석 보니까 더 이 해결책이 납득이 안 감.
file_deny_write()로 해결을 해야된다는 건데
이건 file_deny_write()를 호출을 아예 안 하잖음?
뭔가 이상하다. 분명 다른 해결책이 있을거임.
open_inodes가 초기화되던 이유 : main에서 filesys_init을 호출하기 때문.
https://velog.io/@smilelee9/pintos-kaist-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-System-call-6
답지를 또 봤는데 심기가 불편해짐.
여기선 thread_current()에 정보를 입력해놓고 전달시키려고 하고 있었음.
나는 전달한 거 접근하려고 하면 page fault나던데.
내가 접근한 방식이 문제였나?
그리고 일단 이 글에선 lg, sm 이것들 아무렇지도 않게 통과됨.
심적으로 너무 힘들다.
N=int(input())
cnt = 0
for i in range(1,N+1):
num = i
stack=[]
while num > 0:
stack.append(num%10)
num = int(num/10)
if len(stack) == 1:
cnt+=1
continue
dv = stack[1] - stack[0]
isHS = True
while len(stack) > 1:
last = stack.pop()
blast = stack[-1]
if (last - blast) != dv:
isHS = False
break
if isHS:
cnt+=1
print(cnt)
풀긴했는데 개억지로 품
import sys
input = sys.stdin.readline
# 1. N 입력받기
N = int(input().rstrip())
cnt = 0
# 2. 한수 개수 출력
for i in range(1, N + 1):
temp = str(i)
if len(temp) <= 2:
cnt += 1
else:
if int(temp[1]) * 2 == int(temp[0]) + int(temp[2]):
cnt += 1
print(cnt)
이 사람 좀 잘푼듯
등차수열의 성질을 이용했다.