From owner-freebsd-hackers Thu Jul 26 15: 4:51 2001 Delivered-To: freebsd-hackers@freebsd.org Received: from vaca.uniandes.edu.co (vaca.uniandes.edu.co [157.253.54.5]) by hub.freebsd.org (Postfix) with ESMTP id 5585D37B403 for ; Thu, 26 Jul 2001 15:04:35 -0700 (PDT) (envelope-from y-carden@uniandes.edu.co) Received: from vaca.uniandes.edu.co (localhost [127.0.0.1]) by vaca.uniandes.edu.co (8.12.0.Beta7/8.12.0.Beta7) with SMTP id f6QM4QTk020753 for ; Thu, 26 Jul 2001 17:04:28 -0500 (GMT+5) Received: (from webmail [157.253.54.4]) by vaca.uniandes.edu.co (NAVGW 2.5 bld 90) with SMTP id M2001072617042629945 for ; Thu, 26 Jul 2001 17:04:26 -0500 From: y-carden@uniandes.edu.co To: hackers@FreeBSD.ORG Subject: Re: Invoking a userland function from kernel X-Mailer: Netscape Messenger Express 3.5.2 [Mozilla/4.0 (compatible; MSIE 5.01; Windows NT)] Date: Thu, 26 Jul 2001 17:04:26 -0500 Message-Id: Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG > On Wed, 25 Jul 2001 Terry Lambert wrote: >>y-carden@uniandes.edu.co 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 majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message