Rev 5363 | Rev 6089 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5363 | Rev 6079 | ||
---|---|---|---|
Line 5... | Line 5... | ||
5 | ;; ;; |
5 | ;; ;; |
6 | ;; Synhronization for MenuetOS. ;; |
6 | ;; Synhronization for MenuetOS. ;; |
7 | ;; Author: Halyavin Andrey, halyavin@land.ru ;; |
7 | ;; Author: Halyavin Andrey, halyavin@land.ru ;; |
8 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
8 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
Line 9... | Line 9... | ||
9 | 9 | ||
- | 10 | $Revision: 6079 $ |
|
- | 11 | ||
- | 12 | align 4 |
|
- | 13 | ;struct futex* __fastcall create_futex(int *ptr) |
|
- | 14 | create_futex: |
|
- | 15 | push ecx |
|
- | 16 | mov ecx, sizeof.FUTEX |
|
- | 17 | call create_object |
|
- | 18 | pop ecx |
|
- | 19 | test eax, eax |
|
- | 20 | jz .fail |
|
- | 21 | ||
- | 22 | mov [eax+FUTEX.magic], 'FUTX' |
|
- | 23 | mov [eax+FUTEX.destroy], 0 |
|
- | 24 | mov [eax+FUTEX.pointer], ecx |
|
- | 25 | lea ecx, [eax+FUTEX.wait_list] |
|
- | 26 | list_init ecx |
|
- | 27 | mov [eax+FUTEX.flags], 0 |
|
- | 28 | .fail: |
|
- | 29 | ret |
|
- | 30 | ||
- | 31 | align 4 |
|
- | 32 | ;int __fastcall destroy_futex(struct futex *futex) |
|
- | 33 | destroy_futex: |
|
- | 34 | push esi |
|
- | 35 | mov esi, [current_process] |
|
- | 36 | mov edx, [ecx+FUTEX.handle] |
|
- | 37 | ||
- | 38 | pushfd |
|
- | 39 | cli |
|
- | 40 | ||
- | 41 | lea eax, [ecx+FUTEX.wait_list] |
|
- | 42 | cmp eax, [eax+LHEAD.next] |
|
- | 43 | jne .fail |
|
- | 44 | ||
- | 45 | mov eax, [esi+PROC.ht_next] |
|
- | 46 | mov [esi+PROC.htab+edx*4], eax |
|
- | 47 | mov [esi+PROC.ht_next], edx |
|
- | 48 | inc [esi+PROC.ht_free] |
|
- | 49 | ||
- | 50 | popfd |
|
- | 51 | pop esi |
|
- | 52 | ||
- | 53 | mov eax, ecx |
|
- | 54 | call free |
|
- | 55 | xor eax, eax |
|
- | 56 | ret |
|
- | 57 | ||
- | 58 | .fail: |
|
- | 59 | popfd |
|
- | 60 | pop esi |
|
- | 61 | mov eax, -1 |
|
- | 62 | ret |
|
- | 63 | ||
- | 64 | ||
- | 65 | iglobal |
|
- | 66 | align 4 |
|
- | 67 | f77call: |
|
- | 68 | dd f77.futex_init ;0 |
|
- | 69 | dd f77.futex_destroy ;1 |
|
- | 70 | dd f77.futex_wait ;2 |
|
- | 71 | dd f77.futex_wake ;3 |
|
- | 72 | .end: |
|
- | 73 | endg |
|
- | 74 | ||
- | 75 | align 4 |
|
- | 76 | sys_synchronization: |
|
- | 77 | f77: |
|
- | 78 | test ebx, ebx |
|
- | 79 | jz .futex_init |
|
- | 80 | ||
- | 81 | cmp ebx, (f77call.end-f77call)/4 |
|
- | 82 | jae .fail |
|
- | 83 | ||
- | 84 | cmp ecx, STDERR_FILENO |
|
- | 85 | jbe .fail |
|
- | 86 | cmp ecx, (PROC.pdt_0 - PROC.htab)/4 |
|
- | 87 | jae .fail |
|
- | 88 | ||
- | 89 | mov edi, [current_process] |
|
- | 90 | mov ebp, [edi+PROC.htab+ecx*4] |
|
- | 91 | ||
- | 92 | cmp [ebp+FUTEX.magic], 'FUTX' |
|
- | 93 | jne .fail |
|
- | 94 | cmp [ebp+FUTEX.handle], ecx |
|
- | 95 | jne .fail |
|
- | 96 | ||
- | 97 | jmp dword [f77call+ebx*4] |
|
- | 98 | ||
- | 99 | .fail: |
|
- | 100 | mov [esp+SYSCALL_STACK._eax], -1 |
|
- | 101 | ret |
|
- | 102 | ||
- | 103 | align 4 |
|
- | 104 | .futex_init: |
|
- | 105 | call create_futex |
|
- | 106 | test eax, eax |
|
- | 107 | jz @F |
|
- | 108 | mov eax, [eax+FUTEX.handle] |
|
- | 109 | @@: |
|
- | 110 | mov [esp+SYSCALL_STACK._eax], eax |
|
- | 111 | ret |
|
- | 112 | ||
- | 113 | ||
- | 114 | align 4 |
|
- | 115 | ;ecx futex handle |
|
- | 116 | ;edi current process |
|
- | 117 | ;ebp futex object |
|
- | 118 | .futex_destroy: |
|
- | 119 | mov ecx, ebp |
|
- | 120 | call destroy_futex |
|
- | 121 | mov [esp+SYSCALL_STACK._eax], eax |
|
- | 122 | ret |
|
- | 123 | ||
- | 124 | align 4 |
|
- | 125 | ;ecx futex handle |
|
- | 126 | ;edx control value |
|
- | 127 | ;esi timeout |
|
- | 128 | ;edi current process |
|
- | 129 | ;ebp futex object |
|
- | 130 | .futex_wait: |
|
- | 131 | test esi, esi |
|
- | 132 | jnz .futex_wait_timeout |
|
- | 133 | mov ecx, [ebp+FUTEX.pointer] |
|
- | 134 | mov eax, edx |
|
- | 135 | lock cmpxchg [ecx], edx ;wait until old_value == new_value |
|
- | 136 | jz .wait_slow |
|
- | 137 | ||
- | 138 | mov [esp+SYSCALL_STACK._eax], 0 |
|
- | 139 | ret |
|
- | 140 | ||
- | 141 | .wait_slow: |
|
- | 142 | pushfd |
|
- | 143 | cli |
|
- | 144 | ||
- | 145 | sub esp, sizeof.MUTEX_WAITER |
|
- | 146 | mov ebx, [TASK_BASE] |
|
- | 147 | mov [esp+MUTEX_WAITER.task], ebx |
|
- | 148 | lea esi, [ebp+FUTEX.wait_list] |
|
- | 149 | ||
- | 150 | list_add_tail esp, esi ;esp= new waiter, esi= list head |
|
- | 151 | ||
- | 152 | .again: |
|
- | 153 | mov [ebx+TASKDATA.state], 1 |
|
- | 154 | call change_task |
|
- | 155 | ||
- | 156 | lock cmpxchg [ecx], edx |
|
- | 157 | jz .again |
|
- | 158 | ||
- | 159 | list_del esp |
|
- | 160 | add esp, sizeof.MUTEX_WAITER |
|
- | 161 | ||
- | 162 | popfd |
|
- | 163 | mov [esp+SYSCALL_STACK._eax], 0 |
|
- | 164 | ret |
|
- | 165 | ||
- | 166 | align 4 |
|
- | 167 | ;ecx futex handle |
|
- | 168 | ;edx control value |
|
- | 169 | ;esi timeout |
|
- | 170 | ;edi current process |
|
- | 171 | ;ebp futex object |
|
- | 172 | ||
- | 173 | .futex_wait_timeout: |
|
- | 174 | mov ecx, [ebp+FUTEX.pointer] |
|
- | 175 | mov eax, edx |
|
- | 176 | lock cmpxchg [ecx], edx ;wait until old_value == new_value |
|
- | 177 | jz .wait_slow_timeout |
|
- | 178 | ||
- | 179 | mov [esp+SYSCALL_STACK._eax], 0 |
|
- | 180 | ret |
|
- | 181 | ||
- | 182 | align 4 |
|
- | 183 | .wait_test: |
|
- | 184 | xor eax, eax |
|
- | 185 | ret |
|
- | 186 | ||
- | 187 | .wait_slow_timeout: |
|
- | 188 | pushfd |
|
- | 189 | cli |
|
- | 190 | ||
- | 191 | sub esp, sizeof.MUTEX_WAITER |
|
- | 192 | ||
- | 193 | mov ebx, [current_slot] |
|
- | 194 | mov [ebx+APPDATA.wait_test], f77.wait_test |
|
- | 195 | mov [ebx+APPDATA.wait_timeout], esi |
|
- | 196 | mov [ebx+APPDATA.wait_param], ebp |
|
- | 197 | mov eax, [timer_ticks] |
|
- | 198 | mov [ebx+APPDATA.wait_begin], eax |
|
- | 199 | mov eax, [TASK_BASE] |
|
- | 200 | mov [eax+TASKDATA.state], 5 |
|
- | 201 | ||
- | 202 | mov [esp+MUTEX_WAITER.task], eax |
|
- | 203 | lea esi, [ebp+FUTEX.wait_list] |
|
- | 204 | ||
- | 205 | list_add_tail esp, esi ;esp= new waiter, esi= list head |
|
- | 206 | ||
- | 207 | .again_timeout: |
|
- | 208 | call change_task |
|
- | 209 | mov eax, [ebx+APPDATA.wait_param] |
|
- | 210 | test eax, eax |
|
- | 211 | jz .timeout |
|
- | 212 | ||
- | 213 | lock cmpxchg [ecx], edx |
|
- | 214 | jz .again_timeout |
|
- | 215 | @@: |
|
- | 216 | list_del esp |
|
- | 217 | add esp, sizeof.MUTEX_WAITER |
|
- | 218 | ||
- | 219 | popfd |
|
- | 220 | mov [esp+SYSCALL_STACK._eax], 0 |
|
- | 221 | ret |
|
- | 222 | ||
- | 223 | .timeout: |
|
- | 224 | list_del esp |
|
- | 225 | add esp, sizeof.MUTEX_WAITER |
|
- | 226 | ||
- | 227 | popfd |
|
- | 228 | mov [esp+SYSCALL_STACK._eax], -1 |
|
- | 229 | ret |
|
- | 230 | ||
- | 231 | ||
- | 232 | align 4 |
|
- | 233 | ;ecx futex handle |
|
- | 234 | ;edx number of threads |
|
- | 235 | ;edi current process |
|
- | 236 | ;ebp futex object |
|
- | 237 | .futex_wake: |
|
- | 238 | ||
- | 239 | xor ecx, ecx |
|
- | 240 | ||
- | 241 | pushfd |
|
- | 242 | cli |
|
- | 243 | ||
- | 244 | lea ebx, [ebp+FUTEX.wait_list] |
|
- | 245 | mov esi, [ebx+LHEAD.next] |
|
- | 246 | .wake: |
|
- | 247 | cmp esi, ebx |
|
- | 248 | je .done |
|
- | 249 | ||
- | 250 | mov eax, [esi+MUTEX_WAITER.task] |
|
- | 251 | mov [eax+TASKDATA.state], 0 |
|
- | 252 | ||
- | 253 | mov esi, [esi+MUTEX_WAITER.list.next] |
|
- | 254 | inc ecx |
|
- | 255 | cmp ecx, edx |
|
- | 256 | jb .wake |
|
- | 257 | .done: |
|
- | 258 | popfd |
|
- | 259 | mov [esp+SYSCALL_STACK._eax], ecx |
|
- | 260 | ret |
|
- | 261 | ||
- | 262 | RWSEM_WAITING_FOR_WRITE equ 0 |
|
- | 263 | RWSEM_WAITING_FOR_READ equ 1 |
|
- | 264 | ||
- | 265 | ;void __fastcall mutex_init(struct mutex *lock) |
|
- | 266 | ||
- | 267 | align 4 |
|
- | 268 | mutex_init: |
|
- | 269 | mov [ecx+MUTEX.wait_list.next], ecx |
|
- | 270 | mov [ecx+MUTEX.wait_list.prev], ecx |
|
- | 271 | mov [ecx+MUTEX.count], 1 |
|
- | 272 | ret |
|
- | 273 | ||
- | 274 | ;void __fastcall mutex_lock(struct mutex *lock) |
|
- | 275 | ||
- | 276 | align 4 |
|
- | 277 | mutex_lock: |
|
- | 278 | ||
- | 279 | dec [ecx+MUTEX.count] |
|
- | 280 | jns .done |
|
- | 281 | ||
- | 282 | pushfd |
|
- | 283 | cli |
|
- | 284 | ||
- | 285 | sub esp, sizeof.MUTEX_WAITER |
|
- | 286 | ||
- | 287 | list_add_tail esp, ecx ;esp= new waiter, ecx= list head |
|
- | 288 | ||
- | 289 | mov edx, [TASK_BASE] |
|
- | 290 | mov [esp+MUTEX_WAITER.task], edx |
|
- | 291 | ||
- | 292 | .forever: |
|
- | 293 | ||
- | 294 | mov eax, -1 |
|
- | 295 | xchg eax, [ecx+MUTEX.count] |
|
- | 296 | dec eax |
|
- | 297 | jz @F |
|
- | 298 | ||
- | 299 | mov [edx+TASKDATA.state], 1 |
|
- | 300 | call change_task |
|
- | 301 | jmp .forever |
|
- | 302 | @@: |
|
- | 303 | mov eax, ecx |
|
- | 304 | list_del esp |
|
- | 305 | ||
- | 306 | cmp [eax+MUTEX.wait_list.next], eax |
|
- | 307 | jne @F |
|
- | 308 | ||
- | 309 | mov [eax+MUTEX.count], 0 |
|
- | 310 | @@: |
|
- | 311 | add esp, sizeof.MUTEX_WAITER |
|
- | 312 | ||
- | 313 | popfd |
|
- | 314 | .done: |
|
- | 315 | ret |
|
- | 316 | ||
- | 317 | ;void __fastcall mutex_unlock(struct mutex *lock) |
|
- | 318 | ||
- | 319 | align 4 |
|
- | 320 | mutex_unlock: |
|
- | 321 | ||
- | 322 | pushfd |
|
- | 323 | cli |
|
- | 324 | ||
- | 325 | mov eax, [ecx+MUTEX.wait_list.next] |
|
- | 326 | cmp eax, ecx |
|
- | 327 | mov [ecx+MUTEX.count], 1 |
|
- | 328 | je @F |
|
- | 329 | ||
- | 330 | mov eax, [eax+MUTEX_WAITER.task] |
|
- | 331 | mov [eax+TASKDATA.state], 0 |
|
- | 332 | @@: |
|
- | 333 | popfd |
|
- | 334 | ret |
|
- | 335 | ||
- | 336 | ||
- | 337 | ;void __fastcall init_rwsem(struct rw_semaphore *sem) |
|
- | 338 | ||
- | 339 | align 4 |
|
- | 340 | init_rwsem: |
|
- | 341 | mov [ecx+RWSEM.wait_list.next], ecx |
|
- | 342 | mov [ecx+RWSEM.wait_list.prev], ecx |
|
- | 343 | mov [ecx+RWSEM.count], 0 |
|
- | 344 | ret |
|
- | 345 | ||
- | 346 | ;void __fastcall down_read(struct rw_semaphore *sem) |
|
- | 347 | ||
- | 348 | align 4 |
|
- | 349 | down_read: |
|
- | 350 | pushfd |
|
- | 351 | cli |
|
- | 352 | ||
- | 353 | mov eax, [ecx+RWSEM.count] |
|
- | 354 | test eax, eax |
|
- | 355 | js @F |
|
- | 356 | ||
- | 357 | cmp ecx, [ecx+RWSEM.wait_list.next] |
|
- | 358 | je .ok |
|
- | 359 | @@: |
|
- | 360 | sub esp, sizeof.MUTEX_WAITER |
|
- | 361 | ||
- | 362 | mov eax, [TASK_BASE] |
|
- | 363 | mov [esp+MUTEX_WAITER.task], eax |
|
- | 364 | mov [esp+MUTEX_WAITER.type], RWSEM_WAITING_FOR_READ |
|
- | 365 | mov [eax+TASKDATA.state], 1 |
|
- | 366 | ||
- | 367 | list_add_tail esp, ecx ;esp= new waiter, ecx= list head |
|
- | 368 | ||
- | 369 | call change_task |
|
- | 370 | ||
- | 371 | add esp, sizeof.MUTEX_WAITER |
|
- | 372 | popfd |
|
- | 373 | ret |
|
- | 374 | .ok: |
|
- | 375 | inc eax |
|
- | 376 | mov [ecx+RWSEM.count], eax |
|
- | 377 | ||
- | 378 | popfd |
|
- | 379 | ret |
|
- | 380 | ||
- | 381 | ;void __fastcall down_write(struct rw_semaphore *sem) |
|
- | 382 | ||
- | 383 | align 4 |
|
- | 384 | down_write: |
|
- | 385 | pushfd |
|
- | 386 | cli |
|
- | 387 | sub esp, sizeof.MUTEX_WAITER |
|
- | 388 | ||
- | 389 | mov edx, [TASK_BASE] |
|
- | 390 | mov [esp+MUTEX_WAITER.task], edx |
|
- | 391 | mov [esp+MUTEX_WAITER.type], RWSEM_WAITING_FOR_WRITE |
|
- | 392 | mov [edx+TASKDATA.state], 1 |
|
- | 393 | ||
- | 394 | list_add_tail esp, ecx ;esp= new waiter, ecx= list head |
|
- | 395 | ||
- | 396 | xor eax, eax |
|
- | 397 | not eax |
|
- | 398 | ||
- | 399 | .forever: |
|
- | 400 | test eax, [ecx+RWSEM.count] |
|
- | 401 | jz @F |
|
- | 402 | ||
- | 403 | mov [edx+TASKDATA.state], 1 |
|
- | 404 | call change_task |
|
- | 405 | jmp .forever |
|
- | 406 | @@: |
|
- | 407 | mov [ecx+RWSEM.count], eax |
|
- | 408 | list_del esp |
|
- | 409 | ||
- | 410 | add esp, sizeof.MUTEX_WAITER |
|
- | 411 | popfd |
|
- | 412 | ret |
|
- | 413 | ||
- | 414 | ;void __fastcall up_read(struct rw_semaphore *sem) |
|
- | 415 | ||
- | 416 | align 4 |
|
- | 417 | up_read: |
|
- | 418 | pushfd |
|
- | 419 | cli |
|
- | 420 | ||
- | 421 | dec [ecx+RWSEM.count] |
|
- | 422 | jnz @F |
|
- | 423 | ||
- | 424 | mov eax, [ecx+RWSEM.wait_list.next] |
|
- | 425 | cmp eax, ecx |
|
- | 426 | je @F |
|
- | 427 | ||
- | 428 | mov eax, [eax+MUTEX_WAITER.task] |
|
- | 429 | mov [eax+TASKDATA.state], 0 |
|
- | 430 | @@: |
|
- | 431 | popfd |
|
- | 432 | ret |
|
- | 433 | ||
- | 434 | ;void __fastcall up_write(struct rw_semaphore *sem) |
|
- | 435 | ||
- | 436 | align 4 |
|
- | 437 | up_write: |
|
- | 438 | ||
- | 439 | pushfd |
|
- | 440 | cli |
|
- | 441 | ||
- | 442 | mov eax, [ecx+RWSEM.wait_list.next] |
|
- | 443 | mov [ecx+RWSEM.count], 0 |
|
- | 444 | ||
- | 445 | cmp ecx, eax |
|
- | 446 | je .done |
|
- | 447 | ||
- | 448 | mov edx, [eax+MUTEX_WAITER.type] |
|
- | 449 | test edx, edx |
|
- | 450 | jnz .wake |
|
- | 451 | ||
- | 452 | mov eax, [eax+MUTEX_WAITER.task] |
|
- | 453 | mov [eax+TASKDATA.state], 0 |
|
- | 454 | .done: |
|
- | 455 | popfd |
|
- | 456 | ret |
|
- | 457 | ||
- | 458 | .wake: |
|
- | 459 | push ebx |
|
- | 460 | push esi |
|
- | 461 | push edi |
|
- | 462 | ||
- | 463 | xor esi, esi |
|
- | 464 | mov edi, ecx |
|
- | 465 | ||
- | 466 | .wake_list: |
|
- | 467 | ||
- | 468 | mov ebx, [eax+MUTEX_WAITER.list.next] |
|
- | 469 | list_del eax |
|
- | 470 | mov edx, [eax+MUTEX_WAITER.task] |
|
- | 471 | mov [edx+TASKDATA.state], 0 |
|
- | 472 | inc esi |
|
- | 473 | cmp edi, ebx |
|
- | 474 | je .wake_done |
|
- | 475 | ||
- | 476 | mov ecx, [ebx+MUTEX_WAITER.type] |
|
- | 477 | test ecx, ecx |
|
- | 478 | jz .wake_done |
|
- | 479 | ||
- | 480 | mov eax, ebx |
|
- | 481 | jmp .wake_list |
|
- | 482 | ||
- | 483 | .wake_done: |
|
- | 484 | add [edi+RWSEM.count], esi |
|
- | 485 | ||
- | 486 | pop edi |
|
- | 487 | pop esi |
|
- | 488 | pop ebx |
|
- | 489 | popfd |
|
- | 490 | ret |
|
- | 491 | ||
- | 492 | ||
- | 493 | purge RWSEM_WAITING_FOR_WRITE |
|
Line 10... | Line 494... | ||
10 | $Revision: 5363 $ |
494 | purge RWSEM_WAITING_FOR_READ |
11 | 495 | ||
12 | 496 |