디시인사이드 갤러리

갤러리 이슈박스, 최근방문 갤러리

갤러리 본문 영역

Clair.Event_Loop 구현 완료함. ㅋㅋ 현재 손적화 중

나르시갤로그로 이동합니다. 2025.11.26 17:46:06
조회 41 추천 0 댓글 10

최적화란.. 최씨 무인정권이 적화통일하는 거라는

우스게소리.. 웃기긴 하다.


소스코드는 다음과 같습니다.

.ads 파일은 c언어에 비유하자면 .h 같은 성격의 파일입니다.

외부에 노출되는 API죠.


변수 관련하여 한가지 최적화하고..

구글 제미니, MS 코파일럿에 소스코드 입력하여

조언 받아 인공 최적화하고 있습니다. ㅋㅋㅋ

최상의 결과물이 나오고 있습니다.

0 오버헤드라는 것이 특징입니다.

이벤트 추가 삭제에 O(1) 시간 소요됩니다.

해시맵이나 순서맵 등 맵을 사용하지 않았습니다.

링크드리스트 방식인데 링크가 Idle Source 객체 안에 들어 있습니다.

그 결과 idle 이벤트들을 줄줄히 실행 가능하고 삽입/삭제시 O(1) 시간이 걸립니다.

이론적으로 최상의 속도.

이러한 방식이 해시맵보다 빠릅니다. 해시맵도 이론적으로 O(1)이지만

메모리 소비, 리해싱, 해시 함수 때문에 방금 애기한 침입형 링크드리스트 방식보다는

상대적으로 느립니다.

그러면 등록한 이벤트를 어떻게 찾느냐? 그것은 kqueue 및 epoll이 알아서 해줍니다.

이벤트를 등록할 때 kqueue의 udata (사용자 데이터)에 Source 포인터를 넘깁니다. ㅎㅎ

source 레코드에 ident, event mask, callback, user_data 등이 들어 있지요.

그에 대핸 포인터를 kqueue의 udata로 넘긴거지요.



-- clair-event_loop.ads
-- Copyright (c) 2021-2025 Hodong Kim <hodong@nimfsoft.art>
--
-- Permission to use, copy, modify, and/or distribute this software for any
-- purpose with or without fee is hereby granted.
--
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--

with Clair.File;
with Interfaces.C;
with System;

package Clair.Event_Loop is
use type Interfaces.C.int;

-----------------------------------------------------------------------------
-- [Time Definitions] 64-bit Milliseconds
-----------------------------------------------------------------------------
type Milliseconds is new Interfaces.C.long_long;

INFINITE : constant Milliseconds := -1;
IMMEDIATE : constant Milliseconds := 0;

-----------------------------------------------------------------------------
-- [Handle & Context] Opaque Types
-----------------------------------------------------------------------------
type Context is limited private;

-- 사용자는 Handle이 무엇인지(포인터인지 정수인지) 모릅니다.
type Handle is private;
NULL_HANDLE : constant Handle;

-----------------------------------------------------------------------------
-- [Callbacks] Type Safety
-----------------------------------------------------------------------------
-- 1. I/O 감시용
type Event_Mask is new Interfaces.C.unsigned;

EVENT_INPUT : constant Event_Mask := 16#001#; -- same as EPOLLIN
EVENT_OUTPUT : constant Event_Mask := 16#004#; -- same as EPOLLOUT
EVENT_ERROR : constant Event_Mask := 16#008#; -- same as EPOLLERR
EVENT_HANG_UP : constant Event_Mask := 16#010#; -- same as EPOLLHUP

-- 1. I/O 감시용
type IO_Callback is access procedure (
fd : Clair.File.Descriptor;
events : Event_Mask;
user_data : System.Address
) with convention => c;

-- 2. 타이머용 (자신의 핸들을 받아 삭제 가능)
type Timer_Callback is access procedure (
timer : Handle;
user_data : System.Address
) with convention => c;

-- 아이들 전용 콜백
type Idle_Callback is access procedure (
idle : Handle;
user_data : System.Address
) with convention => c;

-- 시그널 콜백
-- signum: 발생한 시그널 번호 (예: SIGINT=2, SIGTERM=15)
type Signal_Callback is access procedure (
signum : Interfaces.C.int;
user_data : System.Address
) with convention => c;
-----------------------------------------------------------------------------
-- [Public API]
-----------------------------------------------------------------------------
function create return Context;
procedure destroy (self : in out Context);

