Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2017. All rights reserved. ;;
  4. ;;  Distributed under terms of the GNU General Public License.  ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. $Revision: 6917 $
  9.  
  10. O_CLOEXEC           equ 0x40000
  11. PIPE_BUFFER_SIZE    equ 4096
  12.  
  13.  
  14. iglobal
  15. align 4
  16. pipe_file_ops:
  17.         dd pipe_close       ;0
  18.         dd pipe_read        ;1
  19.         dd pipe_write       ;2
  20. endg
  21.  
  22. ;int pipe2(int pipefd[2], int flags);
  23. ;ecx pipefd
  24. ;edx flags
  25.  
  26. align 4
  27. sys_pipe2:
  28. .pipeflags equ  esp+16
  29. .pipefd    equ  esp+12
  30. .fdread    equ  esp+8
  31. .fdwrite   equ  esp+4
  32. .intpipe   equ  esp
  33.  
  34.         push    ebp
  35.         test    ecx, ecx
  36.         mov     ebp, -EFAULT
  37.         js      .fail
  38.  
  39.         test    edx, not O_CLOEXEC
  40.         mov     ebp, -EINVAL
  41.         jnz     .fail
  42.  
  43.         push    edx
  44.         push    ecx
  45.         sub     esp, (5-2)*4
  46.  
  47.         mov     ecx, sizeof.FILED
  48.         call    create_object
  49.         mov     [.fdread], eax
  50.         test    eax, eax
  51.         mov     ebp, -EMFILE
  52.         jz      .err_0
  53.  
  54.         mov     ecx, sizeof.FILED
  55.         call    create_object
  56.         mov     [.fdwrite], eax
  57.         test    eax, eax
  58.         jz      .err_1
  59.  
  60.         mov     eax, sizeof.PIPE
  61.         call    malloc
  62.         test    eax, eax
  63.         mov     ebp, -ENFILE
  64.         jz      .err_2
  65.  
  66.         mov     ebp, eax
  67.  
  68.         stdcall create_ring_buffer, PIPE_BUFFER_SIZE, PG_SWR
  69.         test    eax, eax
  70.         jz      .err_3
  71.  
  72.         mov     [ebp+PIPE.pipe_ops], pipe_file_ops
  73.         mov     [ebp+PIPE.buffer], eax
  74.  
  75.         xor     eax, eax
  76.         mov     [ebp+PIPE.count], eax
  77.         mov     [ebp+PIPE.read_end], eax
  78.         mov     [ebp+PIPE.write_end], eax
  79.  
  80.         inc     eax
  81.         mov     [ebp+PIPE.readers], eax
  82.         mov     [ebp+PIPE.writers], eax
  83.  
  84.         lea     ecx, [ebp+PIPE.pipe_lock]
  85.         call    mutex_init
  86.  
  87.         lea     ecx, [ebp+PIPE.rlist]
  88.         list_init ecx
  89.  
  90.         lea     ecx, [ebp+PIPE.wlist]
  91.         list_init ecx
  92.  
  93.         mov     eax, [.fdread]
  94.         mov     edx, [.fdwrite]
  95.         mov     ecx, [.pipefd]
  96.  
  97.         mov     [eax+FILED.magic], 'PIPE'
  98.         mov     [eax+FILED.destroy], 0
  99.         mov     [eax+FILED.file], ebp
  100.  
  101.         mov     [edx+FILED.magic], 'PIPE'
  102.         mov     [edx+FILED.destroy], 0
  103.         mov     [edx+FILED.file], ebp
  104.  
  105.         mov     eax, [eax+FILED.handle]
  106.         mov     edx, [edx+FILED.handle]
  107.  
  108.         mov     [ecx], eax
  109.         mov     [ecx+4], edx
  110.         add     esp, 5*4
  111.         pop     ebp
  112.         xor     eax, eax
  113.         mov     [esp+SYSCALL_STACK._eax], eax
  114.         ret
  115. .err_3:
  116.         mov     eax, ebp
  117.         call    free
  118.         mov     ebp, -ENFILE
  119. .err_2:
  120.         mov     ecx, [.fdwrite]
  121.         call    destroy_object
  122. .err_1:
  123.         mov     ecx, [.fdread]
  124.         call    destroy_object
  125. .err_0:
  126.         add     esp, 5*4
  127. .fail:
  128.         mov     [esp+SYSCALL_STACK._eax], ebp
  129.         pop     ebp
  130.         ret
  131.  
  132. purge .pipeflags
  133. purge .filefd
  134. purge .fdread
  135. purge .fdwrite
  136. purge .intpipe
  137.  
  138.  
  139. ; edx buf
  140. ; esi count
  141. ; ebp pipe
  142.  
  143. align 4
  144. pipe_read:
  145.         mov     edi, edx
  146.  
  147. .again:
  148.         lea     ecx, [ebp+PIPE.pipe_lock]
  149.         call    mutex_lock
  150.  
  151.         xor     eax, eax
  152.         cmp     eax, [ebp+PIPE.writers]
  153.         je      .eof
  154.  
  155.         mov     ecx, [ebp+PIPE.count]
  156.         test    ecx, ecx
  157.         jz      .wait
  158.  
  159. .check_count:
  160.         cmp     ecx, esi
  161.         jb      .read
  162.         mov     ecx, esi
  163. .read:
  164.         mov     esi, [ebp+PIPE.buffer]
  165.         add     esi, [ebp+PIPE.read_end]
  166.         mov     [esp+SYSCALL_STACK._eax], ecx
  167.         sub     [ebp+PIPE.count], ecx
  168.         cld
  169.         rep movsb
  170.         and     esi, 0xFFF
  171.         mov     [ebp+PIPE.read_end], esi
  172.  
  173.         lea     ecx, [ebp+PIPE.pipe_lock]
  174.         call    mutex_unlock
  175.         ret
  176.  
  177. .wait:
  178.         sub     esp, sizeof.MUTEX_WAITER
  179.         mov     ebx, [TASK_BASE]
  180.         mov     [esp+MUTEX_WAITER.task], ebx
  181.         lea     edx, [ebp+PIPE.rlist]
  182.  
  183.         list_add_tail esp, edx      ;esp= new waiter, edx= list head
  184.  
  185.         lea     ecx, [ebp+PIPE.pipe_lock]
  186.         call    mutex_unlock
  187.  
  188.         mov     [ebx+TASKDATA.state], 1
  189.         call    change_task
  190.  
  191.         list_del esp
  192.         add     esp, sizeof.MUTEX_WAITER
  193.         jmp     .again
  194.  
  195. .eof:
  196.         mov     [esp+SYSCALL_STACK._eax], eax
  197.         lea     ecx, [ebp+PIPE.pipe_lock]
  198.         call    mutex_unlock
  199.         ret
  200.  
  201. ; edx buf
  202. ; esi count
  203. ; ebp pipe
  204.  
  205. align 4
  206. pipe_write:
  207.         mov     edi, edx
  208.  
  209. .again:
  210.         lea     ecx, [ebp+PIPE.pipe_lock]
  211.         call    mutex_lock
  212.  
  213.         xor     eax, eax
  214.         cmp     eax, [ebp+PIPE.readers]
  215.         je      .epipe
  216.  
  217.         mov     ecx, [ebp+PIPE.count]
  218.         sub     ecx, 4096
  219.         jz      .wait
  220.  
  221. .check_count:
  222.         cmp     ecx, esi
  223.         jb      .write
  224.         mov     ecx, esi
  225. .write:
  226.         mov     esi, edi
  227.         mov     edi, [ebp+PIPE.buffer]
  228.         add     edi, [ebp+PIPE.write_end]
  229.         mov     [esp+SYSCALL_STACK._eax], ecx
  230.         add     [ebp+PIPE.count], ecx
  231.         cld
  232.         rep movsb
  233.         and     edi, 0xFFF
  234.         mov     [ebp+PIPE.write_end], edi
  235.  
  236.         lea     ecx, [ebp+PIPE.pipe_lock]
  237.         call    mutex_unlock
  238.         ret
  239.  
  240. .wait:
  241.         sub     esp, sizeof.MUTEX_WAITER
  242.         mov     ebx, [TASK_BASE]
  243.         mov     [esp+MUTEX_WAITER.task], ebx
  244.         lea     edx, [ebp+PIPE.wlist]
  245.  
  246.         list_add_tail esp, edx      ;esp= new waiter, edx= list head
  247.  
  248.         lea     ecx, [ebp+PIPE.pipe_lock]
  249.         call    mutex_unlock
  250.  
  251.         mov     [ebx+TASKDATA.state], 1
  252.         call    change_task
  253.  
  254.         list_del esp
  255.         add     esp, sizeof.MUTEX_WAITER
  256.         jmp     .again
  257.  
  258. .epipe:
  259.         mov     [esp+SYSCALL_STACK._eax], -EPIPE
  260.         lea     ecx, [ebp+PIPE.pipe_lock]
  261.         call    mutex_unlock
  262.         ret
  263.  
  264. align 4
  265. pipe_close:
  266.         mov     [esp+SYSCALL_STACK._eax], -EBADF
  267.         ret
  268.