Solved

Pls Help : Win32 events on Unix

Posted on 1998-11-28
10
501 Views
Last Modified: 2013-12-26
Can anybody please help me to give some  ideas about
implementing Win32 event object in Unix.I need to design a
suitable data structure & functions to provide same functionality in Unix that is provided by event objects on
windows NT.
I have to emulate both automatic & Manual events.
Can I use pthread_mutexes to implement them.Can I use pthread_mutexex across processes.
Please give me suitable feedbacks as I can get a good ideas
from senior people like you in unix who must have  got experience in Synchronization policies & concurrency.

Sincere Regards,
Rajesh
0
Comment
Question by:unifolk
  • 5
  • 4
10 Comments
 
LVL 3

Expert Comment

by:braveheart
Comment Utility
What makes you think that Unix gurus know anything about Windows?
0
 

Author Comment

by:unifolk
Comment Utility
Because I think that Knowledge is a sharable,trivially increasing ,non vanishing unmeasurable resource.A guru of concepts is always a Guru & sometimes platform
independence works here.
0
 
LVL 3

Accepted Solution

by:
dhm earned 200 total points
Comment Utility
A Win32 Event can be emulated with two Unix semaphores.  (In Unix, when you create a semaphore [using semget()] you actually get an array of related semaphores, the size of which is specified by the second arg to semget().  You can allocate a pair of semaphores for each Event, or you can allocate a bunch of them and use them in pairs to emulate several Events.)

You emulate the Event by using one semaphore to control access to the pair, and by using the other semaphore to indicate the state of the Event.  Let me know if you need actual code to do this (and tell me which NT calls you want to emulate).

BTW, pthread_mutexes can be used across processes on some OSs (Solaris-2.5.1) but not on others (Linux-2.0.35).  (Perhaps I'm simply not using mutexes properly on Linux, or perhaps I need to use a different library or something.)  I haven't gotten around to testing on other platforms.  In any case, a mutex won't work to emulate an NT Event: it has the wrong semantics.
0
 

Author Comment

by:unifolk
Comment Utility
A thousand thaks for giving me a positive response.
Dear friend,I am facing one major problem ,Using your  idea I was successfully able to
emulate events.Only problem i am facing is I have to emulate WaitForMultipleobjects
for several events.Here the problem is that i will have to use a Busy wait like this
for(;;)
{
semctl (first event)
semctl(second event)
.
.
if(all signalled) exit
}

If I am doing this the problem is CPU time will be wasted in infinite loop instead I want some effecient wait like this.

Wait on condition (when any event in set of event i am interested is signalled)
{
if all signaled(exit)
}

Please give me any design ideas you experienced.

Sincere Regards,

I am attaching the document i prepared based on your idea below.

----------------------------------------------------------------------------------------------------------------------------------

                         Event model using semaphores as building blocks

Event : A semaphore triplet can be used to simulate a fully functional Win32 event object  in Unix environment.


Design  :  We will use three semaphores .


              Name & Charcteristics                                                       Semaphore No                                                                                      
1)Actual Value of Event          (0-Set/1-Reset)                                            0
2)Control lock(Is it safe to issue Set/Reset or not)                                      1
                    (0 -You can set,1-You can Reset)
3)Type Flag (Manual/Automatic )                                                               2
                   (0 - Automatic,1-Mannual)

Primitive operations on this semaphore list are as follows:

1)Create event(Initial Value of event,Type):
       
· Create a list of three semaphores pointed by  Semid.

                      Value       ControlLock       Type
                         0                 0                       0

· if(Initial Value==False(reset)) then issue an atomic command to do

                     Value       ControlLock       Type
                       1                  1                       0

· if(Type ==Manual)  then  issue an atomic command to do

                     Value       ControlLock       Type
                       0 /1              0/1                     1

2)ResetEvent()

     Give the following command

       
              Semaphore no       OpCode         Flag
                    1                         0                  NOWAIT
                    1                         1                  WAIT
                    0                         1                  WAIT
So lock control acts as a non-blocking mutex resource.If event is already set it will not be affected.