procedure run (self : in out Context);
procedure stop (self : in out Context);

-- 루프의 한 사이클을 실행
-- 이벤트를 확인하고, 준비된 이벤트가 있다면 콜백을 실행한 뒤 복귀합니다.
-- timeout: 밀리초 단위. 음수면 무한 대기.
procedure iterate (self : in out Context;
timeout : Milliseconds := INFINITE);


function add_watch (
self : in out Context;
fd : Clair.File.Descriptor;
events : Event_Mask;
callback : IO_Callback;
user_data : System.Address := System.NULL_ADDRESS
) return Handle;

function add_timer (
self : in out Context;
interval : Milliseconds;
callback : Timer_Callback;
user_data : System.Address := System.NULL_ADDRESS;
one_shot : Boolean := False
) return Handle;

-- Idle 추가: 루프가 돌 때마다 실행됩니다.
function add_idle (
self : in out Context;
callback : Idle_Callback;
user_data : System.Address := System.NULL_ADDRESS
) return Handle;

procedure remove (
self : in out Context;
target : Handle
);

procedure modify_watch (
self : in out Context;
watch : Handle;
events : Event_Mask
);


function add_unix_signal (
self : in out Context;
signum : Interfaces.C.int;
callback : Signal_Callback;
user_data : System.Address := System.NULL_ADDRESS
) return Handle;

private

-----------------------------------------------------------------------------
-- [Internal Data Structures] Pointer + RefCount + Variant Record
-----------------------------------------------------------------------------
-- 1. 리소스의 종류를 식별하는 열거형
type Source_Kind is (KIND_WATCH, KIND_TIMER, KIND_IDLE, KIND_SIGNAL);
type Source; -- Forward declaration
type Source_Access is access all Source;
pragma convention (c, Source_Access);

type Handle is new Source_Access;
NULL_HANDLE : constant Handle := null;

-- 2. 가변 레코드 (variant record)
-- kind(판별자)에 따라 구조가 변합니다.
type Source (kind : Source_Kind := KIND_WATCH) is record
-- [공통 필드] 모든 종류가 공유하는 데이터
ref_count : Integer := 1; -- 참조 카운트 (0이 되면 free)
is_closed : Boolean := False; -- 논리적 삭제 여부 (zombie check)
user_data : System.Address;
-- [가변 필드] Kind에 따라 달라지는 데이터
case kind is
when KIND_WATCH =>
fd : Clair.File.Descriptor; -- 파일 디스크립터
events : Event_Mask; -- 감시 중인 이벤트 마스크
io_cb : IO_Callback; -- I/O 전용 콜백

when KIND_TIMER =>
timer_cb : Timer_Callback; -- 타이머 전용 콜백
-----------------------------------------------------------------------
-- [Platform-Specific Identifier] 플랫폼별 타이머 식별자
-----------------------------------------------------------------------
-- 이 필드는 운영체제 커널이 타이머를 구별하고 제어(삭제)하기 위해
-- 요구하는 고유 값을 저장합니다. OS 구현 방식에 따라 용도가 다릅니다.
--
-- 1. Linux (epoll + timerfd):
-- 'timerfd_create'가 반환한 **파일 디스크립터(FD)**를 반드시 저장해야 합니다.
-- (삭제 시 close(Ident) 호출 필요)
--
-- 2. BSD (kqueue):
-- 'kevent' 구조체의 **'ident'** 필드 값을 저장하는 용도입니다.
--
-- [구현 노트 - 최적화]
-- 구현 전략에 따라, 별도의 ID를 발급하지 않고 **Source 객체의 메모리 주소(Handle)**
-- 그 자체를 정수로 변환하여 kqueue의 ident로 사용할 수 있습니다.
-- 이 경우, **본 필드(Ident)는 사용되지 않거나(Unused)**,
-- 주소값을 중복 저장하는 용도로 사용될 수 있습니다.
--
-- * 타입 선정: 64비트 포인터 주소값 저장을 보장하기 위해 unsigned_long_long 사용.
-----------------------------------------------------------------------
ident : Interfaces.C.unsigned_long_long;

when KIND_IDLE =>
idle_cb : Idle_Callback; -- 아이들 전용 콜백
idle_next : Handle;
idle_prev : Handle; -- 삭제 편의를 위해 이중 연결 리스트 추천

