Subversion Repositories Kolibri OS

Rev

Rev 9831 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2022. All rights reserved. ;;
  4. ;;  Distributed under terms of the GNU General Public License.  ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. $Revision: 9869 $
  9.  
  10. align 4
  11. ;struct futex*  __fastcall create_futex(int *ptr)
  12. create_futex:
  13.         push    ecx
  14.         mov     ecx, sizeof.FUTEX
  15.         call    create_object
  16.         pop     ecx
  17.         test    eax, eax
  18.         jz      .fail
  19.  
  20.         mov     [eax + FUTEX.magic], 'FUTX'
  21.         mov     [eax + FUTEX.destroy], 0
  22.         mov     [eax + FUTEX.pointer], ecx
  23.         lea     ecx, [eax + FUTEX.wait_list]
  24.         list_init ecx
  25.         mov     [eax + FUTEX.flags], 0
  26. .fail:
  27.         ret
  28.  
  29. align 4
  30. ;int __fastcall destroy_futex(struct futex *futex)
  31. destroy_futex:
  32.         push    esi
  33.         mov     esi, [current_process]
  34.         mov     edx, [ecx + FUTEX.handle]
  35.  
  36.         pushfd
  37.         cli
  38.  
  39.         lea     eax, [ecx + FUTEX.wait_list]
  40.         cmp     eax, [eax + LHEAD.next]
  41.         jne     .fail
  42.  
  43.         mov     eax, [esi + PROC.ht_next]
  44.         mov     [esi + PROC.htab + edx*4], eax
  45.         mov     [esi + PROC.ht_next], edx
  46.         inc     [esi + PROC.ht_free]
  47.  
  48.         popfd
  49.         pop     esi
  50.  
  51.         mov     eax, ecx
  52.         call    free
  53.         xor     eax, eax
  54.         ret
  55.  
  56. .fail:
  57.         popfd
  58.         pop     esi
  59.         mov     eax, -1
  60.         ret
  61.  
  62. align 4
  63. sys_futex:
  64.         cmp     ecx, STDERR_FILENO
  65.         jbe     .fail
  66.         cmp     ecx, (PROC.pdt_0 - PROC.htab)/4
  67.         jae     .fail
  68.  
  69.         mov     edi, [current_process]
  70.         mov     ebp, [edi + PROC.htab + ecx*4]
  71.  
  72.         cmp     [ebp + FUTEX.magic], 'FUTX'
  73.         jne     .fail
  74.         cmp     [ebp + FUTEX.handle], ecx
  75.         jne     .fail
  76.  
  77.         jmp     dword [sys_futex_call + ebx*4-4]
  78.  
  79. .fail:
  80. .requeue:
  81. .cmp_requeue:
  82. .wait_bitset:
  83. .wake_bitset:
  84.         mov     [esp + SYSCALL_STACK.eax], -1
  85.         ret
  86.  
  87. align 4
  88. .init:
  89.         call    create_futex
  90.         test    eax, eax
  91.         jz      @F
  92.         mov     eax, [eax + FUTEX.handle]
  93. @@:
  94.         mov     [esp + SYSCALL_STACK.eax], eax
  95.         ret
  96.  
  97. align 4
  98. ;ecx futex handle
  99. ;edi current process
  100. ;ebp futex object
  101. .destroy:
  102.         mov     ecx, ebp
  103.         call    destroy_futex
  104.         mov     [esp + SYSCALL_STACK.eax], eax
  105.         ret
  106.  
  107. align 4
  108. ;ecx futex handle
  109. ;edx control value
  110. ;esi timeout
  111. ;edi current process
  112. ;ebp futex object
  113. .wait:
  114.         test    esi, esi
  115.         jnz     .wait_timeout
  116.         mov     ecx, [ebp + FUTEX.pointer]
  117.         mov     eax, edx
  118.         lock cmpxchg [ecx], edx
  119.         je      .wait_slow
  120.  
  121.         mov     [esp + SYSCALL_STACK.eax], -2
  122.         ret
  123.  
  124. .wait_slow:
  125.         pushfd
  126.         cli
  127.  
  128.         sub     esp, sizeof.MUTEX_WAITER
  129.         mov     ebx, [current_slot]
  130.         mov     [esp + MUTEX_WAITER.task], ebx
  131.         lea     esi, [ebp + FUTEX.wait_list]
  132.  
  133.         list_add_tail esp, esi      ;esp= new waiter, esi= list head
  134.         mov     eax, edx
  135. .again:
  136.         mov     [ebx + APPDATA.state], TSTATE_RUN_SUSPENDED
  137.         call    change_task
  138.  
  139.         lock cmpxchg [ecx], edx
  140.         je      .again
  141.  
  142.         list_del esp
  143.         add     esp, sizeof.MUTEX_WAITER
  144.  
  145.         popfd
  146.         mov     [esp + SYSCALL_STACK.eax], 0
  147.         ret
  148.  
  149. align 4
  150. ;ecx futex handle
  151. ;edx control value
  152. ;esi timeout
  153. ;edi current process
  154. ;ebp futex object
  155.  
  156. .wait_timeout:
  157.         mov     ecx, [ebp + FUTEX.pointer]
  158.         mov     eax, edx
  159.         lock cmpxchg [ecx], edx         ;wait until old_value == new_value
  160.         je      .wait_slow_timeout
  161.  
  162.         mov     [esp + SYSCALL_STACK.eax], -2
  163.         ret
  164.  
  165. align 4
  166. .wait_test:
  167.         xor     eax, eax
  168.         ret
  169.  
  170. .wait_slow_timeout:
  171.         pushfd
  172.         cli
  173.  
  174.         sub     esp, sizeof.MUTEX_WAITER
  175.  
  176.         mov     ebx, [current_slot]
  177.         mov     [ebx + APPDATA.wait_test], sys_futex.wait_test
  178.         mov     [ebx + APPDATA.wait_timeout], esi
  179.         mov     [ebx + APPDATA.wait_param], ebp
  180.         mov     eax, [timer_ticks]
  181.         mov     [ebx + APPDATA.wait_begin], eax
  182.         mov     [ebx + APPDATA.state], TSTATE_WAITING
  183.  
  184.         mov     [esp + MUTEX_WAITER.task], ebx
  185.         lea     esi, [ebp + FUTEX.wait_list]
  186.  
  187.         list_add_tail esp, esi      ;esp= new waiter, esi= list head
  188.         sti
  189. .again_timeout:
  190.         call    change_task
  191.         mov     eax, [ebx + APPDATA.wait_param]
  192.         test    eax, eax
  193.         jz      .timeout
  194.         DEBUGF  1, "FUTEX no timeout [ecx]=%x edx=%x\n", [ecx], edx
  195.         mov     eax, edx
  196.         lock cmpxchg [ecx], edx
  197.         jz      .again_timeout
  198. @@:
  199.         cli
  200.         list_del esp
  201.         sti
  202.         add     esp, sizeof.MUTEX_WAITER
  203.         popfd
  204.         mov     [esp + SYSCALL_STACK.eax], 0
  205.         ret
  206.  
  207. .timeout:
  208.         cli
  209.         list_del esp
  210.         sti
  211.         add     esp, sizeof.MUTEX_WAITER
  212.         DEBUGF  1, "FUTEX timeout\n"
  213.         popfd
  214.         mov     [esp + SYSCALL_STACK.eax], -1
  215.         ret
  216.  
  217.  
  218. align 4
  219. ;ecx futex handle
  220. ;edx number of threads
  221. ;edi current process
  222. ;ebp futex object
  223. .wake:
  224.  
  225.         xor     ecx, ecx
  226.  
  227.         pushfd
  228.         cli
  229.  
  230.         lea     ebx, [ebp + FUTEX.wait_list]
  231.         mov     esi, [ebx + LHEAD.next]
  232. .again_wake:
  233.         cmp     esi, ebx
  234.         je      .done
  235.  
  236.         mov     eax, [esi + MUTEX_WAITER.task]
  237.         mov     [eax + APPDATA.state], TSTATE_RUNNING
  238.  
  239.         mov     esi, [esi + MUTEX_WAITER.list.next]
  240.         inc     ecx
  241.         cmp     ecx, edx
  242.         jb      .again_wake
  243. .done:
  244.         popfd
  245.         mov     [esp + SYSCALL_STACK.eax], ecx
  246.         ret
  247.  
  248.