Subversion Repositories Kolibri OS

Rev

Rev 6926 | Rev 6928 | 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    ecx
  44.         push    edx
  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     [ecx], eax
  106.         mov     [ecx+4], edx
  107.         add     esp, 5*4
  108.         pop     ebp
  109.         xor     eax, eax
  110.         mov     [esp+SYSCALL_STACK._eax], eax
  111.         ret
  112. .err_3:
  113.         mov     eax, ebp
  114.         call    free
  115.         mov     ebp, -ENFILE
  116. .err_2:
  117.         mov     ecx, [.fdwrite]
  118.         call    destroy_object
  119. .err_1:
  120.         mov     ecx, [.fdread]
  121.         call    destroy_object
  122. .err_0:
  123.         add     esp, 5*4
  124. .fail:
  125.         mov     [esp+SYSCALL_STACK._eax], ebp
  126.         pop     ebp
  127.         ret
  128.  
  129. purge .pipeflags
  130. purge .filefd
  131. purge .fdread
  132. purge .fdwrite
  133. purge .intpipe
  134.  
  135.  
  136. ; edx buf
  137. ; esi count
  138. ; ebp pipe
  139.  
  140. align 4
  141. pipe_read:
  142.         mov     edi, edx
  143.  
  144. .again:
  145.         lea     ecx, [ebp+PIPE.pipe_lock]
  146.         call    mutex_lock
  147.  
  148.         xor     eax, eax
  149.         cmp     eax, [ebp+PIPE.writers]
  150.         je      .eof
  151.  
  152.         mov     ecx, [ebp+PIPE.count]
  153.         test    ecx, ecx
  154.         jz      .wait
  155.  
  156. .check_count:
  157.         cmp     ecx, esi
  158.         jb      .read
  159.         mov     ecx, esi
  160. .read:
  161.         mov     esi, [ebp+PIPE.buffer]
  162.         add     esi, [ebp+PIPE.read_end]
  163.         mov     [esp+SYSCALL_STACK._eax], ecx
  164.         sub     [ebp+PIPE.count], ecx
  165.         cld
  166.         rep movsb
  167.         and     esi, 0xFFF
  168.         mov     [ebp+PIPE.read_end], esi
  169.  
  170.         lea     ecx, [ebp+PIPE.pipe_lock]
  171.         call    mutex_unlock
  172.         ret
  173.  
  174. .wait:
  175.         sub     esp, sizeof.MUTEX_WAITER
  176.         mov     ebx, [TASK_BASE]
  177.         mov     [esp+MUTEX_WAITER.task], ebx
  178.         lea     edx, [ebp+PIPE.rlist]
  179.  
  180.         list_add_tail esp, edx      ;esp= new waiter, edx= list head
  181.  
  182.         lea     ecx, [ebp+PIPE.pipe_lock]
  183.         call    mutex_unlock
  184.  
  185.         mov     [ebx+TASKDATA.state], 1
  186.         call    change_task
  187.  
  188.         list_del esp
  189.         add     esp, sizeof.MUTEX_WAITER
  190.         jmp     .again
  191.  
  192. .eof:
  193.         mov     [esp+SYSCALL_STACK._eax], eax
  194.         lea     ecx, [ebp+PIPE.pipe_lock]
  195.         call    mutex_unlock
  196.         ret
  197.  
  198. ; edx buf
  199. ; esi count
  200. ; ebp pipe
  201.  
  202. align 4
  203. pipe_write:
  204.         mov     edi, edx
  205.  
  206. .again:
  207.         lea     ecx, [ebp+PIPE.pipe_lock]
  208.         call    mutex_lock
  209.  
  210.         xor     eax, eax
  211.         cmp     eax, [ebp+PIPE.readers]
  212.         je      .epipe
  213.  
  214.         mov     ecx, [ebp+PIPE.count]
  215.         sub     ecx, 4096
  216.         jz      .wait
  217.  
  218. .check_count:
  219.         cmp     ecx, esi
  220.         jb      .write
  221.         mov     ecx, esi
  222. .write:
  223.         mov     esi, [ebp+PIPE.buffer]
  224.         add     esi, [ebp+PIPE.write_end]
  225.         mov     [esp+SYSCALL_STACK._eax], ecx
  226.         add     [ebp+PIPE.count], ecx
  227.         cld
  228.         rep movsb
  229.         and     esi, 0xFFF
  230.         mov     [ebp+PIPE.write_end], esi
  231.  
  232.         lea     ecx, [ebp+PIPE.pipe_lock]
  233.         call    mutex_unlock
  234.         ret
  235.  
  236. .wait:
  237.         sub     esp, sizeof.MUTEX_WAITER
  238.         mov     ebx, [TASK_BASE]
  239.         mov     [esp+MUTEX_WAITER.task], ebx
  240.         lea     edx, [ebp+PIPE.wlist]
  241.  
  242.         list_add_tail esp, edx      ;esp= new waiter, edx= list head
  243.  
  244.         lea     ecx, [ebp+PIPE.pipe_lock]
  245.         call    mutex_unlock
  246.  
  247.         mov     [ebx+TASKDATA.state], 1
  248.         call    change_task
  249.  
  250.         list_del esp
  251.         add     esp, sizeof.MUTEX_WAITER
  252.         jmp     .again
  253.  
  254. .epipe:
  255.         mov     [esp+SYSCALL_STACK._eax], -EPIPE
  256.         lea     ecx, [ebp+PIPE.pipe_lock]
  257.         call    mutex_unlock
  258.         ret
  259.  
  260. align 4
  261. pipe_close:
  262.         mov     [esp+SYSCALL_STACK._eax], -EBADF
  263.         ret
  264.