Re: Overloading and overlap
Monique Louise wrote: Hi, Daan, Note that "under the hood" even .NET and Java use different names for each method ("renaming") to distinguish them. perhaps the virtual machine or the JIT compiler use different names to resolve overloads, but the code in .NET MSIL, for example, uses the same name. Ah yes, but that is because the .NET system still maintains types, ie. the JIT resolves them in the end. So, if you want to call a .NET overloaded function, you also need to pass the types of the arguments (which is just as complicated as "renaming"). I guess that from the Haskell side, you still need to have unique names for each overloaded version and use the class system to resolve them. Maybe you can do with a single version where you pass the types of the arguments too? Maybe with Dynamic of Equality data types from [1]? All the best, -- Daan [1] Arthur Baars and Doaitse Swierstra, "Typing Dynamic Typing" I don't know of any other solution , but you may want to read Andre Pang's master thesis (under supervision of Manuel Chackravarty) that might have some content about this. Do you know where I can find that thesis ? Thanks, Monique Louise B.Monteiro Msc Student in Computer Science Center of Informatics Federal University of Pernambuco ___ FFI mailing list FFI@haskell.org http://www.haskell.org/mailman/listinfo/ffi ___ FFI mailing list FFI@haskell.org http://www.haskell.org/mailman/listinfo/ffi
Re: Overloading and overlap
Monique Louise wrote: does anyone know about any existing extensions to FFI or even to GHC which incorporate access to overloaded methods, which are common in OO environments (.NET, Java), without using "renaming techniques" ? I think you refer here to "overloaded methods" in the sense of methods with the same name in the same class with different argument types (a la Java, or C++). > class C { void foo( Int i ); void foo (Float f ): } Note that "under the hood" even .NET and Java use different names for each method ("renaming") to distinguish them. > class C { void foo_Int( Int i); void foo_Float( Float f); } This compiler assigns the unoverloaded name statically once the types of the arguments are known. So, when using such methods from the Haskell FFI, I think you can only call into the unoverloaded names. > foreign import dynamic c_foo_Int :: C -> Int -> IO () > foreign import dynamic c_foo_Float :: C -> Float -> IO () I guess you can get the overloading again by using the usual Haskell classes: > class C_foo a where c_foo :: C -> a -> IO () > instance C_foo Int where c_foo = c_foo_Int > instance C_foo Float where c_foo = c_foo_Float I don't know of any other solution , but you may want to read Andre Pang's master thesis (under supervision of Manuel Chackravarty) that might have some content about this. All the best, Daan Leijen. Thanks in advance, ___ FFI mailing list FFI@haskell.org http://www.haskell.org/mailman/listinfo/ffi
Re: help on win32
James Mitchell wrote: I'm writing an interface to Berkeley DB, and, while I can link to my wrapper library fine from C, I can't seem to do it successfully from GHC. I think you are trying to link agains an Microsoft Visual C++ library. You need to convert it first to a mingw compatible library and you can do that using a special utitility called. "reimp.exe". You can get it by downloading the wxHaskell sources -- it is in the "bin" directory. when you do "reimp foo.lib", it will create "libfoo.a" and "foo.def" that can be linked with ghc stuff. I hope this helps, -- Daan Leijen My first attempt was: D:\src\dm>ghc -fffi test.hs db.lib libdb43.lib compilation IS NOT required Warning: .drectve `/DEFAULTLIB:"libcp" /DEFAULTLIB:"LIBC" /DEFAULTLIB:"OLDNAMES" /EXPORT:_db_info_status_pos,DATA /EXPOR T:_db_info_struct_size,DATA /EXPORT:[EMAIL PROTECTED] /EXPORT:[EMAIL PROTECTED] /EXPORT:[EMAIL PROTECTED] /EXPORT:[EMAIL PROTECTED] /EXPORT:_db_re [EMAIL PROTECTED] /EXPORT:_db_info_mode_pos,DATA /EXPORT:_db_info_out_data_pos,DATA /EXPORT:_db_info_in_data_length_pos,DATA /EXPOR T:_db_info_pathname_pos,DATA /EXPORT:_db_info_error_pos,DATA /EXPORT:_db_info_in_data_pos,DATA /EXPORT:_db_info_key_leng th_pos,DATA /EXPORT:_db_info_key_pos,DATA /EXPORT:_db_info_out_data_length_pos,DATA /EXPORT:_db_info_db_name_pos,DATA ' unrecognized db.lib(Release/berk_db.obj)(.text+0xd):berk_db.cpp: undefined reference to [EMAIL PROTECTED]@Z' db.lib(Release/berk_db.obj)(.text+0xc):berk_db.cpp: undefined reference to `_except_list' db.lib(Release/berk_db.obj)(.text+0x14):berk_db.cpp: undefined reference to `_except_list' db.lib(Release/berk_db.obj)(.text+0x5d):berk_db.cpp: undefined reference to [EMAIL PROTECTED]@Z' db.lib(Release/berk_db.obj)(.text+0x7e):berk_db.cpp: undefined reference to `_except_list' db.lib(Release/berk_db.obj)(.text+0x6c):berk_db.cpp: undefined reference to [EMAIL PROTECTED]@Z' db.lib(Release/berk_db.obj)(.text+0x78):berk_db.cpp: undefined reference to [EMAIL PROTECTED]@Z' ... where db.lib is my wrapper library. Taking a hint from the compiler defaultlib directives, I then did the following: D:\src\dm>ghc -fffi test.hs db.lib libdb43.lib libc.lib libcp.lib oldnames.lib compilation IS NOT required libc.lib(build/intel/st_obj/crt0.obj)(.text+0x0): In function `mainCRTStartup': f:\vs70builds\9466: multiple definition of `mainCRTStartup' D:/GHC/GHC-6.2.2/gcc-lib/crt2.o(.text+0x240):crt1.c: first defined here Warning: .drectve `/DEFAULTLIB:"libcp" /DEFAULTLIB:"LIBC" /DEFAULTLIB:"OLDNAMES" /EXPORT:_db_info_status_pos,DATA /EXPOR T:_db_info_struct_size,DATA /EXPORT:[EMAIL PROTECTED] /EXPORT:[EMAIL PROTECTED] /EXPORT:[EMAIL PROTECTED] /EXPORT:[EMAIL PROTECTED] /EXPORT:_db_re [EMAIL PROTECTED] /EXPORT:_db_info_mode_pos,DATA /EXPORT:_db_info_out_data_pos,DATA /EXPORT:_db_info_in_data_length_pos,DATA /EXPOR T:_db_info_pathname_pos,DATA /EXPORT:_db_info_error_pos,DATA /EXPORT:_db_info_in_data_pos,DATA /EXPORT:_db_info_key_leng th_pos,DATA /EXPORT:_db_info_key_pos,DATA /EXPORT:_db_info_out_data_length_pos,DATA /EXPORT:_db_info_db_name_pos,DATA ' unrecognized Warning: .drectve `/merge:.CRT=.data /defaultlib:kernel32.lib /disallowlib:libcd.lib /disallowlib:libcmt.lib /disallowli b:libcmtd.lib /disallowlib:msvcrt.lib /disallowlib:msvcrtd.lib ' unrecognized Warning: .drectve `/MERGE:.rtc=.rdata ' unrecognized I assume that the warnings are no problem, but I can't figure out how to get rid of the duplicate "mainCRTStartup" symbol. This's really vexing me, as there are a number of things such as gdb support that would go a long way towards making Haskell more useable for general purpose applications (instead of the "hard" calculations at which it excels), but I just can't seem to make it work. thanks in advance, James |---| | James Mitchell | http://www.jimdesu.us | |---| |When the shoe fits, the foot is forgotten; when| |the belt fits, the belly is forgotten; when the| |heart is right, "for" and "against" are| |forgotten. -- Chuang Tzu | |---| __ Do you Yahoo!? Yahoo! Small Business - Try our new resources site! http://smallbusiness.yahoo.com/resources/ ___ FFI mailing list FFI@haskell.org http://www.haskell.org/mailman/listinfo/ffi ___ FFI mailing list FFI@haskell.org http://www.haskell.org/mailman/listinfo/ffi
atomicModifyIORef
Thanks Martin and Simon for your prompt feedback. (and apologies for the wrong subject header) On Fri, 25 Jun 2004 12:14:26 +0100, Simon Marlow <[EMAIL PROTECTED]> wrote: It seems to me that returning the old value is always good enough right? Here is an implementation of "atomicModifyIORef" with the current type in terms of a function "proposedModifyIORef" with type (2). atomicModifyIORef :: IORef a -> (a -> (a,b)) -> IO b atomicModifyIORef ref f = do old <- proposedModifyIORef ref (fst . f) return (snd (f old)) Yes, but in your version you apply f to the old value twice, potentially duplicating an expensive computation. Ok, I never thought of that. However, isn't it the case that I normally just want to get the old value back? In that case, the current interface is not so friendly. Is anyone using this function to get something else than the old/new value *and* where the computation is expensive? If not, maybe we should (also) provide a nicer interface? atomicModifyIORef isn't part of the FFI spec, BTW. Well, I asked about this as I was confused by the type of this function: at first I thought that I was missing some essential functionality :-) -- Daan. Cheers, Simon ___ FFI mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/ffi ___ FFI mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/ffi
Re: [Haskell] ANNOUNCING: The Haskell Bookstore
Is there anyone who knows why "atomicModifyIORef" has type: IORef a -> (a -> (a, b)) -> IO b (1) Instead of: IORef a -> (a -> a) -> IO a (2) It seems to me that returning the old value is always good enough right? Here is an implementation of "atomicModifyIORef" with the current type in terms of a function "proposedModifyIORef" with type (2). atomicModifyIORef :: IORef a -> (a -> (a,b)) -> IO b atomicModifyIORef ref f = do old <- proposedModifyIORef ref (fst . f) return (snd (f old)) It makes much more sense to me to have type (2), the scope for errors and code duplication is much lower in my opinion. All the best, Daan. ___ FFI mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/ffi
RE: More Finaliser Trouble
Hi Ashley, You can use the newForeignPtr the is exported from the Concurrent module (in ghc 6.0), this function has the same signature as the old haskell function. When switching to ghc 6.0 I changed: import Foreign.ForeignPtr to: import Foreign.ForeignPtr hiding (newForeignPtr,addForeignPtrFinalizer) import Foreign.Concurrent And everything kept working fine :-) Hope this helps, (allthough it doesn't answer the question of why these things have changed or how to add parameters to the new newForeignPtr function,) -- Daan > -Original Message- > From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On > Behalf Of Ashley Yakeley > Sent: zondag 13 juli 2003 10:15 > To: [EMAIL PROTECTED] > Subject: More Finaliser Trouble > > > How do I pass a parameter to a finaliser? The pointer itself does not > have enough information to run the finaliser, I need an extra > parameter > available at the time the pointer is created. > > This was easy to do when I could write finalisers in Haskell, > of course, > since I could just apply the parameter to my finaliser > function to get a > finaliser that had the correct type. This is what it looked like: > > foreign import ccall "JVMBridge.h JVMBridge_DeleteGlobalRefGC" > rawDeleteGlobalRefGC :: JavaVM -> RawGlobalRef -> IO (); > > > vm <- rawGetJavaVM ?jvmenv; > gref <- newForeignPtr rgref (rawDeleteGlobalRefGC vm >(MkRawGlobalRef rgref)); > return (MkVMRef gref); > > But with the new FFI I can't do this so easily. How would I pass the > 'vm' parameter to a finaliser which is only allowed to look at the > 'rgref' pointer? > > -- > Ashley Yakeley, Seattle WA > > ___ > FFI mailing list > [EMAIL PROTECTED] > http://www.haskell.org/mailman/listinfo/ffi > > ___ FFI mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/ffi
Re: Bound Threads
Hi all, I think everyone is keen to make progress on this bound-threads stuff. You have an alternative idea which we are trying to understand. Do you plan to have a go at the operational semantics, as a way of explaining it? Sorry for not having replied. I am very busy finishing my thesis and I can't look into it sooner than next week. The thesis-finishing business is in any case taking so much time that I can't really help out on implementation or other time consuming activities. However, my proposal is not anywhere fundamentally difficult -- in its essence, I just propose to move the implementation of the thread allocation strategy from the RTS/C code, to a Haskell library. This gives programmers both a low-level interface for explicit access and a high-level interface as it is now. At the moment we're a bit stuck: no one wants to move on before we have some kind of consensus, but you're the only one who can help us understand your proposal. Well, it is not my intention to stop progress! I haven't fully worked out my design, for example, it seems that dynamic rescheduling of haskell threads to OS threads is rather difficult -- I can only say more about this next week. What I mostly wanted to ensure is that people have really thought about this carefully and that they could give strong reasons for choosing a particular design over another. If you feel that this is the case -- by all means continue as you have done and disregard my disturbances. All the best, Daan. Simon | -Original Message- | From: Simon Peyton-Jones [mailto:[EMAIL PROTECTED] | Sent: 17 March 2003 22:06 | To: Daan Leijen; Wolfgang Thaller; [EMAIL PROTECTED] | Subject: RE: Bound Threads | | | | | Maybe, the forkOS/forkIO approach is flawed, but I think we | | should only rule it out when we can provide a convincing | | example where only the keyword approach would work, and where | | we can't use combinators to achieve the same effect. | | | Daan, | | There has been extended discussion on this stuff, which Wolfgang and | Simon and I tried to boil out into a document. It's hard to say exactly | what 'safe' or 'bound' exports, or whatever, might mean, so we give a | little operational semantics. | | My hope is that the very same operational-semantic framework would serve | to describe your system. Would you like to write its transition rules, | in the same style? Then we could compare the two more easily. Without | that, I am hard pressed to understand the implications of what you | suggest, just as I was hard pressed to understand Wolfgang's proposal | till we had it specified. | | You can find the document in the CVS respository in | haskell-report/ffi/threads.tex | | Simon ___ FFI mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/ffi
Re: Bound Threads
Hi Wolfgang, Maybe, the forkOS/forkIO approach is flawed, but I think we should only rule it out when we can provide a convincing example where only the keyword approach would work, and where we can't use combinators to achieve the same effect. That's unfair ;-) --- I could also claim the reverse and say that we stick with threadsafe/bound until we have a convincing example... Using combinators sounds good, but there are things where combinators are not automatically the best choice (we're usually not using combinators to implement lazyness, either), and we don't know yet whether this is the case here or not. So let's just get on with the discussion No, it is not unfair. We should only introduce a new keyword/syntax if we are unable to express the behaviour in plain Haskell or if it very awkward to do so. Now, I can be easily convinced that "threadsafe" is the way to go, whenever there is a compelling example where forkOS/forkIO fails. At first, I thought that one could never come up with a counter example: since forkOS/forkIO are the most primitive calls, we can always model any strategy implemented in C (and more). However, I just realised that there is more than meets the eye: you just described that "GHC moves all non-bound Haskell threads to a second OS thread". This is something that can not be described without adding another primitive (forkUnbound?) and it may lead to an example that is not expressible with forkOS/forkIO. On the other hand, it seems awkward/impossible to make sure that certain functions are always called from a specific OS thread with the "threadsafe" approach while the forkOS/forkIO primitives are always available to the programmer for explicit management of threads. In general though, I have learned over the years that is most of the time better to first find an implementation using low-level primitives in Haskell, and maybe later add special syntax, than to implement a strategy directly in C. About the example: [snip] That is amazing :-) [...] [snip] makes sure that there is a second OS thread available (some overhead the first time) and b) makes sure that all non-bound [in the current implementation: all] Haskell threads are executed by the second OS thread from now on. [snip] Thanks for the explanation. Just on the side, it seems that this approach always involves an OS context switch for bound callbacks. This doesn't happen with the forkOS/forkIO approach. It may be rather expensive, take a mouse motion event handler for example. Maybe we need a more exact specification of how forkOS/forkIO should behave, especially with respect to foreign calls blocking other threads. Could you elaborate on how you would expect "normal" (safe) > foreign calls to behave in different situations? 1) "forkOS" starts a new haskell thread in a new OS thread 2) "forkIO" starts a new haskell thread in the current OS thread 3) maybe we should also add "forkUnbound" that forks a haskell thread that can automatically be moved between OS threads. 4) a foreign call blocks all haskell threads that are attached to the current OS thread until a) the call returns, or b) the call enters Haskell again. 5) on top of this, we can implement *) a library function "fork" that forks a new haskell thread that maybe runs in separate OS thread, depending on the architecture. *) a "threadSafe" combinator to make non-blocking foreign calls. notes: * "forkOS" doesn't have to use a new OS thread to run Haskell threads, just when calling a foreign function, so it would work on Hugs too for example. (as explained in a previous mail). * The naming is a bit inconveniently chosen. Better would be: forkOS => forkNativeThread forkIO => forkHaskellThread Now, "forkIO" can now be implemented in terms of those two functions, and can be used when the user doesn't care about how the thread is scheduled. Now, what I don't like about my proposal and your proposal is that the user has to be aware of OS threads when making foreign calls by wrapping it in "threadSafe" or adding "threadsafe" sometimes -- but maybe that is unavoidable. All the best, Daan. ___ FFI mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/ffi
Re: Bound Threads
Hi Wolfgang, I feel like you are beating my proposal to death here, and I find it hard to react individually to all your remarks. I'll try to focus on the main issue: You are worried that the forkOS and forkIO distinction is too primitive and that it rule out sophisticated scheduling on SMP processors for example. I think that you are right if the programmer use forkOS and forkIO directly all the time but in general, we can provide abstractions *in haskell* to deal with scheduling. See my "fork" example in the previous mail. The bottom line is that if we have access from Haskell to the primitives, we can always implement any smart scheme that we need or want. If you implement a strategy via keywords, it is fixed. I don't promote using low-level programming but I think that "bound" and "threadsafe" should be implemented using combinators in Haskell itself, with some low-level functions like forkIO. Maybe, the forkOS/forkIO approach is flawed, but I think we should only rule it out when we can provide a convincing example where only the keyword approach would work, and where we can't use combinators to achieve the same effect. All the best, Daan. About the example: Now, I have an example from the wxHaskell GUI library that exposes some of the problems with multiple threads. I can't say it can be solved nicely with forkOS, so I wonder how it would work out with "threadsafe": [snip] In case that wxWindows makes the assumption that it's functions are invoked _from the same OS thread_ that it used to call your callback, you can add "bound" to the foreign export statement for your callback. Then you would use just forkIO and everything would work. That is amazing :-) Suppose that there is one OS thread running here -- the GUI thread. When the callback is called, I use "bound" so that the callback still runs in the GUI thread. When I use "forkIO", the forked computation could also run in the same GUI thread (I guess it is unspecified, but suppose it does). When the callback returns to C land, the eventloop will wait and since there is still just one OS thread running, the forked computation will block Urk, somehow the RTS has to be smart enough to spawn a new OS thread when forkIO is called. Right? Since the haskell function is called via a callback, I guess that "threadsafe" should also apply to "wrapper" functions -- that is, when the foreign world calls haskell, we use another OS thread to run the haskell code. Sorry, no clue what you mean... could you elaborate? "threadsafe" just applies to imports, not to ? exports and wrappers. "bound" applies to exports and wrappers, but not to imports. Should it be different? Since the RTS can't guess whether to use new OS threads or not at forkIO, I assumed that you could mark "wrapper" functions (callbacks) with a "threadsafe" attribute. If this is not the case, I don't understand how the implementation could work in this particular example. ___ FFI mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/ffi
Re: Bound Threads
Hi Simon, I'd like to point out a concept that I think is being missed here: We never want to specify what OS thread is running a particular Haskell thread. why not? Because (a) it doesn't matter: the programmer can never tell, and (b) we want to give the implementation freedom to spread Haskell threads across multiple OS threads to make use of multiple real CPUs. I agree that these are valid points. However, as I said, I don't think we can do (b), ie. automatic management, in many real-world situations. The above points are mostly useful in a pure Haskell setting. In general, I think that only the programmer knows what strategy to use. In particular, we can provide a "fork" function that forks of a new Haskell thread that maybe runs in a new OS thread, or other CPU; basically implementing the above concept for programs that don't care about how the Haskell threads are distributed over OS threads: fork :: IO () -> IO ThreadID fork io = do newOS <-[complex algorithm that determines if a new OS thread is needed.] if (newOS) then forkOS io else do threadID <-[complex algorithm that determines in which existing thread we run it] forkIOIn threadID io Note that we can now implement our really sophisticated distributed algorithms in plain Haskell. The point is that you want to specify which OS thread is used to invoke a foreign function, NOT which OS thread is used to execute Haskell code. The semantics that Simon & I wrote make this clear. This is a good point and that is also the weakness of the "forkOS", "forkIO" approach: it is less declarative and thus leaves less freedom to the implementation. However, I hope that through functions like "fork", we can bring back declarativeness by abstraction. If we keep thinking like this, then implementations like Hugs can be single-threaded internally but switch OS threads to call out to foreign functions, and implementations like GHC can be multi-threaded internally and avoid switching threads when calling out to foreign functions. Ha, this is not true :-) We are saved by your observation that in the Haskell world we can't observe whether we run in a different OS thread or not. Thus a single-threaded Hugs will implement forkOS as forkIO but still attaches a different "Hugs OS thread identifier" to the Haskell thread. When a foreign call is made, it matches the Hugs OS thread identifiers and uses a different OS thread if necessary, maintaining a mapping between the Hugs OS thread identifiers and the spawned OS threads. > threadSafe :: IO a -> IO a > threadSafe io > = do result <-newEmptyMVar > forkOS (do{ x <-io; putMVar result x }) > getMVar result This forces a thread switch when calling a threadsafe foreign function, which is something I think we want to avoid. We can refine the implementation to avoid a thread switch when it is the only Haskell thread running in the current OS thread: threadSafeEx :: IO a -> IO a threadSafeEx io = do count <-getHaskellThreadCountInTheCurrentOSThreadif (count > 1) then threadSafe io else io I'm basing this on two assumptions: (a) switching OS threads is expensive and (b) threadsafe foreign calls are common. I could potentially be wrong on either of these, and I'm prepared to be persuaded. But if both (a) and (b) turn out to be true, then worse is worse in this case. I think you are righ on (a), but I also think that we can avoid it just as it can be sometimes avoided when implemented in C in the runtime. Can't say anything about (b). All the best, Daan. Now, I have an example from the wxHaskell GUI library that exposes some of the problems with multiple threads. I can't say it can be solved nicely with forkOS, so I wonder how it would work out with "threadsafe": The example is a Haskell initialization function that is called via a callback from the GUI library. The Haskell initialization function wants to do a lot processing but still stay reactive to close events for example. Since events are processed in an eventloop, new events can only come in by returning from the callback. So, the initilization functions forks of a Haskell thread (the processor) to do all the work and returns as soon as possible to the C GUI library. Now, the eventloop starts to wait for the next event in C land. The problem is that the "processor" thread won't run since we have returned to C-land and the haskell scheduler can't run. We can solve it by running the processor thread with "forkOS". I can't say it is a particularly nice solution but it is how it is done in all other major programming languages. I wonder how the "threadsafe" keyword can be used to solve this problem. Since the haskell function is called via a callback, I guess that "threadsafe" should also apply to "wrapper" functions -- that is, when the foreign world calls haskell, we use another OS thread to run the haskell code. However, I think that we are than forced to use a OS thread context switch?? Cheers, Simon
Re: Bound Threads
Hi all, I have just spend some time reading through all the discussions and the new "threads" document and I would like to propose the addition of a new library function. forkOS :: IO () -> IO ThreadID The function "forkOS" forks a new Haskell thread that runs in a new OS (or native) thread. With this, I also propose that "forkIO" always runs a Haskell thread in the same OS thread that the current Haskell thread runs in. (i.e. "forkIO": same OS thread, "forkOS": new OS thread) Using the new primitive, we can view the new "threadsafe" keyword as syntactic sugar: foreign import threadsafe foo :: Int -> IO Int ===> foo :: Int -> IO Int foo i = threadSafe (primFoo i) foreign import "foo" primFoo :: IO Int where threadSafe :: IO a -> IO a threadSafe io = do result <-newEmptyMVarforkOS (do{ x <-io; putMVar result x }) getMVar result Note that "forkOS" can use thread pooling in its implementation. The advantage of a separate function "forkOS" is that we put control back to the users hands, as a programmer can be very specific about which Haskell threads are part of a certain OS thread and can be specific about the OS thread that is used to run a foreign function. On other words, it is absolutely clear to which OS thread a Haskell thread is bound. In this respect, it helps to have another function that runs a Haskell thread in a specific OS thread. getOSThread :: ThreadID -> OSThreadID forkIOIn :: OSThreadID -> IO () -> IO ThreadID I have the feeling that it is not difficult to implement "forkOS" and family once the runtime system has been upgraded to support multiple OS threads. Wolfgang, you seem to be the expert on the OS thread area, would it be hard? I am not saying that we should discard the "threadsafe" keyword as it might be a useful shorthand, but I think that it is in general a mistake to try to keep the management of OS threads implicit -- don't use new keywords, add combinators to implement them! I feel that the following has happened; urk, we need some way of keeping haskell threads running while calling C; we add "threadsafe"; whoops, sometimes a function expects that it is run in the same OS thread; we add "bound"; whoops, sometimes functions expect to be run from a specific OS thread... unsolved?? Before we know it, we have added tons of new keywords to solve the wrong problem. Maybe it is time to take a step back and use a somewhat lower level model with two fork variants: "forkIO" (in the same OS thread) and "forkOS" (in a new OS thread). It seems that none of the above problems occur when having explicit control. In general it seems that OS threads are a resource that is too subtle to be managed automatically as they have a profound impact on how libraries are used and applications are structured. All the best, Daan. "worse is better" :-) ___ FFI mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/ffi
Re: [Fwd: Re: Foreign import]
The error message is as follows -- CallIncr.o: In function `sWM_entry': CallIncr.o:(.text+0xc5): undefined reference to `incr' collect2: ld returned 1 exit status -- I think that you forgot to link in your library, say libfoo.a that defines the function "incr". ghc CallIncr.o -lfoo If it is just a single file, say "foo.o", you say ghc CallIncr.o foo.o -- Daan. where 'incr' is a toy function defined in 'mylib.h'. Obviously, in the foreign declaration I have changed 'myfun' by 'incr'. The compilation command is the typical ghc -ffi -c CallIncr.hs followed by ghc -ffi CallIncr.o which generate the previous error. Thanks again, gustavo Manuel M T Chakravarty said: "Gustavo Villavicencio" <[EMAIL PROTECTED]> wrote, I'm a new ffi user and I have some problems with foreign import declaration. I'm don't have any problem to access C standard functions. However, I cannot access to my own functions in mylib.h by means of foreign import "mylib.h myfun" hmyfun :: ... May be I'm omitting some compilation step or parameter also, since I'm applying the same compilation process to call C standard functions. I'm working with ghc 5.04 on SuSe Linux 7.0. You should say what goes wrong. Eg, paste the error messages of the compiler and/or linker into your email. Manuel ___ FFI mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/ffi ___ FFI mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/ffi
Re: [GUI] Example: Binding C++ to Haskell using the ffi
On Sat, 1 Mar 2003 13:40:42 -0800 (PST), David Sankel <[EMAIL PROTECTED]> wrote: Has any though gone into cplusplus? If so, how would it interface? Would stubs on the c++ side be generated or would it use the code directly. I think that it is in general infeasable to call c++ member function directly as different c++ compilers use wildly different calling conventions and name-mangling schemes. It makes more sense to call C++ via extern "C" wrappers and use foreign import ccall on the Haskell side. In my opinion, the 'ideal' way of interfacing to C++, or C, would be an adoption of H/Direct to read C or C++ header files directly and translating it to a default IDL specification -- one should than be able to augment this specification with IDL attributes, much like the current 'asf' files of H/Direct but probably more friendly. H/Direct could than generate both exern "C" wrappers and Haskell marshalling code at the same time. On the other hand, even though the above approach would solve all the interface problems once and for all, it certainly involves a significant amount of work to extend H/Direct with a C++ front-end and better asf support. All the best, Daan. ps. I have been experimenting with interfacing to the wxWindows library, a large C++ framework. I have used an existing Eiffel library that wrapped the C++ classes in C functions together with a small hand-written tool to translate their (simple) header files to Haskell marshalling code -- a poor-mans solution until H/Direct gets an update :-) It works rather well and imports 400 classes with 2500 methods with very reasonable type signatures. You may want to look at it to get some inspiration for interfacing to C++: http://wxhaskell.sourceforge.net It also shows how you can use polymorphism to mimic inheritance relationships (as described in "Calling hell from heaven and heaven from hell") pps. This is just a preview, don't expect a wxHaskell too soon, I have a thesis to finish in the next weeks :-) Later, David J. Sankel ___ GUI mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/gui ___ FFI mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/ffi