3)SetEvent()

     Give the following command
       :  
              Semaphore no       Command      Flag
                    1                         -1                  NOWAIT
                    0                         -1                  WAIT
 So lock control acts as a non-blocking mutex resource.If event is already reset it will not be affected.

4)PulseEvent : Need not be implemented.

5) OpenEvent : Acquire the Event id (Semaphore set id) from shared memory.If already created return a pointer(handle index) to it.


This model has following charcteristics.

1)Atomicity : All operations can be atomic in nature.So race conditions would not arise.
2)Pthread independence  : The system level semaphore functions in Unix can also  work effeciently with pthread threads i.e we can effeceintly make pthreads wait on a semaphore.
3)Procedural abstractions : The high level functions (sub -application) will only use wrapper functions instead of  accesing the ingradients of event structure directly.This will protect the implementation.

Interfaces that can help to implement wait functions.

The following  opcode values when passed to semctl() function  can be helpful to implement Wait Functions.

Wait on Single Object : There are four primitive operations
   
1)Non-blocking wait on a Manual event.
     
              Semaphore no       Command      Flag
                    0                          0                  NOWAIT
 
       .
  2) Blocking wait on a Manual event.
   
              Semaphore no       Command      Flag
                    0                          0                  WAIT
 
       
3)Non-blocking wait on a Automatic event.
 
              Semaphore no       Command      Flag
                    0                         0                  NOWAIT
                    1                         0                  NOWAIT
                    1                         1                  WAIT
                    0                         1                  WAIT
 
4) Blocking wait on a Manual evant.
 
              Semaphore no       Command      Flag
                    0                         0                  WAIT
                    1                         0                  NOWAIT
                    1                         1                  WAIT
                    0                         1                  WAIT


 








0
 

Author Comment

by:unifolk
Comment Utility
A thousand thaks for giving me a positive response.
Dear friend,I am facing one major problem ,Using your  idea I was successfully able to
emulate events.Only problem i am facing is I have to emulate WaitForMultipleobjects
for several events.Here the problem is that i will have to use a Busy wait like this
for(;;)
{
semctl (first event)
semctl(second event)
.
.
if(all signalled) exit
}

If I am doing this the problem is CPU time will be wasted in infinite loop instead I want some effecient wait like this.

Wait on condition (when any event in set of event i am interested is signalled)
{
if all signaled(exit)
}

Please give me any design ideas you experienced.

Sincere Regards,

I am attaching the document i prepared based on your idea below.

----------------------------------------------------------------------------------------------------------------------------------

                         Event model using semaphores as building blocks

Event : A semaphore triplet can be used to simulate a fully functional Win32 event object  in Unix environment.


Design  :  We will use three semaphores .


              Name & Charcteristics                                                       Semaphore No                                                                                      
1)Actual Value of Event          (0-Set/1-Reset)                                            0
2)Control lock(Is it safe to issue Set/Reset or not)                                      1
                    (0 -You can set,1-You can Reset)
3)Type Flag (Manual/Automatic )                                                               2
                   (0 - Automatic,1-Mannual)

Primitive operations on this semaphore list are as follows:

1)Create event(Initial Value of event,Type):
       
· Create a list of three semaphores pointed by  Semid.

                      Value       ControlLock       Type
                         0                 0                       0

· if(Initial Value==False(reset)) then issue an atomic command to do

                     Value       ControlLock       Type
                       1                  1                       0

· if(Type ==Manual)  then  issue an atomic command to do

                     Value       ControlLock       Type
                       0 /1              0/1                     1

2)ResetEvent()

     Give the following command

       
              Semaphore no       OpCode         Flag
                    1                         0                  NOWAIT
                    1                         1                  WAIT
                    0                         1                  WAIT
So lock control acts as a non-blocking mutex resource.If event is already set it will not be affected.

3)SetEvent()

     Give the following command
       :  
              Semaphore no       Command      Flag
                    1                         -1                  NOWAIT
                    0                         -1                  WAIT
 So lock control acts as a non-blocking mutex resource.If event is already reset it will not be affected.

