Subversion Repositories Kolibri OS

Rev

Rev 7696 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. (*
  2.     BSD 2-Clause License
  3.  
  4.     Copyright (c) 2018, 2020, Anton Krotov
  5.     All rights reserved.
  6. *)
  7.  
  8. MODULE API;
  9.  
  10. IMPORT SYSTEM, K := KOSAPI;
  11.  
  12.  
  13. CONST
  14.  
  15.     MAX_SIZE  = 16 * 400H;
  16.     HEAP_SIZE =  1 * 100000H;
  17.  
  18.     _new = 1;
  19.     _dispose = 2;
  20.  
  21.     SizeOfHeader = 36;
  22.  
  23.  
  24. TYPE
  25.  
  26.     CRITICAL_SECTION = ARRAY 2 OF INTEGER;
  27.  
  28.  
  29. VAR
  30.  
  31.     heap, endheap: INTEGER;
  32.     pockets: ARRAY MAX_SIZE DIV 32 + 1 OF INTEGER;
  33.  
  34.     CriticalSection: CRITICAL_SECTION;
  35.  
  36.     import*, multi: BOOLEAN;
  37.  
  38.     eol*:  ARRAY 3 OF CHAR;
  39.     base*: INTEGER;
  40.  
  41.  
  42. PROCEDURE [stdcall] zeromem* (dwords: INTEGER; adr: INTEGER);
  43. BEGIN
  44.     SYSTEM.CODE(
  45.     0FCH,               (*  cld                            *)
  46.     031H, 0C0H,         (*  xor     eax, eax               *)
  47.     057H,               (*  push    edi                    *)
  48.     08BH, 07DH, 00CH,   (*  mov     edi, dword [ebp + 12]  *)
  49.     08BH, 04DH, 008H,   (*  mov     ecx, dword [ebp +  8]  *)
  50.     0F3H, 0ABH,         (*  rep     stosd                  *)
  51.     05FH                (*  pop     edi                    *)
  52.     )
  53. END zeromem;
  54.  
  55.  
  56. PROCEDURE mem_commit* (adr, size: INTEGER);
  57. VAR
  58.     tmp: INTEGER;
  59. BEGIN
  60.     FOR tmp := adr TO adr + size - 1 BY 4096 DO
  61.         SYSTEM.PUT(tmp, 0)
  62.     END
  63. END mem_commit;
  64.  
  65.  
  66. PROCEDURE switch_task;
  67. BEGIN
  68.     K.sysfunc2(68, 1)
  69. END switch_task;
  70.  
  71.  
  72. PROCEDURE futex_create (ptr: INTEGER): INTEGER;
  73.     RETURN K.sysfunc3(77, 0, ptr)
  74. END futex_create;
  75.  
  76.  
  77. PROCEDURE futex_wait (futex, value, timeout: INTEGER);
  78. BEGIN
  79.     K.sysfunc5(77, 2, futex, value, timeout)
  80. END futex_wait;
  81.  
  82.  
  83. PROCEDURE futex_wake (futex, number: INTEGER);
  84. BEGIN
  85.     K.sysfunc4(77, 3, futex, number)
  86. END futex_wake;
  87.  
  88.  
  89. PROCEDURE EnterCriticalSection* (VAR CriticalSection: CRITICAL_SECTION);
  90. BEGIN
  91.     switch_task;
  92.     futex_wait(CriticalSection[0], 1, 10000);
  93.     CriticalSection[1] := 1
  94. END EnterCriticalSection;
  95.  
  96.  
  97. PROCEDURE LeaveCriticalSection* (VAR CriticalSection: CRITICAL_SECTION);
  98. BEGIN
  99.     CriticalSection[1] := 0;
  100.     futex_wake(CriticalSection[0], 1)
  101. END LeaveCriticalSection;
  102.  
  103.  
  104. PROCEDURE InitializeCriticalSection* (VAR CriticalSection: CRITICAL_SECTION);
  105. BEGIN
  106.     CriticalSection[0] := futex_create(SYSTEM.ADR(CriticalSection[1]));
  107.     CriticalSection[1] := 0
  108. END InitializeCriticalSection;
  109.  
  110.  
  111. PROCEDURE __NEW (size: INTEGER): INTEGER;
  112. VAR
  113.     res, idx, temp: INTEGER;
  114. BEGIN
  115.     IF size <= MAX_SIZE THEN
  116.         idx := ASR(size, 5);
  117.         res := pockets[idx];
  118.         IF res # 0 THEN
  119.             SYSTEM.GET(res, pockets[idx]);
  120.             SYSTEM.PUT(res, size);
  121.             INC(res, 4)
  122.         ELSE
  123.             temp := 0;
  124.             IF heap + size >= endheap THEN
  125.                 IF K.sysfunc2(18, 16) > ASR(HEAP_SIZE, 10) THEN
  126.                     temp := K.sysfunc3(68, 12, HEAP_SIZE)
  127.                 ELSE
  128.                     temp := 0
  129.                 END;
  130.                 IF temp # 0 THEN
  131.                     mem_commit(temp, HEAP_SIZE);
  132.                     heap := temp;
  133.                     endheap := heap + HEAP_SIZE
  134.                 ELSE
  135.                     temp := -1
  136.                 END
  137.             END;
  138.             IF (heap # 0) & (temp # -1) THEN
  139.                 SYSTEM.PUT(heap, size);
  140.                 res := heap + 4;
  141.                 heap := heap + size
  142.             ELSE
  143.                 res := 0
  144.             END
  145.         END
  146.     ELSE
  147.         IF K.sysfunc2(18, 16) > ASR(size, 10) THEN
  148.             res := K.sysfunc3(68, 12, size);
  149.             IF res # 0 THEN
  150.                 mem_commit(res, size);
  151.                 SYSTEM.PUT(res, size);
  152.                 INC(res, 4)
  153.             END
  154.         ELSE
  155.             res := 0
  156.         END
  157.     END;
  158.     IF (res # 0) & (size <= MAX_SIZE) THEN
  159.         zeromem(ASR(size, 2) - 1, res)
  160.     END
  161.     RETURN res
  162. END __NEW;
  163.  
  164.  
  165. PROCEDURE __DISPOSE (ptr: INTEGER): INTEGER;
  166. VAR
  167.     size, idx: INTEGER;
  168. BEGIN
  169.     DEC(ptr, 4);
  170.     SYSTEM.GET(ptr, size);
  171.     IF size <= MAX_SIZE THEN
  172.         idx := ASR(size, 5);
  173.         SYSTEM.PUT(ptr, pockets[idx]);
  174.         pockets[idx] := ptr
  175.     ELSE
  176.         size := K.sysfunc3(68, 13, ptr)
  177.     END
  178.     RETURN 0
  179. END __DISPOSE;
  180.  
  181.  
  182. PROCEDURE NEW_DISPOSE (func, arg: INTEGER): INTEGER;
  183. VAR
  184.     res: INTEGER;
  185.  
  186. BEGIN
  187.     IF multi THEN
  188.         EnterCriticalSection(CriticalSection)
  189.     END;
  190.  
  191.     IF func = _new THEN
  192.         res := __NEW(arg)
  193.     ELSIF func = _dispose THEN
  194.         res := __DISPOSE(arg)
  195.     END;
  196.  
  197.     IF multi THEN
  198.         LeaveCriticalSection(CriticalSection)
  199.     END
  200.  
  201.     RETURN res
  202. END NEW_DISPOSE;
  203.  
  204.  
  205. PROCEDURE _NEW* (size: INTEGER): INTEGER;
  206.     RETURN NEW_DISPOSE(_new, size)
  207. END _NEW;
  208.  
  209.  
  210. PROCEDURE _DISPOSE* (ptr: INTEGER): INTEGER;
  211.     RETURN NEW_DISPOSE(_dispose, ptr)
  212. END _DISPOSE;
  213.  
  214.  
  215. PROCEDURE exit* (p1: INTEGER);
  216. BEGIN
  217.     K.sysfunc1(-1)
  218. END exit;
  219.  
  220.  
  221. PROCEDURE exit_thread* (p1: INTEGER);
  222. BEGIN
  223.     K.sysfunc1(-1)
  224. END exit_thread;
  225.  
  226.  
  227. PROCEDURE OutChar (c: CHAR);
  228. BEGIN
  229.     K.sysfunc3(63, 1, ORD(c))
  230. END OutChar;
  231.  
  232.  
  233. PROCEDURE OutLn;
  234. BEGIN
  235.     OutChar(0DX);
  236.     OutChar(0AX)
  237. END OutLn;
  238.  
  239.  
  240. PROCEDURE OutStr (pchar: INTEGER);
  241. VAR
  242.     c: CHAR;
  243. BEGIN
  244.     IF pchar # 0 THEN
  245.         REPEAT
  246.             SYSTEM.GET(pchar, c);
  247.             IF c # 0X THEN
  248.                 OutChar(c)
  249.             END;
  250.             INC(pchar)
  251.         UNTIL c = 0X
  252.     END
  253. END OutStr;
  254.  
  255.  
  256. PROCEDURE DebugMsg* (lpText, lpCaption: INTEGER);
  257. BEGIN
  258.     IF lpCaption # 0 THEN
  259.         OutLn;
  260.         OutStr(lpCaption);
  261.         OutChar(":");
  262.         OutLn
  263.     END;
  264.     OutStr(lpText);
  265.     IF lpCaption # 0 THEN
  266.         OutLn
  267.     END
  268. END DebugMsg;
  269.  
  270.  
  271. PROCEDURE OutString (s: ARRAY OF CHAR);
  272. VAR
  273.     i: INTEGER;
  274. BEGIN
  275.     i := 0;
  276.     WHILE (i < LEN(s)) & (s[i] # 0X) DO
  277.         OutChar(s[i]);
  278.         INC(i)
  279.     END
  280. END OutString;
  281.  
  282.  
  283. PROCEDURE imp_error;
  284. BEGIN
  285.     OutString("import error: ");
  286.     IF K.imp_error.error = 1 THEN
  287.         OutString("can't load "); OutString(K.imp_error.lib)
  288.     ELSIF K.imp_error.error = 2 THEN
  289.         OutString("not found "); OutString(K.imp_error.proc); OutString(" in "); OutString(K.imp_error.lib)
  290.     END;
  291.     OutLn
  292. END imp_error;
  293.  
  294.  
  295. PROCEDURE init* (_import, code: INTEGER);
  296. BEGIN
  297.     multi := FALSE;
  298.     eol[0] := 0DX; eol[1] := 0AX; eol[2] := 0X;
  299.     base := code - SizeOfHeader;
  300.     K.sysfunc2(68, 11);
  301.     InitializeCriticalSection(CriticalSection);
  302.     K._init;
  303.     import := (K.dll_Load(_import) = 0) & (K.imp_error.error = 0);
  304.     IF ~import THEN
  305.         imp_error
  306.     END
  307. END init;
  308.  
  309.  
  310. PROCEDURE SetMultiThr* (value: BOOLEAN);
  311. BEGIN
  312.     multi := value
  313. END SetMultiThr;
  314.  
  315.  
  316. PROCEDURE GetTickCount* (): INTEGER;
  317.     RETURN K.sysfunc2(26, 9) * 10
  318. END GetTickCount;
  319.  
  320.  
  321. PROCEDURE dllentry* (hinstDLL, fdwReason, lpvReserved: INTEGER): INTEGER;
  322.     RETURN 0
  323. END dllentry;
  324.  
  325.  
  326. PROCEDURE sofinit*;
  327. END sofinit;
  328.  
  329.  
  330. END API.