namespace sc_core
 {
 
-sc_semaphore::sc_semaphore(int) :
+sc_semaphore::sc_semaphore(int value) :
         sc_interface(), sc_semaphore_if(),
-        sc_object(sc_gen_unique_name("semaphore"))
+        sc_object(sc_gen_unique_name("semaphore")), _value(value)
 {}
 
-sc_semaphore::sc_semaphore(const char *name, int) :
-        sc_interface(), sc_semaphore_if(), sc_object(name)
+sc_semaphore::sc_semaphore(const char *name, int value) :
+        sc_interface(), sc_semaphore_if(), sc_object(name), _value(value)
 {}
 
 int
 sc_semaphore::wait()
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+    while (trywait() == -1)
+        ::sc_core::wait(posted);
     return 0;
 }
 
 int
 sc_semaphore::trywait()
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
-    return 0;
-}
+    if (!_value)
+        return -1;
 
-int
-sc_semaphore::post()
-{
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+    _value--;
     return 0;
 }
 
 int
-sc_semaphore::get_value() const
+sc_semaphore::post()
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+    if (_value++ == 0)
+        posted.notify();
     return 0;
 }
 
-const char *sc_semaphore::kind() const { return "sc_semaphore"; }
+int sc_semaphore::get_value() const { return _value; }
 
 } // namespace sc_core
 
 #ifndef __SYSTEMC_EXT_CHANNEL_SC_SEMAPHORE_HH__
 #define __SYSTEMC_EXT_CHANNEL_SC_SEMAPHORE_HH__
 
+#include "../core/sc_event.hh"
 #include "../core/sc_object.hh"
 #include "sc_semaphore_if.hh"
 
     virtual int post();
     virtual int get_value() const;
 
-    virtual const char *kind() const;
+    virtual const char *kind() const { return "sc_semaphore"; }
 
   private:
     // Disabled
     {}
 
     sc_semaphore &operator = (const sc_semaphore &) { return *this; }
+
+    int _value;
+    sc_event posted;
 };
 
 } // namespace sc_core