4)PulseEvent : Need not be implemented.

5) OpenEvent : Acquire the Event id (Semaphore set id) from shared memory.If already created return a pointer(handle index) to it.


This model has following charcteristics.

1)Atomicity : All operations can be atomic in nature.So race conditions would not arise.
2)Pthread independence  : The system level semaphore functions in Unix can also  work effeciently with pthread threads i.e we can effeceintly make pthreads wait on a semaphore.
3)Procedural abstractions : The high level functions (sub -application) will only use wrapper functions instead of  accesing the ingradients of event structure directly.This will protect the implementation.

Interfaces that can help to implement wait functions.

The following  opcode values when passed to semctl() function  can be helpful to implement Wait Functions.

Wait on Single Object : There are four primitive operations
   
1)Non-blocking wait on a Manual event.
     
              Semaphore no       Command      Flag
                    0                          0                  NOWAIT
 
       .
  2) Blocking wait on a Manual event.
   
              Semaphore no       Command      Flag
                    0                          0                  WAIT
 
       
3)Non-blocking wait on a Automatic event.
 
              Semaphore no       Command      Flag
                    0                         0                  NOWAIT
                    1                         0                  NOWAIT
                    1                         1                  WAIT
                    0                         1                  WAIT
 
4) Blocking wait on a Manual evant.
 
              Semaphore no       Command      Flag
                    0                         0                  WAIT
                    1                         0                  NOWAIT
                    1                         1                  WAIT
                    0                         1                  WAIT


 








0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 3

Expert Comment

by:dhm
Comment Utility
Your proposal is almost 100% correct.  The only things I'd change are:

* Use "1" for a "signalled" event, "0" for "nonsignalled".  This way, you can use the semop() with an operation value of -1 in your WaitForSingleEvent() and WaitForMultipleEvents() routines.  If the Event is supposed to do automatic reset, then you don't have to do anything else after the semop() returns.

* The control lock (your "semaphore 2") should work like this: if the value is "1", then the Event is idle and you can run an operation on it (one of Set, Reset, or Wait).

Your SetEvent() function should do:

semop( sem_id, { 2, -1, 0 }, 1 );      // lock Control Lock
if (!semctl( sem_id, 1, GETVAL ))      // Set flag unless already set
      semop( sem_id, { 1, 1, 0 }, 1 );
semop( sem_id, { 2, 1, 0 }, 1 );      // Unlock Control Lock

The ResetEvent() function should do:

semop( sem_id, { 2, -1, 0 }, 1 );      // lock Control Lock
semctl( sem_id, 1, SETVAL, 0 );            // Clear the Event flag
semop( sem_id, { 2, 1, 0 }, 1 );      // Unlock Control Lock

PulseEvent() is harder; it's a good thing you don't need it! :-)

The procedure for WaitForSingleObject will wait for both the Control Lock and the Event Flag to be 1 (the semop() call for that will decrement both semaphores to 0).  When that call returns, the Event has been triggered so WaitForSingleObject should clean up and return.  The cleanup procedure is to check the Automatic/Manual flag, increment the Event Flag if it's supposed to be Manual Reset, and finally increment the Control Lock so that somebody else can use the Event.  The code will look like this:

semop( sem_id, { { 2, -1, 0 }, { 1, -1, 0 } }, 2 );
if (semctl( sem_id, 3, GETVAL ))
      semop( sem_id, { { 1, 1, 0 }, { 2, 1, 0 } }, 2 );
else
      semop( sem_id, { 2, 1, 0 }, 1 );

You can do WaitForMultipleObjects() as well, as long as all the objects you want to wait for are elements of the same semaphore array.  This suggests that your implementation may want to allocate a really big array of semaphores under the same sem_id, then use triples from that array to make each Event.

