Re: Overloading and overlap

2005-04-20 Thread Daan Leijen




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

2005-04-19 Thread Daan Leijen
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

2005-04-19 Thread Daan Leijen
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

2004-06-25 Thread Daan Leijen
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

2004-06-25 Thread Daan Leijen
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

2003-07-13 Thread Daan Leijen
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

2003-03-21 Thread Daan Leijen
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

2003-03-14 Thread Daan Leijen
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

2003-03-14 Thread Daan Leijen
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

2003-03-14 Thread Daan Leijen
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

2003-03-14 Thread Daan Leijen
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]

2003-03-05 Thread Daan Leijen
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

2003-03-01 Thread Daan Leijen
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