1. windows threads work!!
- Posted by jacques deschênes <desja at globetrotter.net> Jul 10, 2006
- 663 views
In the past I tested threads in euphoria without any success. At my first try and didn't insist because At that time i thought it was a limitation of euphoria interpreter. But this morning reading "windows internals" I learned that windows create a new stack for each thread a process create. if so multithread should in euphoria! I decided to revisit it and IT WORKED!!
-- testing windows system threads in euphoria without warning include misc.e include machine.e include dll.e constant kernel32=open_dll("kernel32.dll") if kernel32 = -1 then puts(1,"failed to open kernel32.dll\n") abort(1) end if constant iCreateThread=define_c_func(kernel32,"CreateThread",{C_POINTER,C_UINT,C_POINTER,C_POINTER,C_UINT,C_POINTER},C_UINT), iSleep=define_c_proc(kernel32,"Sleep",{C_UINT}), iCloseHandle = define_c_func(kernel32,"CloseHandle",{C_UINT},C_UINT) global function CreateThread(atom lpThreadAttributes, atom dwStackSize, -- initial thread stack size, in bytes atom lpStartAddress, -- pointer to thread function atom lpParameter, -- argument for new thread atom dwCreationFlags, -- creation flags atom lpThreadId -- pointer to returned thread identifier ) return c_func(iCreateThread,{lpThreadAttributes,dwStackSize,lpStartAddress,lpParameter,dwCreationFlags,lpThreadId}) end function --CreateThread() global function CloseHandle(atom handle) return c_func(iCloseHandle,{handle}) end function -- CloseHandle() global procedure Sleep(integer ms) c_proc(iSleep,{ms}) end procedure object fnVal atom counter, spinlock counter = 0 spinlock = 0 function IncCounter(atom param)-- the thread function while 1 do if spinlock = 1 then counter +=1 if counter = 10 then spinlock = 2 return 0 end if spinlock = 0 else --sleep(500) this does not work Sleep(500) end if end while end function atom lpStartAddress lpStartAddress = call_back(routine_id("IncCounter")) atom lpThreadId lpThreadId = allocate(4) atom lpParam lpParam = allocate(4) poke4(lpParam,0) atom hThread hThread = CreateThread(0,0,lpStartAddress,lpParam,0,lpThreadId) printf(1,"thread handle\n", hThread) if not hThread then puts(1, "echec creation thread\n") abort(0) end if while spinlock < 2 do if not spinlock then ? counter spinlock = 1 end if end while fnVal = CloseHandle(hThread)
Regards, Jacques Deschênes
2. Re: windows threads work!!
- Posted by Al Getz <Xaxo at aol.com> Jul 10, 2006
- 621 views
jacques deschênes wrote: > > > In the past I tested threads in euphoria without any success. At my first try > and didn't insist because At that time i thought it was a limitation of > euphoria > interpreter. > But this morning reading "windows internals" I learned that windows create a > new stack for each thread a process create. if so multithread should in > euphoria! > I decided to revisit it and IT WORKED!! > > }}} <eucode> > -- testing windows system threads in euphoria > > without warning > > include misc.e > include machine.e > include dll.e > > constant kernel32=open_dll("kernel32.dll") > > if kernel32 = -1 then > puts(1,"failed to open kernel32.dll\n") > abort(1) > end if > > constant > > iCreateThread=define_c_func(kernel32,"CreateThread",{C_POINTER,C_UINT,C_POINTER,C_POINTER,C_UINT,C_POINTER},C_UINT), > iSleep=define_c_proc(kernel32,"Sleep",{C_UINT}), > iCloseHandle = define_c_func(kernel32,"CloseHandle",{C_UINT},C_UINT) > > global function CreateThread(atom lpThreadAttributes, > atom dwStackSize, -- initial thread stack size, > in bytes > atom lpStartAddress, -- pointer to thread > function > atom lpParameter, -- argument for new thread > atom dwCreationFlags, -- creation flags > atom lpThreadId -- pointer to returned thread > identifier > ) > return > c_func(iCreateThread,{lpThreadAttributes,dwStackSize,lpStartAddress,lpParameter,dwCreationFlags,lpThreadId}) > end function --CreateThread() > > global function CloseHandle(atom handle) > return c_func(iCloseHandle,{handle}) > end function -- CloseHandle() > > global procedure Sleep(integer ms) > c_proc(iSleep,{ms}) > end procedure > > > object fnVal > atom counter, spinlock > > counter = 0 > spinlock = 0 > > > function IncCounter(atom param)-- the thread function > while 1 do > if spinlock = 1 then > counter +=1 > if counter = 10 then spinlock = 2 return 0 end if > spinlock = 0 > else > --sleep(500) this does not work > Sleep(500) > end if > end while > end function > > atom lpStartAddress lpStartAddress = call_back(routine_id("IncCounter")) > atom lpThreadId lpThreadId = allocate(4) > atom lpParam lpParam = allocate(4) poke4(lpParam,0) > atom hThread > > hThread = CreateThread(0,0,lpStartAddress,lpParam,0,lpThreadId) > printf(1,"thread handle\n", hThread) > if not hThread then puts(1, "echec creation thread\n") abort(0) end if > > while spinlock < 2 do > if not spinlock then > ? counter > spinlock = 1 > end if > end while > > fnVal = CloseHandle(hThread) > </eucode> {{{ > > Regards, > Jacques Deschênes Hi Jacques, I tried using threads a long time ago too with Euphoria without success, so i decided to try you new version here, but it didnt work for me (WinXP SP1). I got an error: "EXW had a problem and had to close". Any ideas what might be wrong? Also, what op sys are you using, 95,98,2000, or XP ? Take care, Al E boa sorte com sua programacao Euphoria! My bumper sticker: "I brake for LED's" From "Black Knight": "I can live with losing the good fight, but i can not live without fighting it". "Well on second thought, maybe not."
3. Re: windows threads work!!
- Posted by Pete Lomax <petelomax at blueyonder.co.uk> Jul 10, 2006
- 651 views
On Mon, 10 Jul 2006 07:00:41 -0700, jacques desch=EAnes <guest at RapidEuphoria.com> wrote: >In the past I tested threads in euphoria without any success. At my >first try and didn't insist because At that time i thought it was a >limitation of euphoria interpreter. It is. Btw, your example does not run on 2.4. >But this morning reading "windows internals" I learned that windows >create a new stack for each thread a process create. if so multithread >should in euphoria! >I decided to revisit it and IT WORKED!! If you use Eu to create pure windows/c_func threads then all will be fine. However Eu vars are not held on the windows stack, so using Eu code will fail; eg in function IncCounter after while 1 do add:
if not equal(lower("AAA"),"aaa") then puts(1,"lower(AAA)!=aaa\n") if getc(0) then end if abort(0) end if
and after while spinlock < 2 do add:
if not equal(lower("BBB"),"bbb") then puts(1,"lower(BBB)!=bbb\n") if getc(0) then end if abort(0) end if
Also, replace Sleep(500) with c_proc(iSleep,{500}) to avoid an almost inevitable type check on ms. The resulting program will fail or crash at random. TDLL in the archives shows how you can multi-OS-thread C/asm code from Eu, but you cannot multi-OS-thread Eu code, not without doing something like converting it to a dll first. Regards, Pete PS It is also not as simple as two threads calling the same routine (lower) simultaneously; the glitch in Sleep() shows it is re-using internal temporaries or something; if you comment out the lower call inside IncCounter, it works until the end, but the 'return 0' seems to spanner the last lower call from the main pgm. PPS Al: the example did not work for me at all on Eu 2.4 but did on Eu 2.5 (on win98), until as above I replaced Sleep() with c_func and then 2.4 nearly got to the end before crashing )
4. Re: windows threads work!!
- Posted by jacques deschênes <desja at globetrotter.net> Jul 10, 2006
- 661 views
Hi Al, I use windows xp pro with sp2. And run it many times on it without any problem. So I can't say why it work on my computer and not yours. regards, Jacques Deschênes
5. Re: windows threads work!!
- Posted by jacques deschênes <desja at globetrotter.net> Jul 10, 2006
- 660 views
Hi Pete, I modified my sample code adding the code you suggested but don't get any crash. But the line puts(1,"lower(AAA)!=aaa\n") doesn't print anything. Further reading form MSDN learned me that C run time library (CRT) must be a multi-threaded version for a program using multi-thread with CRT functions to work properly. I think that those functions of euphoria that fails are those that call crt functions and I guess that exwc.exe version 2.5 is not linked with a multi-threaded version of CRT. Concerning euphoria variables not being accesible by the thread function, its wrong. A thread function is a callback function like any windows functions and it can access all euphoria object. In my example spinlock and counter are euphoria global variables and IncCounter() access them successfully. In fact the only problem here is the fact that the euphoria interpreter is not linked with a multi-threaded version of CRT. By the way it work without any crash on my machine because all CRT dll that comes with windows xp are multi-threaded versions. But it fail with crt functions that are statically linked with exwc.exe Maybe Robert Craig could confirm my hypothesis about static linkage of CRT in exwc.exe Regards, Jacques Deschênes Pete Lomax wrote: > > On Mon, 10 Jul 2006 07:00:41 -0700, jacques desch=EAnes > <guest at RapidEuphoria.com> wrote: > > >In the past I tested threads in euphoria without any success. At my > >first try and didn't insist because At that time i thought it was a > >limitation of euphoria interpreter. > It is. Btw, your example does not run on 2.4. > >But this morning reading "windows internals" I learned that windows > >create a new stack for each thread a process create. if so multithread > >should in euphoria! > >I decided to revisit it and IT WORKED!! > If you use Eu to create pure windows/c_func threads then all will be > fine. However Eu vars are not held on the windows stack, so using Eu > code will fail; eg in function IncCounter after while 1 do add: > }}} <eucode> > if not equal(lower("AAA"),"aaa") then > puts(1,"lower(AAA)!=aaa\n") > if getc(0) then end if > abort(0) > end if > </eucode> {{{ > and after while spinlock < 2 do add: > }}} <eucode> > if not equal(lower("BBB"),"bbb") then > puts(1,"lower(BBB)!=bbb\n") > if getc(0) then end if > abort(0) > end if > </eucode> {{{ > Also, replace Sleep(500) with c_proc(iSleep,{500}) to avoid an almost > inevitable type check on ms. > The resulting program will fail or crash at random. > > TDLL in the archives shows how you can multi-OS-thread C/asm code from > Eu, but you cannot multi-OS-thread Eu code, not without doing > something like converting it to a dll first. > > Regards, > Pete > PS It is also not as simple as two threads calling the same routine > (lower) simultaneously; the glitch in Sleep() shows it is re-using > internal temporaries or something; if you comment out the lower call > inside IncCounter, it works until the end, but the 'return 0' seems to > spanner the last lower call from the main pgm. > > PPS Al: the example did not work for me at all on Eu 2.4 but did on Eu > 2.5 (on win98), until as above I replaced Sleep() with c_func and then > 2.4 nearly got to the end before crashing ) > >
6. Re: windows threads work!!
- Posted by Robert Craig <rds at RapidEuphoria.com> Jul 11, 2006
- 703 views
jacques deschênes wrote: > Maybe Robert Craig could confirm my hypothesis about static linkage of CRT in > exwc.exe exwc.exe (and exw.exe) are compiled with Watcom C, and they statically link with Watcom's standard C library. You might be able to get O/S threads working in a few small programs, but there are some major problems that will prevent operating system pre-emptive threads from working *reliably*. As you are aware, the C run-time library needs to be thread-safe, but Watcom's library is not. On top of that, Euphoria's run-time routines are not thread safe. For instance, Ref() and DeRef() operations are performed all over the interpreter. If the O/S were to pre-emptively switch to another thread in the middle of a Ref or DeRef, the reference count on an object could get messed up, eventually leading to a storage leak or a crash. A program might run a hundred times successfully before crashing mysteriously on the hundred and first run. I'd probably have to abandon reference counting, and go to garbage collection, as one step in supporting preemptive O/S threads. (Remember that Euphoria 3.0 pre-alpha already supports *cooperative* threads (tasks)). Regards, Rob Craig Rapid Deployment Software http://www.RapidEuphoria.com