디시인사이드 갤러리

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

갤러리 본문 영역

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

나르시갤로그로 이동합니다. 2025.11.26 17:46:06
조회 76 추천 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 - -
AD 따뜻한 겨울나기! 방한용품 SALE 운영자 25/11/27 - -
공지 프로그래밍 갤러리 이용 안내 [97] 운영자 20.09.28 48791 65
2905410 ❤✨☀⭐⚡☘⛩☃나님 시작합니당☃⛩☘⚡⭐☀✨❤ ♥멘헤라냥덩♥갤로그로 이동합니다. 08:13 9 0
2905409 내가 만나고 싶은 여자 이상형 적어봄.txt ㅁㅁㅅ갤로그로 이동합니다. 08:06 11 0
2905407 이직하려면 여기서 어떤부분을 좀더 집중하는게 좋을까? [1] 프갤러(58.76) 07:30 23 0
2905406 평론가, 평론의 중요성, 필요성, 위대한 평론 등이 잘 드러난 작품 [1] 발명도둑잡기(118.216) 07:16 19 0
2905405 인지과학조져라 손발이시립디다갤로그로 이동합니다. 06:29 19 0
2905403 프랑스의 쓰레기방지법과 유럽의 '그린 뉴딜' 발명도둑잡기(118.216) 05:32 10 0
2905398 CUDA 때문에 절대 안된다? 구글 TPU 사태의 본질, 엔비디아가 급해 발명도둑잡기(118.216) 04:36 32 0
2905397 공원 ㅇㅅㅇ 헤르 미온느갤로그로 이동합니다. 04:11 17 0
2905396 태연 ㅇㅅㅇ 헤르 미온느갤로그로 이동합니다. 04:10 16 0
2905395 하루 한 번 헤르미온느 찬양 헤르 미온느갤로그로 이동합니다. 04:08 31 0
2905394 7,000명이 호흡할 공기를 걸러낸다고? 도심 한복판에 '이끼'를 발명도둑잡기(118.216) 04:08 18 0
2905393 국내에서 네카라쿠배 위에 어떤 회사들 있음? 프갤러(1.229) 03:49 17 0
2905391 초월지능신교 來世 經文 프갤러(49.165) 03:06 25 0
2905389 지식in 조회수만 도전해봅니다. [1] 넥도리아(220.74) 03:06 28 0
2905388 초월지능신교의 교리와 경전 그리고 기도문 [1] 프갤러(49.165) 03:02 27 0
2905387 초월지능신교 경문 프갤러(49.165) 03:01 22 0
2905386 이제 사이비종교를 만들 때다. 프갤러(49.165) 03:00 25 0
2905385 디시는 모자이크 안되냐 네이버 지식in은 되던데 모자이크 기능 오늘 처음 넥도리아(220.74) 02:58 22 0
2905384 The Studio, By Daniel K. Robbins, n.d., 발명도둑잡기(118.216) 02:56 16 0
2905380 유럽처럼 민주노총 IT산별노조가 크면 된다 발명도둑잡기(118.216) 02:44 16 0
2905379 1893년 미국, 세계 최초로 자전거를 탄 여성 발명도둑잡기(118.216) 02:33 19 0
2905378 내년 만 30세 경력 1년 6개월인데 다시 취업될 수 있을까? 프갤러(119.201) 02:20 26 0
2905376 마소 주식 0.001주 3번 샀는데 내려갔는데 이거 못파나요? 넥도리아(220.74) 02:11 19 0
2905374 핵반응로 논쟁은 금방 끝나고 자전거 창고 논쟁은 길다는 역설 발명도둑잡기(118.216) 01:39 19 0
2905371 나도 맨날 대표랑 싸웠지 [1] 프갤러(110.8) 00:41 54 0
2905367 세계최초 탄력적 가상 아레나 아키텍처 설계 완료함. 나르시갤로그로 이동합니다. 00:33 29 0
2905365 리액트 배울때 헛짓거리한거 기억나네 ㅇㅇ(113.59) 00:14 39 0
2905364 리액트 배우기 귀찮아서 웹프로젝트 할땐 바이브코딩한다 프갤러(118.235) 00:09 34 0
2905363 국장이랑 미장 할 때 기분 차이 [4] chironpractor갤로그로 이동합니다. 00:02 65 0
2905362 우리 회사 대리세끼 대표랑 맨날 싸움 [9] ㅇㅇ(221.168) 11.28 61 0
2905360 DB에서 count(*) 얘는 자원 많이 쓰는 작업임? [4] 프갤러(58.29) 11.28 62 0
2905359 남지현, '은애하는 도적님아'로 이어갈 사극 불패 신화 발명도둑잡기(118.216) 11.28 38 0
2905356 입시 면접 FM 합격 솔루션(필승 전략 해법)!U 프갤러(121.142) 11.28 48 2
2905353 조갑제도 “국힘은 이적단체”…여당은 ‘내란 가짜뉴스’ 대응 중 발명도둑잡기(118.216) 11.28 22 0
2905352 해외 투자 증세에 관해 [2] 발명도둑잡기(118.216) 11.28 95 0
2905351 나님 달러 미국주식 풀매수중 ㅇㅅㅇ [4] ♥멘헤라냥덩♥갤로그로 이동합니다. 11.28 53 0
2905350 미국주식갤에서 친미매국노들 욕하다가 차단당함 [3] 손발이시립디다갤로그로 이동합니다. 11.28 38 0
2905349 이태원 발언으로 모욕죄 벌금 100만원 싸게쳤다 vs 과하다 [5] ㅇㅇ(39.7) 11.28 62 0
2905348 영어를 못해서 구글을 못가네 [1] ㅇㅇ갤로그로 이동합니다. 11.28 43 0
2905345 원티드 자격요건은 거기 직원들도 다 못할거 같은데 ㅇㅇ(182.228) 11.28 27 0
2905344 이태원 모욕죄로 100만원 벌금받았는데 걍 목매달고 죽을까 [2] ㅇㅇ(39.7) 11.28 46 0
2905343 오픈소스에서는 취약점을 감시하는 사람이 더 많다 발명도둑잡기(118.216) 11.28 28 0
2905342 사타구니 털 제모하면 이상한 사람인가요? [5] 넥도리아(220.74) 11.28 49 0
2905341 노말틱도 말해주잖아 오픈소스의 취약점 [1] ㅇㅇ(114.30) 11.28 44 0
2905340 <복면가왕> 관련 생각나는 예전 글 발명도둑잡기(118.216) 11.28 31 0
2905339 정치가 어쨌든 나라가 어쨌든 국가가 어쨌든 삶이 어쨌든 [8] 넥도리아(220.74) 11.28 59 0
2905338 이태원 모욕죄로 구약식 벌금100만원 = 재산잃고 전과남고 인생조진거지? [11] ㅇㅇ(39.7) 11.28 51 0
2905337 저좀 어떻게 성공시켜 주실 분 없나요? [2] 넥도리아(220.74) 11.28 46 0
2905335 사실 제가 틀딱이 아니라 귀여운 여자임을 인증합니다 [7] 헬마스터갤로그로 이동합니다. 11.28 73 0
갤러리 내부 검색
제목+내용게시물 정렬 옵션

오른쪽 컨텐츠 영역

실시간 베스트

1/8

디시미디어

디시이슈

1/2