Subversion Repositories Kolibri OS

Rev

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

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