One thing you'll have to watch out for is that there's a kernel-parameter limitation on the number of semaphores in a set.  Usually the limit is around 16 or 32 or something, but you can always increase it by reconfiguring and/or recompiling the kernel.  If you decide to go with the big array of events and you don't have a *lot* of SetEvent() / ResetEvent() activity, you may be able to just use a single semaphore as the Control Flag for all the Events.  This will make contention for control of the Events more likely, but it'll save almost 33% in number of semaphores.  Another way to cut down the number of semaphores would be to just say that even-numbered semaphores are Automatic-Reset, and odd-numbered ones are Manual-Reset.  This might work for you if you need approximately equal numbers of each, and it also reduces the number of semop() calls you'll have to make in the Set/Reset/Wait calls.
0
 

Author Comment

by:unifolk
Comment Utility
Dear dhm,
My sincere thanks for all the valuable time you spared to help me.
Your comments are indeed very helpful to me.
Being a little more selfish ,I do not want to lose contact with you just now. I want some more help.
Actually I need to Emulate WaitforMultipleObjects for a set of  mixed type of IPC objects
as Windows does.I have created a raw design to handle the situation of  waiting on many IPC 's at same time without using BUSY WAIT loop.
I naturally wanted to
1)Avoid using Signals (Problem with Async nature..)
2)Increase time effeciency
So I am sending these ideas to you ,Please give your valuable comments regarding the
flaws & possible problems that can crop in this implementation.In this model I am still hunting for a solution to implement TIMEOUT  wait but again I do not want to use signals.
Please consider following points.
1)My Appplication will require 600-700 events at a time 1.e a total 1200 IPC objects.
2)I can even wait in Threads & Processes(Though I have not thought about that yet)
Please also tell me
3)I have used as a convention that all IPC will be implemented using semaphore sets with
semaphore 1 always the Value semaphore.
1)What are maximum no of semaphore sets that I can create
2)Should i use mmap() implementation or shared memory to keep the global data structures required in this design.

Sincere Regards,
----------------------------------------------------------------------------------------------------------------------------------


Design  for  IPC mechanism in Unix.


Data Structures to be maintained :

1)Named IPC table : This will store a lookup for all named IPC objects.i.e  Semaphores,Mutexes,Events & file Mappings.
The fields are :
1)Name of IPC object
2)Internal ID allocated by Unix probably by using ftok().
This table can be implemented as a linked list for memory optimization.
This will serve two purposes
· Will act as a lookup for all named IPC objects.
· Will help us to identify name clash as in Windows two different types of IPC objects can not have same name.

2)Thread Status table : This table will contain a pair  (ThreadId ,  TCE Id).The TCE(Thread Control Event) is an internal system event unique for each  process and will not be visible to  upper layers.This table can be implemented as an array if number of threads in the system at a time has very little variation with the average no of threads in the system.

3)Object Wait Table : This table will store a pair(IPC object id  , Pointer to wait list).The wait list will be a linked list containing  the Id's  of threads currently waiting for the particular object.
The Object Wait  table can be a linked list ,But if frequency of  wait operations on IPC object too high ,it can be implemented as a hash table or an array(If  resources  permit).

Having these as the base data structure now we can define some generic algorithms applicable to all IPC objects.

Algorithms for IPC operations

1.  Creation of Thread :  
1. Create a System Event (indicated by type =2 in third semaphore of the event structure),get a unique id.
2. Insert a pair (ThreadId,System Event Id) in the Thread Status Table.
3. Unsignal the System Event . ResetEvent(TCE)
2.  Creation of a general  IPC object(Any object on which one can wait) :
1. If  the Object is named object,
        Check for clash with name of any other object of different type.
        If clash then return error
Else if name  already  exist for same type of object then return its id.
        Else create an appropriate semaphore set ( set of 3 semaphores for Event,4 for
         Mutex...) & obtain  A unique id on it.Create a pair <Name,ID> and insert it in the Named
         IPC table.
2.    If object is Unnamed then create an appropriate semaphore set ( set of 3 semaphores for  
         Event,4 for Mutex...) & obtain  A unique id on it.
3. For both type of objects perform following operation :
· Perform initial level settings on the IPC object e.g If event to be created non-signalled ,perform reset operation.
· Insert the pair<Id,NULL> in the Object Wait Table.