when KIND_SIGNAL =>
sig_num : Interfaces.C.int; -- 시그널 번호
sig_cb : Signal_Callback; -- 콜백
-- [Linux 호환성]
-- kqueue는 필요 없지만, epoll은 signalfd로 만든 FD를 저장해야 삭제(close) 가능
sig_fd : Clair.File.Descriptor := Clair.File.INVALID_DESCRIPTOR; -- -1
end case;
end record;


type Timespec is record
tv_sec : Interfaces.C.long;
tv_nsec : Interfaces.C.long;
end record;
pragma convention (c, Timespec);

type Context is limited record
fd : Clair.File.Descriptor;
is_running : Boolean := False;
-- 캐싱된 타임아웃 (비교용, 64비트 정수)
cached_timeout : Milliseconds := INFINITE;
cached_timespec : Timespec := (others => 0);
-- idle 관리
call_depth : Natural := 0;
idle_head : Handle := NULL_HANDLE; -- 리스트의 시작
idle_tail : Handle := NULL_HANDLE; -- 리스트의 끝 (빠른 추가용)
idle_count : Natural := 0;
end record;

end Clair.Event_Loop;

추천 비추천

0

고정닉 0

0

댓글 영역

전체 댓글 0
본문 보기

하단 갤러리 리스트 영역

왼쪽 컨텐츠 영역

갤러리 리스트 영역

