[m-rev.] diff: implement semaphores on the il backend

Peter Ross pro at missioncriticalit.com
Sat Mar 1 01:47:38 AEDT 2003


Hi,


===================================================================


Estimated hours taken: 1
Branches: main, release

Implement semaphores on the il backend.

extras/concurrency/semaphore.m:
	Change semaphore to be a foreign_type.
	Add the C# class ME_Semaphore which contains the semaphore
	count and use System.Threading.Monitor to control access to
	it.


Index: semaphore.m
===================================================================
RCS file: /home/mercury1/repository/mercury/extras/concurrency/semaphore.m,v
retrieving revision 1.11
diff -u -r1.11 semaphore.m
--- semaphore.m	13 Feb 2002 09:56:26 -0000	1.11
+++ semaphore.m	28 Feb 2003 14:35:53 -0000
@@ -21,6 +21,9 @@
 :- import_module bool, io.
 
 :- type semaphore.
+:- pragma foreign_type(c,  semaphore, "ME_Semaphore *").
+:- pragma foreign_type(il, semaphore,
+		"class [semaphore__csharp_code]ME_Semaphore").
 
 	% new(Sem, IO0, IO) creates a new semaphore `Sem' with its counter
 	% initialized to 0.
@@ -51,8 +54,6 @@
 
 :- import_module std_util.
 
-:- type semaphore	== c_pointer.
-
 :- pragma c_header_code("
 	#include <stdio.h>
 	#include ""mercury_context.h""
@@ -73,6 +74,12 @@
 	} ME_Semaphore;
 ").
 
+:- pragma foreign_decl("C#", "
+public class ME_Semaphore {
+	public int count;
+}
+").
+
 :- pragma c_header_code("
 #ifdef MR_CONSERVATIVE_GC
   void ME_finalize_semaphore(GC_PTR obj, GC_PTR cd);
@@ -107,9 +114,14 @@
 	GC_REGISTER_FINALIZER(sem, ME_finalize_semaphore, NULL, NULL, NULL);
 #endif
 
-	Semaphore = (MR_Word) sem;
+	Semaphore = sem;
 	IO = IO0;
 }").
+:- pragma foreign_proc("C#", semaphore__new(Semaphore::out, _IO0::di, _IO::uo),
+		[will_not_call_mercury, thread_safe, promise_pure], "{
+	Semaphore = new ME_Semaphore();
+	Semaphore.count = 0;
+}").
 
 :- pragma c_code("
 #ifdef MR_CONSERVATIVE_GC
@@ -179,6 +191,14 @@
 #endif
 	IO = IO0;
 }").
+:- pragma foreign_proc("C#", signal(Semaphore::in, _IO0::di, _IO::uo),
+		[will_not_call_mercury, thread_safe, promise_pure], "{
+	System.Threading.Monitor.Enter(Semaphore);
+	Semaphore.count++;
+		// XXX I think we only need to do a Pulse.
+	System.Threading.Monitor.PulseAll(Semaphore);
+	System.Threading.Monitor.Exit(Semaphore);
+}").
 
 		% because semaphore__wait has a local label, we may get
 		% C compilation errors if inlining leads to multiple copies
@@ -221,6 +241,18 @@
 #endif
 	IO = IO0;
 }").
+:- pragma foreign_proc("C#", wait(Semaphore::in, _IO0::di, _IO::uo),
+		[will_not_call_mercury, thread_safe, promise_pure], "{
+	System.Threading.Monitor.Enter(Semaphore);
+
+	while (Semaphore.count <= 0) {
+		System.Threading.Monitor.Wait(Semaphore);
+	}
+
+	Semaphore.count--;
+
+	System.Threading.Monitor.Exit(Semaphore);
+}").
 
 semaphore__try_wait(Sem, Res) -->
 	semaphore__try_wait0(Sem, Res0),
@@ -249,4 +281,18 @@
 		Res = 1;
 	}
 	IO = IO0;
+}").
+:- pragma foreign_proc("C#",
+		try_wait0(Semaphore::in, Res::out, _IO0::di, _IO::uo),
+		[will_not_call_mercury, thread_safe, promise_pure], "{
+	System.Threading.Monitor.Enter(Semaphore);
+
+	if (Semaphore.count > 0) {
+		Semaphore.count--;
+		System.Threading.Monitor.Exit(Semaphore);
+		Res = 0;
+	} else {
+		System.Threading.Monitor.Exit(Semaphore);
+		Res = 1;
+	}
 }").

--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list