3.    Signalling of  any IPC object :  

               When any object is signallled ,it will have to notify all its waiting processes to take action.
               So the IPC object will go to the Object wait table,traverse through the list of all  
               processes(Threads)  waiting on it & for each thread it will issue the following command.
                     SetEvent(System Event Id)  
              where System Event Id is id of  TCE of  the thread
               It will issue this command in a non-blocking mode.

Generic Wait on one ot set of  IPC's :

               When any thread issues the command
                Waitfor<x>Objects     where x=1 or many
               Then following operations are performed :

1. First check iteration : Get current  signalled status of all IPC objects in the list
(1-Signalled,0-Non-signalled) in an array   Si
If option is Wait for any then  Condition  C =S1 ||  S2 || ......
If option is Wait for all then    Condition C=S1 && S2 && S3....
If(C is TURE)  return to <Label 3> with  Id of  Left most Object in the Linear list of  Objects.

2. <Label 1>
Wait ( TCE of current thread)
Calculate C
If(C is TURE)  return  to <Label 2> with  Id of  Left most Object in the Linear list of  Objects.
Reset(TCE)
Go to <Label 1>

<Label 2>
for each IPC object in the list,
Go to Object -Wait Table.
Traverse the list of waiting processes
Remove node where node.Id value=Thread Id of current thread.
Reset(TCE)

3.          <Label 3)

Open IPC(Name) :
                  1.   Go to Named IPC Table.
                  2.    Search for entry where Node.name value=Name .
                          If search is successful then
                              return Node.id Value
                          else
                          return Error.

 Delete   IPC Object (id):
                   1.  Go to  Object Wait Table.
                   2.   If  Wait list is not null then  return Error
                   3.   If  a Named object first delete the pair<id,Name> from table.
                   4.   Delete the entry <id,LINK> entry from  Object Wait Table.





Delete Thread(Thread Id):
1. Traverse through the Object Wait Table .
2. For each node  Traverse Wait List,Delete all nodes where Node.Id Value=Thread Id .
3. Go to Thread Status table & delete entry <Thread Id,TCE id>
                 

                 







0
 
LVL 3

Expert Comment

by:dhm
Comment Utility
Hmmm, you have a much bigger project than I thought.  I'm doing something similar right now, and I've thought about extending it -- I'd like to write a compatibility layer that would allow NT programs to be run on Linux.  However, between the issues I've discovered and those you've brought up, I suspect that some kernel hacking will be necessary.

I don't have time to provide as much assistance as you'd like.  You should reject my answer and let the question go back into the open pool...maybe somebody else will be able to help more.

Sorry...and good luck!
0
 

Author Comment

by:unifolk
Comment Utility
Dear dhm,
Thanks for the help .
As you rightly guess,I am working on something similar.
I am closing this chapter here only,can understand the value of your time.
Even you are not able to comment on the things I send to you earlier,If time permits
please share some good findinds or ideas encountered during your project.
If you want any help from me(I feel you generally wouldn't as you are much senior than me) please mail to me.
Please feel free to guide this ever learning student.

rmittal@wipsys.soft.net

With Sincere Regards,
Rajesh

0
 
LVL 3

Expert Comment

by:dhm
Comment Utility
Rajesh-

You may want to look at the WINE project on Linux.  All I know about it is that they're trying to emulate Windows (I don't know which version -- 3.1, 95, or NT) and that they've had some success running native M$ binaries.  If they're trying to run 95 or NT binaries, then they will have figured out some way to handle WaitForMultipleObjects.  I've thought about it a little more, but I still don't see a good way to do it without rooting around in the kernel.
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
ASCII Non-Printable characters/codes and their HTML equivalents 6 94
has22 challenge 11 70
NotAlone Challenge 20 70
changeXy challenge 13 55
This is to be the first in a series of articles demonstrating the development of a complete windows based application using the MFC classes.  I’ll try to keep each article focused on one (or a couple) of the tasks that one may meet.   Introductio…
If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

728 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now