Jump to content
Sign in to follow this  

[..] Multithreading with GLFW

Recommended Posts

Hi every body!

I have a small questions to the C pros befor I go making something long and boring:

I am creating a wrapper to GLFW, all OpenGL related stuff works well (creating a window, loading textures...), so it's good for this (PS: i'm gonna post it when i'm done)

But, GLFW has some multithreading functions (see the doc) and i just wanna know il AutoIt will be capable of getting these functions to work? I mean, introducing Multithreading to AutoIt!!! :oops:

I wanna know this befor making the wrappers, and find my self lost precious time!

Thanks for answering!

Share this post

Link to post
Share on other sites

You can get the functions to work but if you use them with a DLLCallback, AutoIt will crash since the interpreter is not threadsafe. The limitations are the same when using the Windows Thread API directly. GLFW only introduces another level of abstraction for OS independence (same function for Win, Linux, ...)

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By paradox109
      I have A simple question about http request. What would be the fastest way to send mupltiple http request at the same time with autoit? The only way i figured  out was to to start multiple processes. This way works fine but its not really a good way. What user would like to see 15 processes running in the background at the same time. I know multithread is also not available in autoit.
    • By Beege
      Here is an old goodie from ms demonstrating concepts behind multithreading and using mutexes to control sharing the screen. Its unfortunately just a console application so you have to press compile (f7) to run (can get annoying if you want to play with the code) but still pretty cool :). Each little question mark box (could be any character (used to be a smiley face in win 7)) is its own thread keeping track of its own coordinates. Each thread shares the screenmutex by kinda waiting in line for ownership of it. When the thread gains control it updates the screen, then releases the mutex for the next thread. 

      First I wrote it in pure autoit to confirm all working as expected. The Console functions actually threw me for a loop. They actual want the whole value of the coord structs and not a ptr to it so that "struct" without a * was a little uncommon. Below au3 code is just the lonely cell bouncing around.
      Func _BounceAU3() ;set a random starting id. we use this to rotate the colors Local $iMyID = Random(1, 15, 1) Local $tMyCell = DllStructCreate('char mc'), $tOldCell = DllStructCreate('char oc') Local $tMyAttrib = DllStructCreate('word ma'), $tOldAttrib = DllStructCreate('word oa') Local $tCoords = DllStructCreate($tagCOORD), $tOld = DllStructCreate($tagCOORD) Local $tDelta = DllStructCreate($tagCOORD) ;Random start and delta values $tCoords.X = Random(0, 119, 1) $tCoords.Y = Random(0, 29, 1) $tDelta.X = Random(-3, 3, 1) $tDelta.Y = Random(-3, 3, 1) ;set character/cell attributes $tMyCell.mc = $iMyID > 16 ? 0x01 : 0x02 ; doesnt seem to make a differnce in windows 10 $tMyAttrib.ma = BitAND($iMyID, 0x0F) ; Set the character color Do ;check the last position values DllCall('kernel32.dll', "bool", "ReadConsoleOutputCharacter", "handle", $g_hStdHandle, "struct*", $tOldCell, "dword", 1, "struct", $tOld, "dword*", 0) DllCall('kernel32.dll', "bool", "ReadConsoleOutputAttribute", "handle", $g_hStdHandle, "struct*", $tOldAttrib, "dword", 1, "struct", $tOld, "dword*", 0) ;if the last postion was this cell, blank/empty the cell. (Otherwise its been taken over by another thread) If ($tOldCell.oc = $tMyCell.mc) And ($tOldAttrib.oa = $tMyAttrib.ma) Then DllCall('kernel32.dll', "bool", "WriteConsoleOutputCharacter", "handle", $g_hStdHandle, "byte*", 0x20, "dword", 1, "struct", $tOld, "dword*", 0) EndIf ;write the current cell DllCall('kernel32.dll', "bool", "WriteConsoleOutputCharacter", "handle", $g_hStdHandle, "struct*", $tMyCell, "dword", 1, "struct", $tCoords, "dword*", 0) DllCall('kernel32.dll', "bool", "WriteConsoleOutputAttribute", "handle", $g_hStdHandle, "struct*", $tMyAttrib, "dword", 1, "struct", $tCoords, "dword*", 0) ;update coords $tOld.X = $tCoords.X $tOld.Y = $tCoords.Y $tCoords.X += $tDelta.X $tCoords.Y += $tDelta.Y ;change directions if we are out of bounds If $tCoords.X < 0 Or $tCoords.X >= 120 Then $tDelta.X *= -1 If $tCoords.Y < 0 Or $tCoords.Y >= 30 Then $tDelta.Y *= -1 Sleep(75) Until GUIGetMsg() = -3 EndFunc ;==>_BounceAU3  
      From there the that function converted into assembly so we can call as a thread. The only real differences are the extra parameters we passing as a structure and I also generate the random starting values in autoit instead, then pass them to the function. Here is what the main assembly function looks like. I added comments for each peice of code from au3 that we are translating:
      _('procf _Bounce uses ebx, pParms') ; ; create the local variables _(' locals') _(' BlankCell db 32') ; this first group covers the variables from the original script _(' MyCell db ?') _(' OldCell db ?') _(' MyAtt dw ?') _(' OldAtt dw ?') _(' tCoords COORD') _(' tDelta COORD') _(' tOld COORD') _(' bytesread dw ?') ; _(' iMyID dw ?') ; this group of local vars cover holding all the other paramerters we are passing in tParms _(' g_hScreenMutex dd ?') _(' g_hRunMutex dd ?') _(' g_hStdHandle dd ?') _(' pfWaitForSingleObject dd ?') _(' pfReleaseMutex dd ?') _(' pfReadChar dd ?') _(' pfReadAttr dd ?') _(' pfWriteChar dd ?') _(' pfWriteAttr dd ?') _(' endl') ; ;all of these push/pops are to transfer the rest of variables from tParms structure to the local variables we created ;first mov the structure address into ebx _(' mov ebx, [pParms]') ; ; now push and pop the values into the variables ; use _winapi_displaystruct() to view all the offsets being used in the [ebx+offset] lines _(' pushw [ebx]') ; _(' popw word[tCoords+COORD.X]') _(' pushw word[ebx+2]') ; _(' popw word[tCoords+COORD.Y]') _(' pushw word[ebx+4]') ; _(' popw word[tDelta+COORD.X]') _(' pushw word[ebx+6]') ; _(' popw word[tDelta+COORD.Y]') _(' pushw word[ebx+8]') ; _(' popw word[iMyID]') _(' push dword[ebx+12]') ; _(' pop dword[g_hScreenMutex]') _(' push dword[ebx+16]') ; _(' pop dword[g_hRunMutex]') _(' push dword[ebx+20]') ; _(' pop dword[g_hStdHandle]') _(' push dword[ebx+24]') ; _(' pop dword[pfWaitForSingleObject]') _(' push dword[ebx+28]') ; _(' pop dword[pfReleaseMutex]') _(' push dword[ebx+32]') ; _(' pop dword[pfReadChar]') _(' push dword[ebx+36]') ; _(' pop dword[pfReadAttr]') _(' push dword[ebx+40]') ; _(' pop dword[pfWriteChar]') _(' push dword[ebx+44]') ; _(' pop dword[pfWriteAttr]') _('.if word[iMyID] > 16') ; $tMyCell.mc = $iMyID > 16 ? 0x01 : 0x02 (no difference in windows 10) _(' mov word[MyCell], 1') _('.else') _(' mov word[MyCell], 2') _('.endif') ; _('pushw word[iMyID]') ; $tMyAttrib.ma = BitAND($iMyID, 0x0F) _('popw word[MyAtt]') _('and word[MyAtt], 15') ; _('.repeat') ; do ; ; Wait infinetly for the screen mutex to be available, then take ownership _(' invoke pfWaitForSingleObject, [g_hScreenMutex], -1') ; ; DllCall('kernel32.dll', "bool", "WriteConsoleOutputCharacter", "handle", $hStdHandle, "byte*", 0x20, "dword", 1, "struct", $tOld, "dword*", 0) _(' invoke pfReadChar, [g_hStdHandle], addr OldCell, 1, dword[tOld], addr bytesread') ; _(' invoke pfReadAttr, [g_hStdHandle], addr OldAtt, 1, dword[tOld], addr bytesread') ; ; _(' mov al, byte[MyCell]') ;If ($tOldCell.oc = $tMyCell.mc) And ($tOldAttrib.oa = $tMyAttrib.ma) Then _(' mov cl, byte[MyAtt]') _(' .if (byte[OldCell] = al) & (byte[OldAtt] = cl)') _(' invoke pfWriteChar, [g_hStdHandle], addr BlankCell, 1, dword[tOld], addr bytesread') _(' .endif') ; ; DllCall('kernel32.dll', "bool", "WriteConsoleOutputCharacter", "handle", $hStdHandle, "struct*", $tMyCell, "dword", 1, "struct", $tCoords, "dword*", 0) _(' invoke pfWriteChar, [g_hStdHandle], addr MyCell, 1, dword[tCoords], addr bytesread') _(' invoke pfWriteAttr, [g_hStdHandle], addr MyAtt, 1, dword[tCoords], addr bytesread') ; _(' pushw word[tCoords+COORD.X]') ;$tOld.X = $tCoords.X _(' popw word[tOld+COORD.X]') ; _(' pushw word[tCoords+COORD.Y]') ;$tOld.Y = $tCoords.Y _(' popw word[tOld+COORD.Y]') _(' mov ax, word[tDelta+COORD.X]') ; $tCoords.X += $tDelta.X _(' add word[tCoords+COORD.X], ax') ; _(' mov ax, word[tDelta+COORD.Y]') ; $tCoords.Y += $tDelta.Y _(' add word[tCoords+COORD.Y], ax') ; ; If $tCoords.X < 0 Or $tCoords.X >= 120 Then $tDelta.X *= -1 _(' .if (word[tCoords+COORD.X] < 0 | word[tCoords+COORD.X] >= 120)') _(' neg word[tDelta+COORD.X]') _(' .endif') _(' .if (word[tCoords+COORD.Y] < 0 | word[tCoords+COORD.Y] >= 30)') _(' neg word[tDelta+COORD.Y]') _(' .endif') ; ; release the screen mutex _(' invoke pfReleaseMutex, [g_hScreenMutex]') ; ; wait 100 ms for the Runmutex to be available. _(' invoke pfWaitForSingleObject, [g_hRunMutex], 100') ; ; a return of 258 means it timed out waiting and that the run mutex (owned by the main autoit thread) is still alive. ; when the run mutex handle gets closed this will return a fail or abandonded. _('.until eax <> 258') ; ;exit thread _(' ret') _('endp')  
      And finally how we call that assembled function from autoit to create the theads:
      ;create mutex for sharing the screen thats not owned by main thread Global $g_hScreenMutex = _WinAPI_CreateMutex('', False) ; ;create mutex that tells the threads to exit that is owned by main thread Global $g_hRunMutex = _WinAPI_CreateMutex('', True) ... ... ;assemble function Local $tBinExec = _fasmg_Assemble($g_sFasm, False) ;Local $tBinExec = _fasmg_CompileAu3($g_sFasm) If @error Then Exit (ConsoleWrite($tBinExec & @CRLF)) ;this is struct is for all the values Im passing to the thread. ;this will hold are random start x,y,delta values, handles, and pointers to functions called within the thread $tParms = DllStructCreate('short start[4];word myid;dword hands[3];ptr funcs[6]') $tParms.start(1) = Random(0, 119, 1) $tParms.start(2) = Random(0, 29, 1) $tParms.start(3) = Random(-3, 3, 1) $tParms.start(4) = Random(-3, 3, 1) $tParms.myid = 1 $tParms.hands(1) = $g_hScreenMutex $tParms.hands(2) = $g_hRunMutex $tParms.hands(3) = $g_hStdHandle $tParms.funcs(1) = _GPA('kernel32.dll', 'WaitForSingleObject') $tParms.funcs(2) = _GPA('kernel32.dll', 'ReleaseMutex') $tParms.funcs(3) = _GPA('kernel32.dll', 'ReadConsoleOutputCharacterA') $tParms.funcs(4) = _GPA('kernel32.dll', 'ReadConsoleOutputAttribute') $tParms.funcs(5) = _GPA('kernel32.dll', 'WriteConsoleOutputCharacterA') $tParms.funcs(6) = _GPA('kernel32.dll', 'WriteConsoleOutputAttribute') ;create 128 threads with different start values and colors for each one For $i = 1 To 128 $tParms.myid = $i $tParms.start(1) = Random(0, 119, 1) $tParms.start(2) = Random(0, 29, 1) $tParms.start(3) = Random(-3, 3, 1) $tParms.start(4) = Random(-3, 3, 1) If $tParms.start(3) + $tParms.start(4) = 0 Then $tParms.start(3) = (Mod(@MSEC, 2) ? 1 : -1) ; adjusting non-moving (0,0) delta values.. DllCall("kernel32.dll", "hwnd", "CreateThread", "ptr", 0, "dword", 0, "struct*", $tBinExec, "struct*", $tParms, "dword", 0, "dword*", 0) Sleep(50) Next MsgBox(262144, '', '128 Threads Created') ;Close the run mutex handle. This will cause all the threads to exit _WinAPI_CloseHandle($g_hRunMutex) _WinAPI_CloseHandle($g_hScreenMutex) MsgBox(262144, '', 'Mutex handles closed. All Threads should have exited') Exit The attachment below contains both the compiled and source assembly. To play with the assembly source you need to add the fasmg udf in my sig. The compiled version should not need anything. Let me know if you have any issues.
      Special thanks to @trancexx for teaching me this with her clock example
    • By UEZ
      Here some graphical examples written completely in FreeBasic just for fun.  
      _WinAPI_SetWindowTitleIcon Check for Numeric Entry in an EditBox using RegEx CreateWindowEx (hGUI) Example FB 3D Starfield Rotating Flight FB File2Bas Code Generator FB Fire Particles FB Fireworks FB GFX Examples FB Image to Trapezoid Transformation FB Layered Parallax Effect FB Plasma FB Puristic Clock FB Rotating Cube FB Rotating Earth FB Rutt Etra Izer Effect FB Simple Recursive Tree Generator FB Snowfall FB Tunnel Flight FB Water Effect FMOD Examples GDI - GDI+ 3D Sinus Wave GDI - GDI+ Animated Pythagoras Tree GDI - GDI+ Bezier Lines GDI - GDI+ Particles - Repulsive Force Sim v2.0 GDI - GDI+ Plasma v5 Booster GDI - GDI+ Random Pattern GDI - GDI+ Space Flight GDI - GDI+ Tunnel Flight - WipeOut Style GDI Classic Raytraced Tunnel GDI Elastic Twister Effect GDI Exploding Pixels GDI Infinite Image Zoom Flight GDI Liquid Pixels GDI Mandelbrot GDI Particle Repulsion Grid GDI Particles Mouse Attraction GDI Starfield GDI The Nautilus Raymarcher GDI Worm Tunnel Flight GDI+ 3D Starfield Scrolling v1 Booster GDI+ 3D Starfield Scrolling v3 Booster GDI+ Convert Bitmap to ASCII GDI+ GIF Anim to ASCII Player GDI+ Image Painting GDI+ Impossible Possible GDI+ Kaleidoscope GDI+ Performance Test - Au3 vs FB GDI+ Polar Clock GDI+ Rotating Earth GDI+ Spiral Text GDI+ Star Wars Scroller GDI+ Streamer GDI+ Swiss Railway Clock GDI+ The MATRIX Ini Read - Write Rutt_Etra_Izer_Booster Stack TitchySID uFMOD  
      Download: FreeBasic Examples build 2019-05-08.rar
      I will add new examples from time to time.
      FreeBasic source codes are also included.
    • By Miliardsto
      I want to detect if exact process or window uses directx or opengl or maybe something else library used in applications.
      Thats becouse there could be many windows with same names and different names and the same with process. I got so much process names I want to my script works with all, so i want standardize.
      All of this processes uses DirectX or OpenGL so then If I check this window/process uses these libraries I will be sure thats the right process
  • Create New...