갤러리 리스트
번호 제목 글쓴이 작성일 조회 추천
설문 뛰어난 운동 신경으로 남자와 싸워도 이길 것 같은 여자 스타는? 운영자 25/11/24 - -
이슈 [디시人터뷰] 충무로가 주목하는 신예, '세계의 주인' 서수빈 운영자 25/11/24 - -
AD 대학생 필수템! What's in my Bag 운영자 25/11/21 - -
공지 프로그래밍 갤러리 이용 안내 [97] 운영자 20.09.28 48771 65
2905009 법무부 영문 표기가 Ministry of Justice 발명도둑잡기(118.216) 00:14 2 0
2905008 DB 검색할 때 %like%는 걍 없다고 생각하고 써야함? 프갤러(58.29) 00:14 3 0
2905007 새벽 1시 핫딜... 당신은 잠만 잤습니다 프갤러(117.111) 00:01 10 0
2905006 이거 항소하면 무죄 내지는 벌금50까지 줄여지냐? 씨발국가야? ㅇㅇ(39.7) 11.26 11 0
2905005 대통령보다 연봉높은 우주청 현실 [1] 타이밍뒷.통수한방(1.213) 11.26 21 0
2905004 개인 자격으로 인공위성 만들어 발사한 미디어아티스트 송호준 [1] 발명도둑잡기(118.216) 11.26 12 0
2905003 해외기사들보면 삼성 lg제품 존나 광고하네 타이밍뒷.통수한방(1.213) 11.26 12 0
2905002 소프트웨어 엔지니어의 몰입 손발이시립디다갤로그로 이동합니다. 11.26 15 0
2905001 [공식] 누리호 4차 발사 현장 생중계 발명도둑잡기(118.216) 11.26 8 0
2905000 이거 ㅈㄴ 억울한데 항소할지 걍 벌받을지 추천좀 ㅇㅇ(39.7) 11.26 15 0
2904999 슬슬 재취업들어가야겠군 ㅇㅇ(113.59) 11.26 13 0
2904998 R이나 파이썬같은 툴 돌릴 때 작동 원리에 대한 수학 ㅇㅇ(211.108) 11.26 14 0
2904997 음악인 나오는 영화 추천 <꿈의 제인> 발명도둑잡기(118.216) 11.26 10 0
2904994 충격적임.. ♥냥덩이의우웅한하룽♥갤로그로 이동합니다. 11.26 15 0
2904993 유재석 김태호 카르텔 근황 ♥냥덩이의우웅한하룽♥갤로그로 이동합니다. 11.26 28 1
2904992 밤하늘 별빛이 호롱불 같구낭 ♥냥덩이의우웅한하룽♥갤로그로 이동합니다. 11.26 16 0
2904988 Wendy & Lisa-The Closing Of the Year 발명도둑잡기(118.216) 11.26 7 0
2904986 회사에서 AI 써야하는 이유가 있음 박민준갤로그로 이동합니다. 11.26 31 0
2904984 33살 인생 평가좀.. 진지함 정말이야, 절박해 [1] ㅇㅇ(39.7) 11.26 23 0
2904982 [발언대] ‘2인 선거구’ 없애야 민심 제대로 반영된다 발명도둑잡기(118.216) 11.26 9 0
2904981 Ada의 case when 최적화와 errno → 예외 매핑 나르시갤로그로 이동합니다. 11.26 9 0
2904979 무슨 맛으로 먹을까 떡볶이 인데 망했다. [1] 넥도리아(220.74) 11.26 18 0
2904976 통합 에러 핸들러와 이진 탐색 최적화 나르시갤로그로 이동합니다. 11.26 13 0
2904975 나님 주무십니당⭐+ ♥냥덩이의우웅한하룽♥갤로그로 이동합니다. 11.26 10 0
2904974 Go 쓰자 박민준갤로그로 이동합니다. 11.26 24 0
2904973 악플러 멍유 제발 일본에서 조난.. [4] ♥냥덩이의우웅한하룽♥갤로그로 이동합니다. 11.26 38 0
2904972 나님 누엇어양✨ ♥냥덩이의우웅한하룽♥갤로그로 이동합니다. 11.26 16 0
2904970 뉴비들을 위한 입시 면접 합격 가이드(따뜻한 조언)!M 프갤러(121.142) 11.26 19 1
2904969 누리호 발사 기원 우주 플레이리스트 발명도둑잡기(118.216) 11.26 17 0
2904966 나씻주준⭐+ [1] ♥냥덩이의우웅한하룽♥갤로그로 이동합니다. 11.26 30 0
2904964 일본 취업 유학 워홀 여행 관련모임 ㅇㅇ(106.146) 11.26 22 0
2904963 27일 27번 타자가 친 공처럼 로케트 잘 올라갈까? 발명도둑잡기(118.216) 11.26 18 0
2904962 <UDT 우리동네 특공대>가 인기래서 생각나는 예전 글 [1] 발명도둑잡기(118.216) 11.26 22 0
2904961 C API를 위한 고성능 예외-에러코드(errcode) 매핑 전략 나르시갤로그로 이동합니다. 11.26 34 0
2904960 엣지 탭 천개쯤 띄우면 다 [1] 발명도둑잡기(118.216) 11.26 21 0
2904959 왜 갑자기 쌍ㅅ쌍 얘기야? 나르시갤로그로 이동합니다. 11.26 29 1
2904958 Clair 라이브러리: Ada 예외를 C API로 매핑하기 나르시갤로그로 이동합니다. 11.26 20 0
2904957 한국에 실제 있다는 중국 사이비종교 마을 ㄷㅅㄷ [1] ♥냥덩이의우웅한하룽♥갤로그로 이동합니다. 11.26 36 0
2904956 트위터가 공개한건 국적이 아니라 위치다 발명도둑잡기(118.216) 11.26 19 0
2904955 민주정의당 후보, 4대강 죽이기 광고모델 이순재 발명도둑잡기(118.216) 11.26 27 1
2904954 외모는 단점을 커버시키는 힘이 있다 [2] Move갤로그로 이동합니다. 11.26 47 0
2904953 짱깨 한국 여론조작 또 걸렸네 ㅋㅅㅋ ♥냥덩이의우웅한하룽♥갤로그로 이동합니다. 11.26 34 2
2904952 귀찮은데 말이 필요하나 루도그담당(58.233) 11.26 43 0
2904951 저능아씨는 여기서 살아 RyuDOG갤로그로 이동합니다. 11.26 35 0
2904950 프붕이들 솔직히 병신들이 도배하는거보다 러스트 얘기가 낫지? [4] 프갤러(110.8) 11.26 41 0
2904949 아아 하늘은 어째서 나를 낳고 RyuDOG갤로그로 이동합니다. 11.26 24 0
2904948 낄낄낄낄 RyuDOG갤로그로 이동합니다. 11.26 22 0
2904947 솔직히 글 읽을 필요도 없음 RyuDOG갤로그로 이동합니다. 11.26 29 0
2904946 저거 봐바 몇대 때려주니까 루도그담당(58.233) 11.26 31 0
갤러리 내부 검색
제목+내용게시물 정렬 옵션

오른쪽 컨텐츠 영역

실시간 베스트

1/8

디시미디어

디시이슈

1/2