> On Wed, 25 Jul 2001 Terry Lambert wrote:
>>[EMAIL PROTECTED] wrote:
>>
>> I need pass asynchronously data from kernel
>> to a userland process, include a quantity variable of
>> data (void *opaque).
>The easiest way to do this is to have the user space process
>register a kevent, and then KNOTE() in the kernel when the
>event takes place.
Please, look the question at the bottom of this message.
>You can't; at least, you can't do exactly that. As others
>have pointed out, you would have better luck telling us what
>problem it is you are trying to solve, and then letting
>people suggest solutions, instead of picking "the one true
>solution", and then asking us how to implement it.
OK, I'm incorporating the Real Time Protocol RTP into the
FreeBSD Kernel.
I took the RTP Lucent Technologies Library that
provides a high level interface for
developing applications that make use of the
Real Time Transport Protocol (RTP) and I changed
many of the original API library functions
to kernel systems calls, and it works fine.
Here you look about the original library:
http://www-out.bell-labs.com/project/RTPlib/DOCS/rtp_api.hrml
Now, I need manage Timed Events:
Two RTP related events must occur which are timed. They are:
1.RTCP (control RTP packages) reports must be sent periodically.
2.BYE (a control RTP package) packets may be reconsidered for transmission.
To support scheduling, timed events are handled by two functions,
RTPSchedule() and RTPExecute().
The first of these functions is written by the user(user process).
It is called by the RTP kernel module (originally the library)
to request scheduling of events at some predetermined time.
The user is responsible for writing the function to schedule
the event with whatever mechanism is appropriate for the application.
The second function is part of the RTP kernel module (originally the
library),
and is to be called upon execution of the timed event.
The specific formats of the functions are:
void RTPSchedule(int id, void* opaque, struct timeval *tp);
rtperror RTPExecute(int id, void* opaque);
The RTP kernel module will call RTPSchedule, and pass it the context cid
and an opaque piece of data, opaque. It will also pass the time for
which the scheduled event is to occur, tp. At the appropriate time,
tp, the application should call RTPExecute, and pass it the opaque
token provided in the call to RTPSchedule, in addition to the identifier
id.
This general mechanism allows for the RTP kernel module to schedule
arbitrary
timed events. All information about the nature of the events is kept
internal. The opaque data is used internally to identify particular events.
For example the following simple code would implement
the RTP Scheduler in the userland process:
/* Maintain a simple queue of events. */
/* An element queue */
struct evt_queue_elt {
int id;
void* event_opaque;
double event_time;
struct evt_queue_elt *next;
};
/* A queue */
static struct evt_queue_elt* evt_queue = NULL;
/* An the kernel would call this RTPSchedule
function when it needs to schedule an event.
*/
void RTPSchedule(int id, void* opaque, struct timeval *tp)
{
struct evt_queue_elt *elt;
elt = (struct evt_queue_elt *) malloc(sizeof(struct evt_queue_elt));
if (elt == NULL)
return;
elt->id = id;
elt->event_opaque = opaque;
elt->event_time = tv2dbl(*tp);
insert_in_evt_queue(elt); /* Here insert element in queue */
return;
}
/* In other place of the user program ... */
struct evt_queue_elt *next;
gettimeofday(&now_tv, NULL);
now = tv2dbl(now_tv);
while (evt_queue != NULL && evt_queue->event_time <= now) {
/* There is a pending RTP event (currently this means there's
* an RTCP packet to send), so run it. */
RTPExecute(evt_queue->id, evt_queue->event_opaque);
/* Advance the queue */
next = evt_queue->next;
free(evt_queue);
evt_queue = next;
}
/* ----- RTP systemcall RTPExecute() BEGIN ----- */
#ifndef _SYS_SYSPROTO_H_
struct RTPExecute_args {
int id ;
void* opaque ;
};
#endif
rtperror RTPExecute (p,uap)
struct proc *p;
register struct RTPExecute_args *uap;
{
int id ;
void* opaque ;
int rtp_error;
int rtp_retorno;
cid = uap->cid ;
rtp_error = copyin( uap->opaque , opaque, sizeof( opaque ));
if (rtp_error != RTP_OK )
goto copyin_out;
/* internal kernel work */
rtp_retorno = the_RTPExecute_rtp_internal(id, opaque);
rtp_error = copyout( opaque , uap->opaque , sizeof( opaque ));
if (rtp_error != RTP_OK )
goto copyout_out;
printf("RTPExecute--> Return: %d \n", rtp_retorno );
p->p_retval[0] = rtp_retorno;
return rtp_retorno;
copyin_out:
printf("RTPExecute--> Error at copyin()\n");
goto bailout;
copyout_out:
printf("RTPExecute--> Error at copyout()\n");
bailout:
p->p_retval[0] = rtp_error;
return rtp_error;
}
/* ----- RTP systemcall RTPExecute() END ----- */
Other internal functions into the kernel like to
"the_RTPExecute_rtp_internal()" needs to call
to RTPSchedule() userland function.
So, my original question was:
Into my kernel code, How I can call to
RTPSchedule() userland function?
You say me that I can do with kevent() facility.
How I can do it exactly?
I apologize perhaps the following is stupid,
but from the user process I can call kevent()
for a file descriptor and into kernel when I need
call to RTPSchedule() instead I would try for example to write
to file descriptor to trigger the event.
Can I do this?
I don't sure but into kernel it can't write
to file descriptor.
Thanks for your help.
+------------------------------+
YONNY CARDENAS B.
Systems Engineer
Student M.Sc.
UNIVERSIDAD DE LOS ANDES
+-------------------------------+
UNIX is BSD, and FreeBSD is an advanced 4.4BSD
To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message