wine  6.0.1
About: Wine is an Open Source implementation of the MS Windows API on top of X, OpenGL, and Unix. Think of Wine as a compatibility layer for running Windows programs.
  Fossies Dox: wine-6.0.1.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

thread.c
Go to the documentation of this file.
1 /*
2  * Win32 threads
3  *
4  * Copyright 1996, 2002, 2019 Alexandre Julliard
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #include <stdarg.h>
22 #include <string.h>
23 #include <limits.h>
24 
25 #include "ntstatus.h"
26 #define WIN32_NO_STATUS
27 #define NONAMELESSUNION
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winnls.h"
31 #include "winternl.h"
32 
33 #include "kernelbase.h"
34 #include "wine/exception.h"
35 #include "wine/asm.h"
36 #include "wine/debug.h"
37 #include "wine/heap.h"
38 
40 
41 
42 /***********************************************************************
43  * Threads
44  ***********************************************************************/
45 
46 
47 static DWORD rtlmode_to_win32mode( DWORD rtlmode )
48 {
49  DWORD win32mode = 0;
50 
51  if (rtlmode & 0x10) win32mode |= SEM_FAILCRITICALERRORS;
52  if (rtlmode & 0x20) win32mode |= SEM_NOGPFAULTERRORBOX;
53  if (rtlmode & 0x40) win32mode |= SEM_NOOPENFILEERRORBOX;
54  return win32mode;
55 }
56 
57 
58 /***************************************************************************
59  * CreateRemoteThread (kernelbase.@)
60  */
63  DWORD flags, DWORD *id )
64 {
65  return CreateRemoteThreadEx( process, sa, stack, start, param, flags, NULL, id );
66 }
67 
68 
69 /***************************************************************************
70  * CreateRemoteThreadEx (kernelbase.@)
71  */
76 {
77  HANDLE handle;
78  CLIENT_ID client_id;
79  SIZE_T stack_reserve = 0, stack_commit = 0;
80 
81  if (attributes) FIXME("thread attributes ignored\n");
82 
83  if (flags & STACK_SIZE_PARAM_IS_A_RESERVATION) stack_reserve = stack;
84  else stack_commit = stack;
85 
87  NULL, stack_reserve, stack_commit,
88  (PRTL_THREAD_START_ROUTINE)start, param, &handle, &client_id )))
89  return 0;
90 
91  if (id) *id = HandleToULong( client_id.UniqueThread );
92  if (sa && sa->nLength >= sizeof(*sa) && sa->bInheritHandle)
94  if (!(flags & CREATE_SUSPENDED))
95  {
96  ULONG ret;
97  if (NtResumeThread( handle, &ret ))
98  {
99  NtClose( handle );
101  handle = 0;
102  }
103  }
104  return handle;
105 }
106 
107 
108 /***********************************************************************
109  * CreateThread (kernelbase.@)
110  */
113  DWORD flags, LPDWORD id )
114 {
115  return CreateRemoteThread( GetCurrentProcess(), sa, stack, start, param, flags, id );
116 }
117 
118 
119 /***********************************************************************
120  * FreeLibraryAndExitThread (kernelbase.@)
121  */
123 {
124  FreeLibrary( module );
125  RtlExitUserThread( exit_code );
126 }
127 
128 
129 /***********************************************************************
130  * GetCurrentThreadStackLimits (kernelbase.@)
131  */
133 {
134  *low = (ULONG_PTR)NtCurrentTeb()->DeallocationStack;
135  *high = (ULONG_PTR)NtCurrentTeb()->Tib.StackBase;
136 }
137 
138 
139 /***********************************************************************
140  * GetCurrentThread (kernelbase.@)
141  */
143 {
144  return (HANDLE)~(ULONG_PTR)1;
145 }
146 
147 
148 /***********************************************************************
149  * GetCurrentThreadId (kernelbase.@)
150  */
152 {
153  return HandleToULong( NtCurrentTeb()->ClientId.UniqueThread );
154 }
155 
156 
157 /**********************************************************************
158  * GetExitCodeThread (kernelbase.@)
159  */
161 {
164  &info, sizeof(info), NULL );
165  if (!status && exit_code) *exit_code = info.ExitStatus;
166  return set_ntstatus( status );
167 }
168 
169 
170 /**********************************************************************
171  * GetLastError (kernelbase.@)
172  */
174 {
175  return NtCurrentTeb()->LastErrorValue;
176 }
177 
178 
179 /**********************************************************************
180  * GetProcessIdOfThread (kernelbase.@)
181  */
183 {
185 
187  return 0;
188  return HandleToULong( tbi.ClientId.UniqueProcess );
189 }
190 
191 
192 /***********************************************************************
193  * GetThreadContext (kernelbase.@)
194  */
196 {
198 }
199 
200 
201 /***********************************************************************
202  * GetThreadErrorMode (kernelbase.@)
203  */
205 {
207 }
208 
209 
210 /***********************************************************************
211  * GetThreadGroupAffinity (kernelbase.@)
212  */
214 {
215  if (!affinity)
216  {
218  return FALSE;
219  }
221  affinity, sizeof(*affinity), NULL ));
222 }
223 
224 
225 /***********************************************************************
226  * GetThreadIOPendingFlag (kernelbase.@)
227  */
229 {
231  pending, sizeof(*pending), NULL ));
232 }
233 
234 
235 /**********************************************************************
236  * GetThreadId (kernelbase.@)
237  */
239 {
241 
243  return 0;
244  return HandleToULong( tbi.ClientId.UniqueThread );
245 }
246 
247 
248 /***********************************************************************
249  * GetThreadIdealProcessorEx (kernelbase.@)
250  */
252 {
253  FIXME( "(%p %p): stub\n", thread, ideal );
255  return FALSE;
256 }
257 
258 
259 /***********************************************************************
260  * GetThreadLocale (kernelbase.@)
261  */
262 LCID WINAPI /* DECLSPEC_HOTPATCH */ GetThreadLocale(void)
263 {
264  LCID ret = NtCurrentTeb()->CurrentLocale;
265  if (!ret) NtCurrentTeb()->CurrentLocale = ret = GetUserDefaultLCID();
266  return ret;
267 }
268 
269 
270 /**********************************************************************
271  * GetThreadPriority (kernelbase.@)
272  */
274 {
276 
278  &info, sizeof(info), NULL )))
280  return info.Priority;
281 }
282 
283 
284 /**********************************************************************
285  * GetThreadPriorityBoost (kernelbase.@)
286  */
288 {
289  if (state) *state = FALSE;
290  return TRUE;
291 }
292 
293 
294 /**********************************************************************
295  * GetThreadTimes (kernelbase.@)
296  */
298  LPFILETIME kerneltime, LPFILETIME usertime )
299 {
300  KERNEL_USER_TIMES times;
301 
302  if (!set_ntstatus( NtQueryInformationThread( thread, ThreadTimes, &times, sizeof(times), NULL )))
303  return FALSE;
304 
305  if (creationtime)
306  {
307  creationtime->dwLowDateTime = times.CreateTime.u.LowPart;
308  creationtime->dwHighDateTime = times.CreateTime.u.HighPart;
309  }
310  if (exittime)
311  {
312  exittime->dwLowDateTime = times.ExitTime.u.LowPart;
313  exittime->dwHighDateTime = times.ExitTime.u.HighPart;
314  }
315  if (kerneltime)
316  {
317  kerneltime->dwLowDateTime = times.KernelTime.u.LowPart;
318  kerneltime->dwHighDateTime = times.KernelTime.u.HighPart;
319  }
320  if (usertime)
321  {
322  usertime->dwLowDateTime = times.UserTime.u.LowPart;
323  usertime->dwHighDateTime = times.UserTime.u.HighPart;
324  }
325  return TRUE;
326 }
327 
328 
329 /***********************************************************************
330  * GetThreadUILanguage (kernelbase.@)
331  */
333 {
334  LANGID lang;
335 
336  FIXME(": stub, returning default language.\n");
337  NtQueryDefaultUILanguage( &lang );
338  return lang;
339 }
340 
341 
342 /***********************************************************************
343  * OpenThread (kernelbase.@)
344  */
346 {
347  HANDLE handle;
349  CLIENT_ID cid;
350 
351  attr.Length = sizeof(attr);
352  attr.RootDirectory = 0;
353  attr.Attributes = inherit ? OBJ_INHERIT : 0;
354  attr.ObjectName = NULL;
355  attr.SecurityDescriptor = NULL;
356  attr.SecurityQualityOfService = NULL;
357 
358  cid.UniqueProcess = 0;
359  cid.UniqueThread = ULongToHandle( id );
360 
361  if (!set_ntstatus( NtOpenThread( &handle, access, &attr, &cid ))) handle = 0;
362  return handle;
363 }
364 
365 
366 /* callback for QueueUserAPC */
367 static void CALLBACK call_user_apc( ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3 )
368 {
369  PAPCFUNC func = (PAPCFUNC)arg1;
370  func( arg2 );
371 }
372 
373 /***********************************************************************
374  * QueueUserAPC (kernelbase.@)
375  */
377 {
379 }
380 
381 
382 /***********************************************************************
383  * QueryThreadCycleTime (kernelbase.@)
384  */
386 {
387  static int once;
388  if (!once++) FIXME( "(%p,%p): stub!\n", thread, cycle );
390  return FALSE;
391 }
392 
393 
394 /**********************************************************************
395  * ResumeThread (kernelbase.@)
396  */
398 {
399  DWORD ret;
400 
401  if (!set_ntstatus( NtResumeThread( thread, &ret ))) ret = ~0U;
402  return ret;
403 }
404 
405 
406 /***********************************************************************
407  * SetThreadContext (kernelbase.@)
408  */
410 {
412 }
413 
414 
415 /***********************************************************************
416  * SetThreadDescription (kernelbase.@)
417  */
419 {
421  int length;
422 
423  TRACE( "(%p, %s)\n", thread, debugstr_w( description ));
424 
425  length = description ? lstrlenW( description ) * sizeof(WCHAR) : 0;
426 
427  if (length > USHRT_MAX)
429 
430  info.Description.Length = info.Description.MaximumLength = length;
431  info.Description.Buffer = (WCHAR *)description;
432 
434 }
435 
436 /***********************************************************************
437  * GetThreadDescription (kernelbase.@)
438  */
440 {
443  ULONG length;
444 
445  TRACE( "(%p, %p)\n", thread, description );
446 
447  *description = NULL;
448 
449  length = 0;
452  return HRESULT_FROM_NT(status);
453 
454  if (!(info = heap_alloc( length )))
456 
458  if (!status)
459  {
460  if (!(*description = LocalAlloc( 0, info->Description.Length + sizeof(WCHAR))))
462  else
463  {
464  if (info->Description.Length)
465  memcpy(*description, info->Description.Buffer, info->Description.Length);
466  (*description)[info->Description.Length / sizeof(WCHAR)] = 0;
467  }
468  }
469 
470  heap_free(info);
471 
472  return HRESULT_FROM_NT(status);
473 }
474 
475 /***********************************************************************
476  * SetThreadErrorMode (kernelbase.@)
477  */
479 {
481  DWORD new = 0;
482 
484  {
486  return FALSE;
487  }
488 
489  if (mode & SEM_FAILCRITICALERRORS) new |= 0x10;
490  if (mode & SEM_NOGPFAULTERRORBOX) new |= 0x20;
491  if (mode & SEM_NOOPENFILEERRORBOX) new |= 0x40;
492 
493  status = RtlSetThreadErrorMode( new, old );
494  if (!status && old) *old = rtlmode_to_win32mode( *old );
495  return set_ntstatus( status );
496 }
497 
498 
499 /***********************************************************************
500  * SetThreadGroupAffinity (kernelbase.@)
501  */
503  GROUP_AFFINITY *old )
504 {
505  if (old && !GetThreadGroupAffinity( thread, old )) return FALSE;
506  return set_ntstatus( NtSetInformationThread( thread, ThreadGroupInformation, new, sizeof(*new) ));
507 }
508 
509 
510 /**********************************************************************
511  * SetThreadIdealProcessor (kernelbase.@)
512  */
514 {
515  FIXME( "(%p %u): stub\n", thread, proc );
516  if (proc > MAXIMUM_PROCESSORS)
517  {
519  return ~0u;
520  }
521  return 0;
522 }
523 
524 
525 /***********************************************************************
526  * SetThreadIdealProcessorEx (kernelbase.@)
527  */
529  PROCESSOR_NUMBER *previous )
530 {
531  FIXME( "(%p %p %p): stub\n", thread, ideal, previous );
533  return FALSE;
534 }
535 
536 
537 /**********************************************************************
538  * SetThreadLocale (kernelbase.@)
539  */
541 {
543  if (lcid != GetThreadLocale())
544  {
546  {
548  return FALSE;
549  }
550  NtCurrentTeb()->CurrentLocale = lcid;
551  }
552  return TRUE;
553 }
554 
555 
556 /**********************************************************************
557  * SetThreadPriority (kernelbase.@)
558  */
560 {
561  DWORD prio = priority;
562  return set_ntstatus( NtSetInformationThread( thread, ThreadBasePriority, &prio, sizeof(prio) ));
563 }
564 
565 
566 /**********************************************************************
567  * SetThreadPriorityBoost (kernelbase.@)
568  */
570 {
571  return TRUE;
572 }
573 
574 
575 /**********************************************************************
576  * SetThreadStackGuarantee (kernelbase.@)
577  */
579 {
580  ULONG prev_size = NtCurrentTeb()->GuaranteedStackBytes;
581  ULONG new_size = (*size + 4095) & ~4095;
582 
583  /* at least 2 pages on 64-bit */
584  if (sizeof(void *) > sizeof(int) && new_size) new_size = max( new_size, 8192 );
585 
586  *size = prev_size;
587  if (new_size >= (char *)NtCurrentTeb()->Tib.StackBase - (char *)NtCurrentTeb()->DeallocationStack)
588  {
590  return FALSE;
591  }
592  if (new_size > prev_size) NtCurrentTeb()->GuaranteedStackBytes = (new_size + 4095) & ~4095;
593  return TRUE;
594 }
595 
596 
597 /**********************************************************************
598  * SetThreadUILanguage (kernelbase.@)
599  */
601 {
602  TRACE( "(0x%04x) stub - returning success\n", langid );
603 
605  return langid;
606 }
607 
608 
609 /**********************************************************************
610  * SuspendThread (kernelbase.@)
611  */
613 {
614  DWORD ret;
615 
616  if (!set_ntstatus( NtSuspendThread( thread, &ret ))) ret = ~0U;
617  return ret;
618 }
619 
620 
621 /***********************************************************************
622  * SwitchToThread (kernelbase.@)
623  */
625 {
627 }
628 
629 
630 /**********************************************************************
631  * TerminateThread (kernelbase.@)
632  */
634 {
635  return set_ntstatus( NtTerminateThread( handle, exit_code ));
636 }
637 
638 
639 /**********************************************************************
640  * TlsAlloc (kernelbase.@)
641  */
643 {
644  DWORD index;
645  PEB * const peb = NtCurrentTeb()->Peb;
646 
648  index = RtlFindClearBitsAndSet( peb->TlsBitmap, 1, 1 );
649  if (index != ~0U) NtCurrentTeb()->TlsSlots[index] = 0; /* clear the value */
650  else
651  {
652  index = RtlFindClearBitsAndSet( peb->TlsExpansionBitmap, 1, 0 );
653  if (index != ~0U)
654  {
655  if (!NtCurrentTeb()->TlsExpansionSlots &&
656  !(NtCurrentTeb()->TlsExpansionSlots = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
657  8 * sizeof(peb->TlsExpansionBitmapBits) * sizeof(void*) )))
658  {
659  RtlClearBits( peb->TlsExpansionBitmap, index, 1 );
660  index = ~0U;
662  }
663  else
664  {
665  NtCurrentTeb()->TlsExpansionSlots[index] = 0; /* clear the value */
666  index += TLS_MINIMUM_AVAILABLE;
667  }
668  }
670  }
672  return index;
673 }
674 
675 
676 /**********************************************************************
677  * TlsFree (kernelbase.@)
678  */
680 {
681  BOOL ret;
682 
684  if (index >= TLS_MINIMUM_AVAILABLE)
685  {
686  ret = RtlAreBitsSet( NtCurrentTeb()->Peb->TlsExpansionBitmap, index - TLS_MINIMUM_AVAILABLE, 1 );
687  if (ret) RtlClearBits( NtCurrentTeb()->Peb->TlsExpansionBitmap, index - TLS_MINIMUM_AVAILABLE, 1 );
688  }
689  else
690  {
691  ret = RtlAreBitsSet( NtCurrentTeb()->Peb->TlsBitmap, index, 1 );
692  if (ret) RtlClearBits( NtCurrentTeb()->Peb->TlsBitmap, index, 1 );
693  }
694  if (ret) NtSetInformationThread( GetCurrentThread(), ThreadZeroTlsCell, &index, sizeof(index) );
697  return ret;
698 }
699 
700 
701 /**********************************************************************
702  * TlsGetValue (kernelbase.@)
703  */
705 {
707  if (index < TLS_MINIMUM_AVAILABLE) return NtCurrentTeb()->TlsSlots[index];
708 
709  index -= TLS_MINIMUM_AVAILABLE;
710  if (index >= 8 * sizeof(NtCurrentTeb()->Peb->TlsExpansionBitmapBits))
711  {
713  return NULL;
714  }
715  if (!NtCurrentTeb()->TlsExpansionSlots) return NULL;
716  return NtCurrentTeb()->TlsExpansionSlots[index];
717 }
718 
719 
720 /**********************************************************************
721  * TlsSetValue (kernelbase.@)
722  */
724 {
725  if (index < TLS_MINIMUM_AVAILABLE)
726  {
727  NtCurrentTeb()->TlsSlots[index] = value;
728  }
729  else
730  {
731  index -= TLS_MINIMUM_AVAILABLE;
732  if (index >= 8 * sizeof(NtCurrentTeb()->Peb->TlsExpansionBitmapBits))
733  {
735  return FALSE;
736  }
737  if (!NtCurrentTeb()->TlsExpansionSlots &&
738  !(NtCurrentTeb()->TlsExpansionSlots = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
739  8 * sizeof(NtCurrentTeb()->Peb->TlsExpansionBitmapBits) * sizeof(void*) )))
740  {
742  return FALSE;
743  }
744  NtCurrentTeb()->TlsExpansionSlots[index] = value;
745  }
746  return TRUE;
747 }
748 
749 
750 /***********************************************************************
751  * Fibers
752  ***********************************************************************/
753 
754 
756 {
757  LPVOID param; /* 00/00 fiber param */
758  void *except; /* 04/08 saved exception handlers list */
759  void *stack_base; /* 08/10 top of fiber stack */
760  void *stack_limit; /* 0c/18 fiber stack low-water mark */
761  void *stack_allocation; /* 10/20 base of the fiber stack allocation */
762  CONTEXT context; /* 14/30 fiber context */
763  DWORD flags; /* fiber flags */
764  LPFIBER_START_ROUTINE start; /* start routine */
765  void *fls_slots; /* fiber storage slots */
766 };
767 
768 extern void WINAPI switch_fiber( CONTEXT *old, CONTEXT *new );
769 #ifdef __i386__
771  "movl 4(%esp),%ecx\n\t" /* old */
772  "movl %edi,0x9c(%ecx)\n\t" /* old->Edi */
773  "movl %esi,0xa0(%ecx)\n\t" /* old->Esi */
774  "movl %ebx,0xa4(%ecx)\n\t" /* old->Ebx */
775  "movl %ebp,0xb4(%ecx)\n\t" /* old->Ebp */
776  "movl 0(%esp),%eax\n\t"
777  "movl %eax,0xb8(%ecx)\n\t" /* old->Eip */
778  "leal 12(%esp),%eax\n\t"
779  "movl %eax,0xc4(%ecx)\n\t" /* old->Esp */
780  "movl 8(%esp),%ecx\n\t" /* new */
781  "movl 0x9c(%ecx),%edi\n\t" /* new->Edi */
782  "movl 0xa0(%ecx),%esi\n\t" /* new->Esi */
783  "movl 0xa4(%ecx),%ebx\n\t" /* new->Ebx */
784  "movl 0xb4(%ecx),%ebp\n\t" /* new->Ebp */
785  "movl 0xc4(%ecx),%esp\n\t" /* new->Esp */
786  "jmp *0xb8(%ecx)" ) /* new->Eip */
787 #elif defined(__x86_64__)
789  "movq %rbx,0x90(%rcx)\n\t" /* old->Rbx */
790  "leaq 0x8(%rsp),%rax\n\t"
791  "movq %rax,0x98(%rcx)\n\t" /* old->Rsp */
792  "movq %rbp,0xa0(%rcx)\n\t" /* old->Rbp */
793  "movq %rsi,0xa8(%rcx)\n\t" /* old->Rsi */
794  "movq %rdi,0xb0(%rcx)\n\t" /* old->Rdi */
795  "movq %r12,0xd8(%rcx)\n\t" /* old->R12 */
796  "movq %r13,0xe0(%rcx)\n\t" /* old->R13 */
797  "movq %r14,0xe8(%rcx)\n\t" /* old->R14 */
798  "movq %r15,0xf0(%rcx)\n\t" /* old->R15 */
799  "movq (%rsp),%rax\n\t"
800  "movq %rax,0xf8(%rcx)\n\t" /* old->Rip */
801  "movdqa %xmm6,0x200(%rcx)\n\t" /* old->Xmm6 */
802  "movdqa %xmm7,0x210(%rcx)\n\t" /* old->Xmm7 */
803  "movdqa %xmm8,0x220(%rcx)\n\t" /* old->Xmm8 */
804  "movdqa %xmm9,0x230(%rcx)\n\t" /* old->Xmm9 */
805  "movdqa %xmm10,0x240(%rcx)\n\t" /* old->Xmm10 */
806  "movdqa %xmm11,0x250(%rcx)\n\t" /* old->Xmm11 */
807  "movdqa %xmm12,0x260(%rcx)\n\t" /* old->Xmm12 */
808  "movdqa %xmm13,0x270(%rcx)\n\t" /* old->Xmm13 */
809  "movdqa %xmm14,0x280(%rcx)\n\t" /* old->Xmm14 */
810  "movdqa %xmm15,0x290(%rcx)\n\t" /* old->Xmm15 */
811  "movq 0x90(%rdx),%rbx\n\t" /* new->Rbx */
812  "movq 0xa0(%rdx),%rbp\n\t" /* new->Rbp */
813  "movq 0xa8(%rdx),%rsi\n\t" /* new->Rsi */
814  "movq 0xb0(%rdx),%rdi\n\t" /* new->Rdi */
815  "movq 0xd8(%rdx),%r12\n\t" /* new->R12 */
816  "movq 0xe0(%rdx),%r13\n\t" /* new->R13 */
817  "movq 0xe8(%rdx),%r14\n\t" /* new->R14 */
818  "movq 0xf0(%rdx),%r15\n\t" /* new->R15 */
819  "movdqa 0x200(%rdx),%xmm6\n\t" /* new->Xmm6 */
820  "movdqa 0x210(%rdx),%xmm7\n\t" /* new->Xmm7 */
821  "movdqa 0x220(%rdx),%xmm8\n\t" /* new->Xmm8 */
822  "movdqa 0x230(%rdx),%xmm9\n\t" /* new->Xmm9 */
823  "movdqa 0x240(%rdx),%xmm10\n\t" /* new->Xmm10 */
824  "movdqa 0x250(%rdx),%xmm11\n\t" /* new->Xmm11 */
825  "movdqa 0x260(%rdx),%xmm12\n\t" /* new->Xmm12 */
826  "movdqa 0x270(%rdx),%xmm13\n\t" /* new->Xmm13 */
827  "movdqa 0x280(%rdx),%xmm14\n\t" /* new->Xmm14 */
828  "movdqa 0x290(%rdx),%xmm15\n\t" /* new->Xmm15 */
829  "movq 0x98(%rdx),%rsp\n\t" /* new->Rsp */
830  "jmp *0xf8(%rdx)" ) /* new->Rip */
831 #elif defined(__arm__)
833  "str r4, [r0, #0x14]\n\t" /* old->R4 */
834  "str r5, [r0, #0x18]\n\t" /* old->R5 */
835  "str r6, [r0, #0x1c]\n\t" /* old->R6 */
836  "str r7, [r0, #0x20]\n\t" /* old->R7 */
837  "str r8, [r0, #0x24]\n\t" /* old->R8 */
838  "str r9, [r0, #0x28]\n\t" /* old->R9 */
839  "str r10, [r0, #0x2c]\n\t" /* old->R10 */
840  "str r11, [r0, #0x30]\n\t" /* old->R11 */
841  "str sp, [r0, #0x38]\n\t" /* old->Sp */
842  "str lr, [r0, #0x40]\n\t" /* old->Pc */
843  "ldr r4, [r1, #0x14]\n\t" /* new->R4 */
844  "ldr r5, [r1, #0x18]\n\t" /* new->R5 */
845  "ldr r6, [r1, #0x1c]\n\t" /* new->R6 */
846  "ldr r7, [r1, #0x20]\n\t" /* new->R7 */
847  "ldr r8, [r1, #0x24]\n\t" /* new->R8 */
848  "ldr r9, [r1, #0x28]\n\t" /* new->R9 */
849  "ldr r10, [r1, #0x2c]\n\t" /* new->R10 */
850  "ldr r11, [r1, #0x30]\n\t" /* new->R11 */
851  "ldr sp, [r1, #0x38]\n\t" /* new->Sp */
852  "ldr r2, [r1, #0x40]\n\t" /* new->Pc */
853  "bx r2" )
854 #elif defined(__aarch64__)
856  "stp x19, x20, [x0, #0xa0]\n\t" /* old->X19,X20 */
857  "stp x21, x22, [x0, #0xb0]\n\t" /* old->X21,X22 */
858  "stp x23, x24, [x0, #0xc0]\n\t" /* old->X23,X24 */
859  "stp x25, x26, [x0, #0xd0]\n\t" /* old->X25,X26 */
860  "stp x27, x28, [x0, #0xe0]\n\t" /* old->X27,X28 */
861  "str x29, [x0, #0xf0]\n\t" /* old->Fp */
862  "mov x2, sp\n\t"
863  "str x2, [x0, #0x100]\n\t" /* old->Sp */
864  "str x30, [x0, #0x108]\n\t" /* old->Pc */
865  "ldp x19, x20, [x1, #0xa0]\n\t" /* new->X19,X20 */
866  "ldp x21, x22, [x1, #0xb0]\n\t" /* new->X21,X22 */
867  "ldp x23, x24, [x1, #0xc0]\n\t" /* new->X23,X24 */
868  "ldp x25, x26, [x1, #0xd0]\n\t" /* new->X25,X26 */
869  "ldp x27, x28, [x1, #0xe0]\n\t" /* new->X27,X28 */
870  "ldr x29, [x1, #0xf0]\n\t" /* new->Fp */
871  "ldr x2, [x1, #0x100]\n\t" /* new->Sp */
872  "ldr x30, [x1, #0x108]\n\t" /* new->Pc */
873  "mov sp, x2\n\t"
874  "ret" )
875 #else
876 void WINAPI switch_fiber( CONTEXT *old, CONTEXT *new )
877 {
878  FIXME( "not implemented\n" );
879  DbgBreakPoint();
880 }
881 #endif
882 
883 /* call the fiber initial function once we have switched stack */
884 static void CDECL start_fiber(void)
885 {
886  struct fiber_data *fiber = NtCurrentTeb()->Tib.u.FiberData;
888 
889  __TRY
890  {
891  start( fiber->param );
892  RtlExitUserThread( 1 );
893  }
895  {
897  }
898  __ENDTRY
899 }
900 
901 static void init_fiber_context( struct fiber_data *fiber )
902 {
903 #ifdef __i386__
904  fiber->context.Esp = (ULONG_PTR)fiber->stack_base - 4;
905  fiber->context.Eip = (ULONG_PTR)start_fiber;
906 #elif defined(__x86_64__)
907  fiber->context.Rsp = (ULONG_PTR)fiber->stack_base - 0x28;
908  fiber->context.Rip = (ULONG_PTR)start_fiber;
909 #elif defined(__arm__)
910  fiber->context.Sp = (ULONG_PTR)fiber->stack_base;
911  fiber->context.Pc = (ULONG_PTR)start_fiber;
912 #elif defined(__aarch64__)
913  fiber->context.Sp = (ULONG_PTR)fiber->stack_base;
914  fiber->context.Pc = (ULONG_PTR)start_fiber;
915 #endif
916 }
917 
918 
919 /***********************************************************************
920  * CreateFiber (kernelbase.@)
921  */
923 {
924  return CreateFiberEx( stack, 0, 0, start, param );
925 }
926 
927 
928 /***********************************************************************
929  * CreateFiberEx (kernelbase.@)
930  */
933 {
934  struct fiber_data *fiber;
935  INITIAL_TEB stack;
936 
937  if (!(fiber = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*fiber) )))
938  {
940  return NULL;
941  }
942 
943  if (!set_ntstatus( RtlCreateUserStack( stack_commit, stack_reserve, 0, 1, 1, &stack )))
944  {
945  HeapFree( GetProcessHeap(), 0, fiber );
946  return NULL;
947  }
948 
949  fiber->stack_allocation = stack.DeallocationStack;
950  fiber->stack_base = stack.StackBase;
951  fiber->stack_limit = stack.StackLimit;
952  fiber->param = param;
953  fiber->except = (void *)-1;
954  fiber->start = start;
955  fiber->flags = flags;
956  init_fiber_context( fiber );
957  return fiber;
958 }
959 
960 
961 /***********************************************************************
962  * ConvertFiberToThread (kernelbase.@)
963  */
965 {
966  struct fiber_data *fiber = NtCurrentTeb()->Tib.u.FiberData;
967 
968  if (fiber)
969  {
970  NtCurrentTeb()->Tib.u.FiberData = NULL;
971  HeapFree( GetProcessHeap(), 0, fiber );
972  }
973  return TRUE;
974 }
975 
976 
977 /***********************************************************************
978  * ConvertThreadToFiber (kernelbase.@)
979  */
981 {
982  return ConvertThreadToFiberEx( param, 0 );
983 }
984 
985 
986 /***********************************************************************
987  * ConvertThreadToFiberEx (kernelbase.@)
988  */
990 {
991  struct fiber_data *fiber;
992 
993  if (!(fiber = HeapAlloc( GetProcessHeap(), 0, sizeof(*fiber) )))
994  {
996  return NULL;
997  }
998  fiber->param = param;
999  fiber->except = NtCurrentTeb()->Tib.ExceptionList;
1000  fiber->stack_base = NtCurrentTeb()->Tib.StackBase;
1001  fiber->stack_limit = NtCurrentTeb()->Tib.StackLimit;
1002  fiber->stack_allocation = NtCurrentTeb()->DeallocationStack;
1003  fiber->start = NULL;
1004  fiber->flags = flags;
1005  fiber->fls_slots = NtCurrentTeb()->FlsSlots;
1006  NtCurrentTeb()->Tib.u.FiberData = fiber;
1007  return fiber;
1008 }
1009 
1010 
1011 /***********************************************************************
1012  * DeleteFiber (kernelbase.@)
1013  */
1015 {
1016  struct fiber_data *fiber = fiber_ptr;
1017 
1018  if (!fiber) return;
1019  if (fiber == NtCurrentTeb()->Tib.u.FiberData)
1020  {
1021  HeapFree( GetProcessHeap(), 0, fiber );
1022  RtlExitUserThread( 1 );
1023  }
1025  RtlProcessFlsData( fiber->fls_slots, 3 );
1026  HeapFree( GetProcessHeap(), 0, fiber );
1027 }
1028 
1029 
1030 /***********************************************************************
1031  * IsThreadAFiber (kernelbase.@)
1032  */
1034 {
1035  return NtCurrentTeb()->Tib.u.FiberData != NULL;
1036 }
1037 
1038 
1039 /***********************************************************************
1040  * SwitchToFiber (kernelbase.@)
1041  */
1043 {
1044  struct fiber_data *new_fiber = fiber;
1045  struct fiber_data *current_fiber = NtCurrentTeb()->Tib.u.FiberData;
1046 
1047  current_fiber->except = NtCurrentTeb()->Tib.ExceptionList;
1048  current_fiber->stack_limit = NtCurrentTeb()->Tib.StackLimit;
1049  current_fiber->fls_slots = NtCurrentTeb()->FlsSlots;
1050  /* stack_allocation and stack_base never change */
1051 
1052  /* FIXME: should save floating point context if requested in fiber->flags */
1053  NtCurrentTeb()->Tib.u.FiberData = new_fiber;
1054  NtCurrentTeb()->Tib.ExceptionList = new_fiber->except;
1055  NtCurrentTeb()->Tib.StackBase = new_fiber->stack_base;
1056  NtCurrentTeb()->Tib.StackLimit = new_fiber->stack_limit;
1057  NtCurrentTeb()->DeallocationStack = new_fiber->stack_allocation;
1058  NtCurrentTeb()->FlsSlots = new_fiber->fls_slots;
1059  switch_fiber( &current_fiber->context, &new_fiber->context );
1060 }
1061 
1062 
1063 /***********************************************************************
1064  * FlsAlloc (kernelbase.@)
1065  */
1067 {
1068  DWORD index;
1069 
1070  if (!set_ntstatus( RtlFlsAlloc( callback, &index ))) return FLS_OUT_OF_INDEXES;
1071  return index;
1072 }
1073 
1074 
1075 /***********************************************************************
1076  * FlsFree (kernelbase.@)
1077  */
1079 {
1080  return set_ntstatus( RtlFlsFree( index ));
1081 }
1082 
1083 
1084 /***********************************************************************
1085  * FlsGetValue (kernelbase.@)
1086  */
1088 {
1089  void *data;
1090 
1091  if (!set_ntstatus( RtlFlsGetValue( index, &data ))) return NULL;
1093  return data;
1094 }
1095 
1096 
1097 /***********************************************************************
1098  * FlsSetValue (kernelbase.@)
1099  */
1101 {
1102  return set_ntstatus( RtlFlsSetValue( index, data ));
1103 }
1104 
1105 
1106 /***********************************************************************
1107  * Thread pool
1108  ***********************************************************************/
1109 
1110 
1111 /***********************************************************************
1112  * CallbackMayRunLong (kernelbase.@)
1113  */
1115 {
1117 }
1118 
1119 
1120 /***********************************************************************
1121  * CreateThreadpool (kernelbase.@)
1122  */
1124 {
1125  TP_POOL *pool;
1126 
1127  if (!set_ntstatus( TpAllocPool( &pool, reserved ))) pool = NULL;
1128  return pool;
1129 }
1130 
1131 
1132 /***********************************************************************
1133  * CreateThreadpoolCleanupGroup (kernelbase.@)
1134  */
1136 {
1138 
1139  if (!set_ntstatus( TpAllocCleanupGroup( &group ))) return NULL;
1140  return group;
1141 }
1142 
1143 
1144 static void WINAPI tp_io_callback( TP_CALLBACK_INSTANCE *instance, void *userdata, void *cvalue, IO_STATUS_BLOCK *iosb, TP_IO *io )
1145 {
1146  PTP_WIN32_IO_CALLBACK callback = *(void **)io;
1147  callback( instance, userdata, cvalue, RtlNtStatusToDosError( iosb->u.Status ), iosb->Information, io );
1148 }
1149 
1150 
1151 /***********************************************************************
1152  * CreateThreadpoolIo (kernelbase.@)
1153  */
1156 {
1157  TP_IO *io;
1158  if (!set_ntstatus( TpAllocIoCompletion( &io, handle, tp_io_callback, userdata, environment ))) return NULL;
1159  *(void **)io = callback; /* ntdll leaves us space to store our callback at the beginning of TP_IO struct */
1160  return io;
1161 }
1162 
1163 
1164 /***********************************************************************
1165  * CreateThreadpoolTimer (kernelbase.@)
1166  */
1169 {
1170  TP_TIMER *timer;
1171 
1172  if (!set_ntstatus( TpAllocTimer( &timer, callback, userdata, environment ))) return NULL;
1173  return timer;
1174 }
1175 
1176 
1177 /***********************************************************************
1178  * CreateThreadpoolWait (kernelbase.@)
1179  */
1182 {
1183  TP_WAIT *wait;
1184 
1185  if (!set_ntstatus( TpAllocWait( &wait, callback, userdata, environment ))) return NULL;
1186  return wait;
1187 }
1188 
1189 
1190 /***********************************************************************
1191  * CreateThreadpoolWork (kernelbase.@)
1192  */
1195 {
1196  TP_WORK *work;
1197 
1198  if (!set_ntstatus( TpAllocWork( &work, callback, userdata, environment ))) return NULL;
1199  return work;
1200 }
1201 
1202 
1203 /***********************************************************************
1204  * TrySubmitThreadpoolCallback (kernelbase.@)
1205  */
1208 {
1209  return set_ntstatus( TpSimpleTryPost( callback, userdata, environment ));
1210 }
1211 
1212 
1213 /***********************************************************************
1214  * QueueUserWorkItem (kernelbase.@)
1215  */
1217 {
1219 }
1220 
1221 /***********************************************************************
1222  * SetThreadpoolStackInformation (kernelbase.@)
1223  */
1225 {
1227 }
1228 
1229 /***********************************************************************
1230  * QueryThreadpoolStackInformation (kernelbase.@)
1231  */
1233 {
1235 }
const UINT description
Definition: action.c:7430
#define __ASM_STDCALL_FUNC(name, args, code)
Definition: asm.h:91
unsigned long long ULONG64
Definition: basetsd.h:99
#define ULongToHandle(ul)
Definition: basetsd.h:243
unsigned long ULONG_PTR
Definition: basetsd.h:130
#define HandleToULong(h)
Definition: basetsd.h:241
ULONG_PTR SIZE_T
Definition: basetsd.h:264
LONG NTSTATUS
Definition: bcrypt.h:40
#define WINAPI
Definition: bcrypt.h:23
void stack_info(int len)
Definition: stack.c:38
static HINSTANCE instance
Definition: main.c:40
void FreeLibraryAndExitThread(HINSTANCE hLibModule, DWORD dwExitCode)
Definition: thread.c:66
LONG UnhandledExceptionFilter(EXCEPTION_POINTERS *epointers)
Definition: debug.c:738
BOOL FreeLibrary(HINSTANCE module)
Definition: loader.c:231
HLOCAL LocalAlloc(UINT flags, SIZE_T size)
Definition: memory.c:602
BOOL SetHandleInformation(HANDLE handle, DWORD mask, DWORD flags)
Definition: process.c:1091
PTP_IO CreateThreadpoolIo(HANDLE handle, PTP_WIN32_IO_CALLBACK callback, PVOID userdata, TP_CALLBACK_ENVIRON *environment)
Definition: thread.c:1154
BOOL SetThreadpoolStackInformation(PTP_POOL pool, PTP_POOL_STACK_INFORMATION stack_info)
Definition: thread.c:1224
DWORD kernelbase_GetLastError(void)
Definition: thread.c:173
PTP_TIMER CreateThreadpoolTimer(PTP_TIMER_CALLBACK callback, PVOID userdata, TP_CALLBACK_ENVIRON *environment)
Definition: thread.c:1167
HANDLE CreateRemoteThreadEx(HANDLE process, SECURITY_ATTRIBUTES *sa, SIZE_T stack, LPTHREAD_START_ROUTINE start, LPVOID param, DWORD flags, LPPROC_THREAD_ATTRIBUTE_LIST attributes, DWORD *id)
Definition: thread.c:72
LANGID GetThreadUILanguage(void)
Definition: thread.c:332
BOOL SetThreadStackGuarantee(ULONG *size)
Definition: thread.c:578
HANDLE kernelbase_GetCurrentThread(void)
Definition: thread.c:142
BOOL FlsFree(DWORD index)
Definition: thread.c:1078
void DeleteFiber(LPVOID fiber_ptr)
Definition: thread.c:1014
HANDLE CreateRemoteThread(HANDLE process, SECURITY_ATTRIBUTES *sa, SIZE_T stack, LPTHREAD_START_ROUTINE start, LPVOID param, DWORD flags, DWORD *id)
Definition: thread.c:61
BOOL SetThreadGroupAffinity(HANDLE thread, const GROUP_AFFINITY *new, GROUP_AFFINITY *old)
Definition: thread.c:502
BOOL GetThreadContext(HANDLE thread, CONTEXT *context)
Definition: thread.c:195
LPVOID CreateFiberEx(SIZE_T stack_commit, SIZE_T stack_reserve, DWORD flags, LPFIBER_START_ROUTINE start, LPVOID param)
Definition: thread.c:931
BOOL SetThreadErrorMode(DWORD mode, DWORD *old)
Definition: thread.c:478
BOOL SwitchToThread(void)
Definition: thread.c:624
BOOL GetThreadTimes(HANDLE thread, LPFILETIME creationtime, LPFILETIME exittime, LPFILETIME kerneltime, LPFILETIME usertime)
Definition: thread.c:297
PTP_WORK CreateThreadpoolWork(PTP_WORK_CALLBACK callback, PVOID userdata, TP_CALLBACK_ENVIRON *environment)
Definition: thread.c:1193
DWORD SuspendThread(HANDLE thread)
Definition: thread.c:612
HANDLE OpenThread(DWORD access, BOOL inherit, DWORD id)
Definition: thread.c:345
BOOL TerminateThread(HANDLE handle, DWORD exit_code)
Definition: thread.c:633
PTP_WAIT CreateThreadpoolWait(PTP_WAIT_CALLBACK callback, PVOID userdata, TP_CALLBACK_ENVIRON *environment)
Definition: thread.c:1180
PTP_CLEANUP_GROUP CreateThreadpoolCleanupGroup(void)
Definition: thread.c:1135
BOOL GetThreadPriorityBoost(HANDLE thread, BOOL *state)
Definition: thread.c:287
HRESULT SetThreadDescription(HANDLE thread, PCWSTR description)
Definition: thread.c:418
static void init_fiber_context(struct fiber_data *fiber)
Definition: thread.c:901
BOOL SetThreadPriorityBoost(HANDLE thread, BOOL disable)
Definition: thread.c:569
LPVOID ConvertThreadToFiber(LPVOID param)
Definition: thread.c:980
void SwitchToFiber(LPVOID fiber)
Definition: thread.c:1042
BOOL QueryThreadpoolStackInformation(PTP_POOL pool, PTP_POOL_STACK_INFORMATION stack_info)
Definition: thread.c:1232
static DWORD rtlmode_to_win32mode(DWORD rtlmode)
Definition: thread.c:47
BOOL FlsSetValue(DWORD index, PVOID data)
Definition: thread.c:1100
DWORD SetThreadIdealProcessor(HANDLE thread, DWORD proc)
Definition: thread.c:513
LPVOID ConvertThreadToFiberEx(LPVOID param, DWORD flags)
Definition: thread.c:989
INT GetThreadPriority(HANDLE thread)
Definition: thread.c:273
HRESULT GetThreadDescription(HANDLE thread, WCHAR **description)
Definition: thread.c:439
LCID GetThreadLocale(void)
Definition: thread.c:262
BOOL GetThreadGroupAffinity(HANDLE thread, GROUP_AFFINITY *affinity)
Definition: thread.c:213
BOOL SetThreadIdealProcessorEx(HANDLE thread, PROCESSOR_NUMBER *ideal, PROCESSOR_NUMBER *previous)
Definition: thread.c:528
BOOL SetThreadContext(HANDLE thread, const CONTEXT *context)
Definition: thread.c:409
DWORD GetThreadErrorMode(void)
Definition: thread.c:204
BOOL SetThreadLocale(LCID lcid)
Definition: thread.c:540
BOOL TrySubmitThreadpoolCallback(PTP_SIMPLE_CALLBACK callback, PVOID userdata, TP_CALLBACK_ENVIRON *environment)
Definition: thread.c:1206
BOOL QueryThreadCycleTime(HANDLE thread, ULONG64 *cycle)
Definition: thread.c:385
BOOL GetExitCodeThread(HANDLE thread, LPDWORD exit_code)
Definition: thread.c:160
BOOL ConvertFiberToThread(void)
Definition: thread.c:964
BOOL TlsSetValue(DWORD index, LPVOID value)
Definition: thread.c:723
BOOL SetThreadPriority(HANDLE thread, INT priority)
Definition: thread.c:559
HANDLE CreateThread(SECURITY_ATTRIBUTES *sa, SIZE_T stack, LPTHREAD_START_ROUTINE start, LPVOID param, DWORD flags, LPDWORD id)
Definition: thread.c:111
DWORD ResumeThread(HANDLE thread)
Definition: thread.c:397
PVOID FlsGetValue(DWORD index)
Definition: thread.c:1087
static void start_fiber(void)
Definition: thread.c:884
void GetCurrentThreadStackLimits(ULONG_PTR *low, ULONG_PTR *high)
Definition: thread.c:132
DWORD kernelbase_GetCurrentThreadId(void)
Definition: thread.c:151
BOOL IsThreadAFiber(void)
Definition: thread.c:1033
DWORD FlsAlloc(PFLS_CALLBACK_FUNCTION callback)
Definition: thread.c:1066
void switch_fiber(CONTEXT *old, CONTEXT *new)
Definition: thread.c:876
static void call_user_apc(ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3)
Definition: thread.c:367
DWORD QueueUserAPC(PAPCFUNC func, HANDLE thread, ULONG_PTR data)
Definition: thread.c:376
DWORD TlsAlloc(void)
Definition: thread.c:642
LPVOID CreateFiber(SIZE_T stack, LPFIBER_START_ROUTINE start, LPVOID param)
Definition: thread.c:922
PTP_POOL CreateThreadpool(void *reserved)
Definition: thread.c:1123
LPVOID TlsGetValue(DWORD index)
Definition: thread.c:704
BOOL GetThreadIdealProcessorEx(HANDLE thread, PROCESSOR_NUMBER *ideal)
Definition: thread.c:251
LANGID SetThreadUILanguage(LANGID langid)
Definition: thread.c:600
static void tp_io_callback(TP_CALLBACK_INSTANCE *instance, void *userdata, void *cvalue, IO_STATUS_BLOCK *iosb, TP_IO *io)
Definition: thread.c:1144
BOOL GetThreadIOPendingFlag(HANDLE thread, PBOOL pending)
Definition: thread.c:228
BOOL QueueUserWorkItem(LPTHREAD_START_ROUTINE func, PVOID context, ULONG flags)
Definition: thread.c:1216
BOOL CallbackMayRunLong(TP_CALLBACK_INSTANCE *instance)
Definition: thread.c:1114
BOOL TlsFree(DWORD index)
Definition: thread.c:679
DWORD GetProcessIdOfThread(HANDLE thread)
Definition: thread.c:182
DWORD GetThreadId(HANDLE thread)
Definition: thread.c:238
void * memcpy(void *dst, const void *src, size_t n)
Definition: string.c:2580
void RtlExitUserThread(ULONG status)
Definition: thread.c:81
NTSTATUS RtlFlsAlloc(PFLS_CALLBACK_FUNCTION callback, ULONG *ret_index)
Definition: thread.c:313
void RtlProcessFlsData(void *teb_fls_data, ULONG flags)
Definition: thread.c:477
NTSTATUS RtlCreateUserThread(HANDLE process, SECURITY_DESCRIPTOR *descr, BOOLEAN suspended, PVOID stack_addr, SIZE_T stack_reserve, SIZE_T stack_commit, PRTL_THREAD_START_ROUTINE start, void *param, HANDLE *handle_ptr, CLIENT_ID *id)
Definition: thread.c:154
NTSTATUS RtlFlsGetValue(ULONG index, void **data)
Definition: thread.c:459
NTSTATUS RtlFlsFree(ULONG index)
Definition: thread.c:380
NTSTATUS RtlFlsSetValue(ULONG index, void *data)
Definition: thread.c:431
NTSTATUS NtClose(HANDLE handle)
Definition: server.c:1666
NTSTATUS NtResumeThread(HANDLE handle, ULONG *count)
Definition: thread.c:492
NTSTATUS NtOpenThread(HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr, const CLIENT_ID *id)
Definition: thread.c:451
NTSTATUS NtSetInformationThread(HANDLE handle, THREADINFOCLASS class, const void *data, ULONG length)
Definition: thread.c:1162
NTSTATUS NtQueueApcThread(HANDLE handle, PNTAPCFUNC func, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3)
Definition: thread.c:556
NTSTATUS NtQueryInformationThread(HANDLE handle, THREADINFOCLASS class, void *data, ULONG length, ULONG *ret_len)
Definition: thread.c:897
NTSTATUS NtSuspendThread(HANDLE handle, ULONG *count)
Definition: thread.c:472
NTSTATUS NtTerminateThread(HANDLE handle, LONG exit_code)
Definition: thread.c:532
long BOOL
Definition: dxgitype.idl:24
NTSTATUS status
Definition: except.c:81
#define __TRY
Definition: exception.h:136
#define __ENDTRY
Definition: exception.h:179
#define __EXCEPT(func)
Definition: exception.h:143
#define GetExceptionCode()
Definition: exception.h:222
static void heap_free(void *mem)
Definition: heap.h:44
#define WINE_DEFAULT_DEBUG_CHANNEL(ch)
Definition: debug.h:499
static UINT_PTR timer
Definition: input.c:1033
static int access(const char *path, int mode)
Definition: io.h:110
BYTE flags
Definition: ioports.c:48
static BOOL set_ntstatus(NTSTATUS status)
BOOL IsValidLocale(LCID lcid, DWORD flags)
Definition: locale.c:5138
LCID lcid
Definition: locale.c:4137
LCID GetUserDefaultLCID(void)
Definition: locale.c:4807
LCID ConvertDefaultLocale(LCID lcid)
Definition: locale.c:3177
struct version_info info
Definition: version.c:140
#define USHRT_MAX
Definition: limits.h:23
#define max(a, b)
Definition: minmax.h:25
void * PAPCFUNC
Definition: mmstream.idl:42
int(CDECL *mono_jit_exec)(MonoDomain *domain
LANGID langid
Definition: msctf.idl:605
ULONG RtlNtStatusToDosError(NTSTATUS status)
Definition: error.c:79
ULONG start
Definition: error.c:1729
NTSTATUS RtlQueueWorkItem(PRTL_WORK_ITEM_ROUTINE function, PVOID context, ULONG flags)
Definition: threadpool.c:438
NTSTATUS TpCallbackMayRunLong(TP_CALLBACK_INSTANCE *instance)
Definition: threadpool.c:2727
NTSTATUS TpSimpleTryPost(PTP_SIMPLE_CALLBACK callback, PVOID userdata, TP_CALLBACK_ENVIRON *environment)
Definition: threadpool.c:3217
NTSTATUS TpQueryPoolStackInformation(TP_POOL *pool, TP_POOL_STACK_INFORMATION *stack_info)
Definition: threadpool.c:3338
NTSTATUS TpAllocCleanupGroup(TP_CLEANUP_GROUP **out)
Definition: threadpool.c:2516
NTSTATUS TpAllocIoCompletion(TP_IO **out, HANDLE file, PTP_IO_CALLBACK callback, void *userdata, TP_CALLBACK_ENVIRON *environment)
Definition: threadpool.c:2526
NTSTATUS TpAllocWork(TP_WORK **out, PTP_WORK_CALLBACK callback, PVOID userdata, TP_CALLBACK_ENVIRON *environment)
Definition: threadpool.c:2663
NTSTATUS TpAllocTimer(TP_TIMER **out, PTP_TIMER_CALLBACK callback, PVOID userdata, TP_CALLBACK_ENVIRON *environment)
Definition: threadpool.c:2583
NTSTATUS TpSetPoolStackInformation(TP_POOL *pool, TP_POOL_STACK_INFORMATION *stack_info)
Definition: threadpool.c:3319
NTSTATUS TpAllocPool(TP_POOL **out, PVOID reserved)
Definition: threadpool.c:2570
NTSTATUS TpAllocWait(TP_WAIT **out, PTP_WAIT_CALLBACK callback, PVOID userdata, TP_CALLBACK_ENVIRON *environment)
Definition: threadpool.c:2623
USHORT * data
Definition: env.c:81
NTSTATUS NtQueryDefaultUILanguage(LANGID *lang)
Definition: env.c:1442
NTSTATUS NtYieldExecution(void)
Definition: sync.c:1307
void RtlFreeUserStack(void *stack)
Definition: virtual.c:100
NTSTATUS RtlCreateUserStack(SIZE_T commit, SIZE_T reserve, ULONG zero_bits, SIZE_T commit_align, SIZE_T reserve_align, INITIAL_TEB *stack)
Definition: virtual.c:44
PSecurityUserData *typedef PSECPKG_EXTENDED_INFORMATION *typedef PVOID
Definition: ntsecpkg.h:378
PSecurityUserData *typedef PSECPKG_EXTENDED_INFORMATION *typedef ULONG
Definition: ntsecpkg.h:377
#define STATUS_INVALID_PARAMETER
Definition: ntstatus.h:223
#define STATUS_NO_MEMORY
Definition: ntstatus.h:233
#define STATUS_NO_YIELD_PERFORMED
Definition: ntstatus.h:123
#define STATUS_BUFFER_TOO_SMALL
Definition: ntstatus.h:245
HRESULT(* func)(HTMLDocumentNode *, DWORD, VARIANT *, VARIANT *)
Definition: olecmd.c:734
static ALenum ALfloat value
Definition: openal.c:51
static ALenum param
Definition: openal.c:51
#define U(x)
Definition: main.h:32
static void * environment
Definition: services.c:48
void * heap_alloc(size_t len)
Definition: util.c:30
LPVOID proc
DWORD RtlGetThreadErrorMode(void)
Definition: rtl.c:2108
void RtlAcquirePebLock(void)
Definition: rtl.c:385
void RtlReleasePebLock(void)
Definition: rtl.c:393
NTSTATUS RtlSetThreadErrorMode(DWORD mode, LPDWORD oldmode)
Definition: rtl.c:2085
BOOLEAN RtlAreBitsSet(PCRTL_BITMAP lpBits, ULONG ulStart, ULONG ulCount)
Definition: rtlbitmap.c:252
ULONG RtlFindClearBitsAndSet(PRTL_BITMAP lpBits, ULONG ulCount, ULONG ulHint)
Definition: rtlbitmap.c:513
void RtlClearBits(PRTL_BITMAP lpBits, ULONG ulStart, ULONG ulCount)
Definition: rtlbitmap.c:190
HANDLE UniqueThread
Definition: winternl.h:134
HANDLE UniqueProcess
Definition: winternl.h:133
DWORD dwHighDateTime
Definition: winbase.h:253
DWORD dwLowDateTime
Definition: winbase.h:252
void * DeallocationStack
Definition: winternl.h:2567
void * StackBase
Definition: winternl.h:2565
void * StackLimit
Definition: winternl.h:2566
LARGE_INTEGER UserTime
Definition: winternl.h:1372
LARGE_INTEGER CreateTime
Definition: winternl.h:1369
LARGE_INTEGER KernelTime
Definition: winternl.h:1371
LARGE_INTEGER ExitTime
Definition: winternl.h:1370
Definition: winternl.h:301
PRTL_BITMAP TlsBitmap
Definition: winternl.h:321
ULONG TlsExpansionBitmapBits[32]
Definition: winternl.h:355
PRTL_BITMAP TlsExpansionBitmap
Definition: winternl.h:354
LPVOID lpSecurityDescriptor
Definition: winbase.h:239
Definition: cookie.c:202
LPVOID param
Definition: thread.c:757
void * stack_limit
Definition: thread.c:760
DWORD flags
Definition: thread.c:763
void * except
Definition: thread.c:758
LPFIBER_START_ROUTINE start
Definition: thread.c:764
CONTEXT context
Definition: thread.c:762
void * fls_slots
Definition: thread.c:765
void * stack_allocation
Definition: thread.c:761
void * stack_base
Definition: thread.c:759
Definition: token.c:125
Definition: file.h:35
Definition: ticket.c:41
Definition: thread.h:50
Definition: main.c:768
void(CALLBACK * PTP_WIN32_IO_CALLBACK)(PTP_CALLBACK_INSTANCE, PVOID, PVOID, ULONG, ULONG_PTR, PTP_IO)
#define NULL
Definition: ungif.h:66
#define TRUE
Definition: ungif.h:59
#define FALSE
Definition: ungif.h:62
struct _LARGE_INTEGER::@1824 u
Definition: pdh_main.c:90
YY_BUFFER_STATE state
Definition: parser.l:85
DWORD(CALLBACK * LPTHREAD_START_ROUTINE)(LPVOID)
Definition: winbase.h:50
#define FLS_OUT_OF_INDEXES
Definition: winbase.h:344
DECLSPEC_IMPORT HANDLE WINAPI GetCurrentProcess(void)
#define SEM_FAILCRITICALERRORS
Definition: winbase.h:198
#define HANDLE_FLAG_INHERIT
Definition: winbase.h:1234
DECLSPEC_IMPORT BOOL WINAPI HeapFree(HANDLE, DWORD, LPVOID)
DECLSPEC_IMPORT VOID WINAPI SetLastError(DWORD)
#define SEM_NOGPFAULTERRORBOX
Definition: winbase.h:199
#define STACK_SIZE_PARAM_IS_A_RESERVATION
Definition: winbase.h:683
DECLSPEC_IMPORT HANDLE WINAPI GetCurrentThread(void)
#define CREATE_SUSPENDED
Definition: winbase.h:654
DECLSPEC_IMPORT HANDLE WINAPI GetProcessHeap(void)
DECLSPEC_IMPORT INT WINAPI lstrlenW(LPCWSTR)
#define SEM_NOOPENFILEERRORBOX
Definition: winbase.h:201
#define THREAD_PRIORITY_ERROR_RETURN
Definition: winbase.h:1244
DECLSPEC_IMPORT LPVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T) __WINE_ALLOC_SIZE(3)
PFIBER_START_ROUTINE LPFIBER_START_ROUTINE
Definition: winbase.h:53
#define CDECL
Definition: windef.h:198
int * PBOOL
Definition: windef.h:249
int INT
Definition: windef.h:252
unsigned int * LPDWORD
Definition: windef.h:261
unsigned int DWORD
Definition: windef.h:261
#define CALLBACK
Definition: windef.h:194
#define disable(id)
Definition: winecfg.h:124
GLint mode
Definition: opengl.c:195
#define HRESULT_FROM_NT(x)
Definition: winerror.h:101
#define ERROR_NOT_ENOUGH_MEMORY
Definition: winerror.h:118
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: winerror.h:199
#define ERROR_INVALID_PARAMETER
Definition: winerror.h:178
#define ERROR_NO_MORE_ITEMS
Definition: winerror.h:299
#define ERROR_SUCCESS
Definition: winerror.h:110
#define LCID_SUPPORTED
Definition: winnls.h:158
struct _TP_WAIT * PTP_WAIT
Definition: winnt.h:6789
WORD LANGID
Definition: winnt.h:569
struct _TP_CLEANUP_GROUP TP_CLEANUP_GROUP
Definition: winnt.h:6737
#define TLS_MINIMUM_AVAILABLE
Definition: winnt.h:2822
struct _TP_TIMER * PTP_TIMER
Definition: winnt.h:6786
struct _TP_WORK * PTP_WORK
Definition: winnt.h:6785
struct _TP_POOL TP_POOL
Definition: winnt.h:6720
unsigned short WCHAR
Definition: winnt.h:468
void(* PTP_TIMER_CALLBACK)(PTP_CALLBACK_INSTANCE, PVOID, PTP_TIMER)
Definition: winnt.h:6796
void(* PFLS_CALLBACK_FUNCTION)(PVOID)
Definition: winnt.h:6236
#define DECLSPEC_HOTPATCH
Definition: winnt.h:184
struct _TP_WAIT TP_WAIT
Definition: winnt.h:6789
struct _TP_IO * PTP_IO
Definition: winnt.h:6791
DWORD LCID
Definition: winnt.h:568
struct _TP_WORK TP_WORK
Definition: winnt.h:6785
struct _TP_IO TP_IO
Definition: winnt.h:6791
#define MAXIMUM_PROCESSORS
Definition: winnt.h:725
struct _TP_TIMER TP_TIMER
Definition: winnt.h:6786
struct _TEB * NtCurrentTeb(void)
struct _TP_POOL * PTP_POOL
Definition: winnt.h:6720
struct _TP_CLEANUP_GROUP * PTP_CLEANUP_GROUP
Definition: winnt.h:6737
const WCHAR * PCWSTR
Definition: winnt.h:513
void(* PTP_SIMPLE_CALLBACK)(PTP_CALLBACK_INSTANCE, PVOID)
Definition: winnt.h:6718
void(* PTP_WAIT_CALLBACK)(PTP_CALLBACK_INSTANCE, PVOID, PTP_WAIT, TP_WAIT_RESULT)
Definition: winnt.h:6797
struct _TP_CALLBACK_INSTANCE TP_CALLBACK_INSTANCE
Definition: winnt.h:6716
#define HEAP_ZERO_MEMORY
Definition: winnt.h:906
void(* PTP_WORK_CALLBACK)(PTP_CALLBACK_INSTANCE, PVOID, PTP_WORK)
Definition: winnt.h:6795
NTSTATUS NtSetContextThread(HANDLE, const CONTEXT *)
void(* PRTL_THREAD_START_ROUTINE)(LPVOID)
Definition: winternl.h:2279
@ ThreadTimes
Definition: winternl.h:1309
@ ThreadGroupInformation
Definition: winternl.h:1338
@ ThreadDescription
Definition: winternl.h:1343
@ ThreadBasePriority
Definition: winternl.h:1311
@ ThreadBasicInformation
Definition: winternl.h:1308
@ ThreadIsIoPending
Definition: winternl.h:1324
@ ThreadZeroTlsCell
Definition: winternl.h:1318
void DbgBreakPoint(void)
#define OBJ_INHERIT
Definition: winternl.h:2267
NTSTATUS NtGetContextThread(HANDLE, CONTEXT *)