From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 4901 invoked by alias); 15 Mar 2004 21:18:26 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 4869 invoked from network); 15 Mar 2004 21:18:24 -0000 Received: from unknown (HELO localhost.redhat.com) (66.30.197.194) by sources.redhat.com with SMTP; 15 Mar 2004 21:18:24 -0000 Received: from gnu.org (localhost [127.0.0.1]) by localhost.redhat.com (Postfix) with ESMTP id 5E0422B92; Mon, 15 Mar 2004 16:18:24 -0500 (EST) Message-ID: <40561DA0.9040106@gnu.org> Date: Fri, 19 Mar 2004 00:09:00 -0000 From: Andrew Cagney User-Agent: Mozilla/5.0 (X11; U; NetBSD macppc; en-GB; rv:1.4.1) Gecko/20040217 MIME-Version: 1.0 To: Andrew Cagney , Eli Zaretskii Cc: gdb-patches@sources.redhat.com, kettenis@chello.nl Subject: Re: [patch/rfc] Separate gdbarch_data_register_pre_init References: <404CC940.70805@gnu.org> <4055E603.3040904@gnu.org> <9003-Mon15Mar2004215253+0200-eliz@elta.co.il> <40561C75.5000908@gnu.org> In-Reply-To: <40561C75.5000908@gnu.org> Content-Type: multipart/mixed; boundary="------------070005080700030607020702" X-SW-Source: 2004-03/txt/msg00336.txt.bz2 This is a multi-part message in MIME format. --------------070005080700030607020702 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Content-length: 1858 [hopefully with the correct patch] >>> Date: Mon, 15 Mar 2004 12:21:07 -0500 >>> From: Andrew Cagney >>> >>> How does the doco part of this change look? > > > > Looks okay to me, except for the following small gotchas: > > >>> ! @var{post_init} is used to obtain an initial value for a >>> ! per-architecture data-pointer @emph{after}. Since @var{post_init} is >>> ! always called after architecture creation, it both receives the fully >>> ! initialized architecture and is free to call modules that use >>> ! per-architecture data (care should be taken to avoid cycles in the >>> ! call graph). >>> ! @end deftypefun > > > > This sounds like important notes, but they are worded too vaguely, > IMHO. A question that popped up in my mind when I read that was: what > cycles should I avoid in the call graph, and how? > > Perhaps an example would help drive these points home. I've tried to make the problem more explict. >>> ! current value of the per-architecture data-pointer. If the data >>> ! pointer is @code{NULL}, it is first initialize by calling the > > > ^^^^^^^^^^^^^^^^^^^^^^ > A typo: it should be "initialized". yes. >>> ! The examples below assuming the following definitions: > > > ^^^^^^^^ > "The examples ... assume ..." yes >>> ! A module can extend the architecture vector, adding additional >>> ! per-architecture attributes, using the @var{pre_init} method. These >>> ! attribute being set by the architecture's @var{gdbarch_init} method >>> ! during architecture creation. > > > > "These attributes are set by the architecture's @var{gdbarch_init} > method ...". > > Btw, what ``attributes'' are those? The text doesn't explain that. I've re-worded it so that it doesn't use "attribute". ok? Andrew --------------070005080700030607020702 Content-Type: text/plain; name="diffs" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="diffs" Content-length: 8645 2004-03-15 Andrew Cagney * gdbint.texinfo (Coding): Update section on gdbarch_data, describe pre_init and post_init. Index: gdbint.texinfo =================================================================== RCS file: /cvs/src/src/gdb/doc/gdbint.texinfo,v retrieving revision 1.190 diff -c -r1.190 gdbint.texinfo *** gdbint.texinfo 26 Feb 2004 20:52:08 -0000 1.190 --- gdbint.texinfo 15 Mar 2004 21:11:49 -0000 *************** *** 4872,5004 **** @cindex multi-arch data @cindex data-pointer, per-architecture/per-module ! The multi-arch framework includes a mechanism for adding module specific ! per-architecture data-pointers to the @code{struct gdbarch} architecture ! object. ! ! A module registers one or more per-architecture data-pointers using the ! function @code{register_gdbarch_data}: ! ! @deftypefun struct gdbarch_data *register_gdbarch_data (gdbarch_data_init_ftype *@var{init}) ! ! The @var{init} function is used to obtain an initial value for a ! per-architecture data-pointer. The function is called, after the ! architecture has been created, when the data-pointer is still ! uninitialized (@code{NULL}) and its value has been requested via a call ! to @code{gdbarch_data}. A data-pointer can also be initialize ! explicitly using @code{set_gdbarch_data}. ! ! Any memory required by the @var{init} function should be allocated ! using @code{GDBARCH_OBSTACK_ZALLOC}. That memory is automatically ! released when the corresponding architecture is deleted. ! ! The function @code{register_gdbarch_data} returns a @code{struct ! gdbarch_data} that is used to identify the data-pointer that was added ! to the module. ! @end deftypefun ! A typical module has an @code{init} function of the form: ! ! @smallexample ! struct nozel @{ int total; @}; ! static struct gdbarch_data *nozel_handle; ! static void * ! nozel_init (struct gdbarch *gdbarch) ! @{ ! struct nozel *data = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct nozel); ! @dots{} ! return data; ! @} ! @end smallexample ! ! Since uninitialized (@code{NULL}) data-pointers are initialized ! on-demand, an @code{init} function is free to call other modules that ! use data-pointers. Those modules data-pointers will be initialized as ! needed. Care should be taken to ensure that the @code{init} call graph ! does not contain cycles. ! ! The data-pointer is registered with the call: ! @smallexample ! void ! _initialize_nozel (void) ! @{ ! nozel_handle = register_gdbarch_data (nozel_init); ! @dots{} ! @end smallexample The per-architecture data-pointer is accessed using the function: @deftypefun void *gdbarch_data (struct gdbarch *@var{gdbarch}, struct gdbarch_data *@var{data_handle}) Given the architecture @var{arch} and module data handle ! @var{data_handle} (returned by @code{register_gdbarch_data}, this ! function returns the current value of the per-architecture data-pointer. @end deftypefun ! The non-@code{NULL} data-pointer returned by @code{gdbarch_data} should ! be saved in a local variable and then used directly: @smallexample ! int ! nozel_total (struct gdbarch *gdbarch) ! @{ ! int total; ! struct nozel *data = gdbarch_data (gdbarch, nozel_handle); ! @dots{} ! return total; ! @} @end smallexample ! It is also possible to directly initialize the data-pointer using: ! ! @deftypefun void set_gdbarch_data (struct gdbarch *@var{gdbarch}, struct gdbarch_data *@var{handle}, void *@var{pointer}) ! Set the still @code{NULL} data-pointer corresponding to @var{handle} ! to the non-@code{NULL} @var{pointer} value. ! @end deftypefun ! ! This function is used by modules that require a mechanism for explicitly ! setting the per-architecture data-pointer during architecture creation: @smallexample ! /* Always return a non-NULL nozel. */ ! static struct nozel * ! gdbarch_nozel (struct gdbarch *gdbarch) @{ ! struct nozel *nozel = gdbarch_data (gdbarch, nozel_handle); ! if (nozel == NULL) ! @{ ! nozel = nozel_init (gdbarch); ! set_gdbarch_data (gdbarch, nozel_handle, nozel); ! @} ! return nozel; @} @end smallexample @smallexample - /* Called during architecture creation. */ extern void set_gdbarch_nozel (struct gdbarch *gdbarch, int total) @{ ! struct nozel *data = gdbarch_nozel (gdbarch); ! @dots{} ! data->total = total; @} @end smallexample @smallexample ! void ! _initialize_nozel (void) @{ ! nozel_handle = register_gdbarch_data (nozel_init); ! @dots{} @end smallexample ! @noindent ! Note that an @code{init} function still needs to be registered. It is ! used to initialize the data-pointer when the architecture creation phase ! fail to set an initial value. ! @section Wrapping Output Lines @cindex line wrap in output --- 4872,4974 ---- @cindex multi-arch data @cindex data-pointer, per-architecture/per-module ! The multi-arch framework includes a mechanism for adding module ! specific per-architecture data-pointers to the @code{struct gdbarch} ! architecture object. ! ! A module registers one or more per-architecture data-pointers using: ! ! @deftypefun struct gdbarch_data *gdbarch_data_register_pre_init (gdbarch_data_pre_init_ftype *@var{pre_init}) ! @var{pre_init} is used to, on-demand, allocate an initial value for a ! per-architecture data-pointer using the architecture's obstack (passed ! in as a parameter). Since @var{pre_init} can be called during ! architecture creation, it is not parameterized with the architecture. ! and must not call modules that use per-architecture data. @end deftypefun ! @deftypefun struct gdbarch_data *gdbarch_data_register_post_init (gdbarch_data_post_init_ftype *@var{post_init}) ! @var{post_init} is used to obtain an initial value for a ! per-architecture data-pointer @emph{after}. Since @var{post_init} is ! always called after architecture creation, it both receives the fully ! initialized architecture and is free to call modules that use ! per-architecture data (care needs to be taken to ensure that those ! other modules do not try to call back to this module as that will ! create in cycles in the initialization call graph). ! @end deftypefun ! These functions return a @code{struct gdbarch_data} that is used to ! identify the per-architecture data-pointer added for that module. The per-architecture data-pointer is accessed using the function: @deftypefun void *gdbarch_data (struct gdbarch *@var{gdbarch}, struct gdbarch_data *@var{data_handle}) Given the architecture @var{arch} and module data handle ! @var{data_handle} (returned by @code{gdbarch_data_register_pre_init} ! or @code{gdbarch_data_register_post_init}), this function returns the ! current value of the per-architecture data-pointer. If the data ! pointer is @code{NULL}, it is first initialized by calling the ! corresponding @var{pre_init} or @var{post_init} method. @end deftypefun ! The examples below assume the following definitions: @smallexample ! struct nozel @{ int total; @}; ! static struct gdbarch_data *nozel_handle; @end smallexample ! A module can extend the architecture vector, adding additional ! per-architecture data, using the @var{pre_init} method. The module's ! per-architecture data is then initialized during architecture ! creation. ! ! In the below, the module's per-architecture @emph{nozel} is added. An ! architecture can specify its nozel by calling @code{set_gdbarch_nozel} ! from @code{gdbarch_init}. @smallexample ! static void * ! nozel_pre_init (struct obstack *obstack) @{ ! struct nozel *data = OBSTACK_ZALLOC (obstack, struct nozel); ! return data; @} @end smallexample @smallexample extern void set_gdbarch_nozel (struct gdbarch *gdbarch, int total) @{ ! struct nozel *data = gdbarch_data (gdbarch, nozel_handle); ! data->total = nozel; @} @end smallexample + A module can on-demand create architecture dependant data structures + using @code{post_init}. + + In the below, the nozel's total is computed on-demand by + @code{nozel_post_init} using information obtained from the + architecture. + @smallexample ! static void * ! nozel_post_init (struct gdbarch *gdbarch) @{ ! struct nozel *data = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct nozel); ! nozel->total = gdbarch@dots{} (gdbarch); ! return data; ! @} @end smallexample ! @smallexample ! extern int ! nozel_total (struct gdbarch *gdbarch) ! @{ ! struct nozel *data = gdbarch_data (gdbarch, nozel_handle); ! return data->total; ! @} ! @end smallexample @section Wrapping Output Lines @cindex line wrap in output --------------070005080700030607020702-- From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 4901 invoked by alias); 15 Mar 2004 21:18:26 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 4869 invoked from network); 15 Mar 2004 21:18:24 -0000 Received: from unknown (HELO localhost.redhat.com) (66.30.197.194) by sources.redhat.com with SMTP; 15 Mar 2004 21:18:24 -0000 Received: from gnu.org (localhost [127.0.0.1]) by localhost.redhat.com (Postfix) with ESMTP id 5E0422B92; Mon, 15 Mar 2004 16:18:24 -0500 (EST) Message-ID: <40561DA0.9040106@gnu.org> Date: Mon, 15 Mar 2004 21:18:00 -0000 From: Andrew Cagney User-Agent: Mozilla/5.0 (X11; U; NetBSD macppc; en-GB; rv:1.4.1) Gecko/20040217 MIME-Version: 1.0 To: Andrew Cagney , Eli Zaretskii Cc: gdb-patches@sources.redhat.com, kettenis@chello.nl Subject: Re: [patch/rfc] Separate gdbarch_data_register_pre_init References: <404CC940.70805@gnu.org> <4055E603.3040904@gnu.org> <9003-Mon15Mar2004215253+0200-eliz@elta.co.il> <40561C75.5000908@gnu.org> In-Reply-To: <40561C75.5000908@gnu.org> Content-Type: multipart/mixed; boundary="------------070005080700030607020702" X-SW-Source: 2004-03.o/txt/msg00336.txt Message-ID: <20040315211800.VJ3Ek8PTAAc3IYvuHmXPZbg7sH_XBq9SbQTBqDsnkzc@z> This is a multi-part message in MIME format. --------------070005080700030607020702 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Content-length: 1858 [hopefully with the correct patch] >>> Date: Mon, 15 Mar 2004 12:21:07 -0500 >>> From: Andrew Cagney >>> >>> How does the doco part of this change look? > > > > Looks okay to me, except for the following small gotchas: > > >>> ! @var{post_init} is used to obtain an initial value for a >>> ! per-architecture data-pointer @emph{after}. Since @var{post_init} is >>> ! always called after architecture creation, it both receives the fully >>> ! initialized architecture and is free to call modules that use >>> ! per-architecture data (care should be taken to avoid cycles in the >>> ! call graph). >>> ! @end deftypefun > > > > This sounds like important notes, but they are worded too vaguely, > IMHO. A question that popped up in my mind when I read that was: what > cycles should I avoid in the call graph, and how? > > Perhaps an example would help drive these points home. I've tried to make the problem more explict. >>> ! current value of the per-architecture data-pointer. If the data >>> ! pointer is @code{NULL}, it is first initialize by calling the > > > ^^^^^^^^^^^^^^^^^^^^^^ > A typo: it should be "initialized". yes. >>> ! The examples below assuming the following definitions: > > > ^^^^^^^^ > "The examples ... assume ..." yes >>> ! A module can extend the architecture vector, adding additional >>> ! per-architecture attributes, using the @var{pre_init} method. These >>> ! attribute being set by the architecture's @var{gdbarch_init} method >>> ! during architecture creation. > > > > "These attributes are set by the architecture's @var{gdbarch_init} > method ...". > > Btw, what ``attributes'' are those? The text doesn't explain that. I've re-worded it so that it doesn't use "attribute". ok? Andrew --------------070005080700030607020702 Content-Type: text/plain; name="diffs" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="diffs" Content-length: 8645 2004-03-15 Andrew Cagney * gdbint.texinfo (Coding): Update section on gdbarch_data, describe pre_init and post_init. Index: gdbint.texinfo =================================================================== RCS file: /cvs/src/src/gdb/doc/gdbint.texinfo,v retrieving revision 1.190 diff -c -r1.190 gdbint.texinfo *** gdbint.texinfo 26 Feb 2004 20:52:08 -0000 1.190 --- gdbint.texinfo 15 Mar 2004 21:11:49 -0000 *************** *** 4872,5004 **** @cindex multi-arch data @cindex data-pointer, per-architecture/per-module ! The multi-arch framework includes a mechanism for adding module specific ! per-architecture data-pointers to the @code{struct gdbarch} architecture ! object. ! ! A module registers one or more per-architecture data-pointers using the ! function @code{register_gdbarch_data}: ! ! @deftypefun struct gdbarch_data *register_gdbarch_data (gdbarch_data_init_ftype *@var{init}) ! ! The @var{init} function is used to obtain an initial value for a ! per-architecture data-pointer. The function is called, after the ! architecture has been created, when the data-pointer is still ! uninitialized (@code{NULL}) and its value has been requested via a call ! to @code{gdbarch_data}. A data-pointer can also be initialize ! explicitly using @code{set_gdbarch_data}. ! ! Any memory required by the @var{init} function should be allocated ! using @code{GDBARCH_OBSTACK_ZALLOC}. That memory is automatically ! released when the corresponding architecture is deleted. ! ! The function @code{register_gdbarch_data} returns a @code{struct ! gdbarch_data} that is used to identify the data-pointer that was added ! to the module. ! @end deftypefun ! A typical module has an @code{init} function of the form: ! ! @smallexample ! struct nozel @{ int total; @}; ! static struct gdbarch_data *nozel_handle; ! static void * ! nozel_init (struct gdbarch *gdbarch) ! @{ ! struct nozel *data = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct nozel); ! @dots{} ! return data; ! @} ! @end smallexample ! ! Since uninitialized (@code{NULL}) data-pointers are initialized ! on-demand, an @code{init} function is free to call other modules that ! use data-pointers. Those modules data-pointers will be initialized as ! needed. Care should be taken to ensure that the @code{init} call graph ! does not contain cycles. ! ! The data-pointer is registered with the call: ! @smallexample ! void ! _initialize_nozel (void) ! @{ ! nozel_handle = register_gdbarch_data (nozel_init); ! @dots{} ! @end smallexample The per-architecture data-pointer is accessed using the function: @deftypefun void *gdbarch_data (struct gdbarch *@var{gdbarch}, struct gdbarch_data *@var{data_handle}) Given the architecture @var{arch} and module data handle ! @var{data_handle} (returned by @code{register_gdbarch_data}, this ! function returns the current value of the per-architecture data-pointer. @end deftypefun ! The non-@code{NULL} data-pointer returned by @code{gdbarch_data} should ! be saved in a local variable and then used directly: @smallexample ! int ! nozel_total (struct gdbarch *gdbarch) ! @{ ! int total; ! struct nozel *data = gdbarch_data (gdbarch, nozel_handle); ! @dots{} ! return total; ! @} @end smallexample ! It is also possible to directly initialize the data-pointer using: ! ! @deftypefun void set_gdbarch_data (struct gdbarch *@var{gdbarch}, struct gdbarch_data *@var{handle}, void *@var{pointer}) ! Set the still @code{NULL} data-pointer corresponding to @var{handle} ! to the non-@code{NULL} @var{pointer} value. ! @end deftypefun ! ! This function is used by modules that require a mechanism for explicitly ! setting the per-architecture data-pointer during architecture creation: @smallexample ! /* Always return a non-NULL nozel. */ ! static struct nozel * ! gdbarch_nozel (struct gdbarch *gdbarch) @{ ! struct nozel *nozel = gdbarch_data (gdbarch, nozel_handle); ! if (nozel == NULL) ! @{ ! nozel = nozel_init (gdbarch); ! set_gdbarch_data (gdbarch, nozel_handle, nozel); ! @} ! return nozel; @} @end smallexample @smallexample - /* Called during architecture creation. */ extern void set_gdbarch_nozel (struct gdbarch *gdbarch, int total) @{ ! struct nozel *data = gdbarch_nozel (gdbarch); ! @dots{} ! data->total = total; @} @end smallexample @smallexample ! void ! _initialize_nozel (void) @{ ! nozel_handle = register_gdbarch_data (nozel_init); ! @dots{} @end smallexample ! @noindent ! Note that an @code{init} function still needs to be registered. It is ! used to initialize the data-pointer when the architecture creation phase ! fail to set an initial value. ! @section Wrapping Output Lines @cindex line wrap in output --- 4872,4974 ---- @cindex multi-arch data @cindex data-pointer, per-architecture/per-module ! The multi-arch framework includes a mechanism for adding module ! specific per-architecture data-pointers to the @code{struct gdbarch} ! architecture object. ! ! A module registers one or more per-architecture data-pointers using: ! ! @deftypefun struct gdbarch_data *gdbarch_data_register_pre_init (gdbarch_data_pre_init_ftype *@var{pre_init}) ! @var{pre_init} is used to, on-demand, allocate an initial value for a ! per-architecture data-pointer using the architecture's obstack (passed ! in as a parameter). Since @var{pre_init} can be called during ! architecture creation, it is not parameterized with the architecture. ! and must not call modules that use per-architecture data. @end deftypefun ! @deftypefun struct gdbarch_data *gdbarch_data_register_post_init (gdbarch_data_post_init_ftype *@var{post_init}) ! @var{post_init} is used to obtain an initial value for a ! per-architecture data-pointer @emph{after}. Since @var{post_init} is ! always called after architecture creation, it both receives the fully ! initialized architecture and is free to call modules that use ! per-architecture data (care needs to be taken to ensure that those ! other modules do not try to call back to this module as that will ! create in cycles in the initialization call graph). ! @end deftypefun ! These functions return a @code{struct gdbarch_data} that is used to ! identify the per-architecture data-pointer added for that module. The per-architecture data-pointer is accessed using the function: @deftypefun void *gdbarch_data (struct gdbarch *@var{gdbarch}, struct gdbarch_data *@var{data_handle}) Given the architecture @var{arch} and module data handle ! @var{data_handle} (returned by @code{gdbarch_data_register_pre_init} ! or @code{gdbarch_data_register_post_init}), this function returns the ! current value of the per-architecture data-pointer. If the data ! pointer is @code{NULL}, it is first initialized by calling the ! corresponding @var{pre_init} or @var{post_init} method. @end deftypefun ! The examples below assume the following definitions: @smallexample ! struct nozel @{ int total; @}; ! static struct gdbarch_data *nozel_handle; @end smallexample ! A module can extend the architecture vector, adding additional ! per-architecture data, using the @var{pre_init} method. The module's ! per-architecture data is then initialized during architecture ! creation. ! ! In the below, the module's per-architecture @emph{nozel} is added. An ! architecture can specify its nozel by calling @code{set_gdbarch_nozel} ! from @code{gdbarch_init}. @smallexample ! static void * ! nozel_pre_init (struct obstack *obstack) @{ ! struct nozel *data = OBSTACK_ZALLOC (obstack, struct nozel); ! return data; @} @end smallexample @smallexample extern void set_gdbarch_nozel (struct gdbarch *gdbarch, int total) @{ ! struct nozel *data = gdbarch_data (gdbarch, nozel_handle); ! data->total = nozel; @} @end smallexample + A module can on-demand create architecture dependant data structures + using @code{post_init}. + + In the below, the nozel's total is computed on-demand by + @code{nozel_post_init} using information obtained from the + architecture. + @smallexample ! static void * ! nozel_post_init (struct gdbarch *gdbarch) @{ ! struct nozel *data = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct nozel); ! nozel->total = gdbarch@dots{} (gdbarch); ! return data; ! @} @end smallexample ! @smallexample ! extern int ! nozel_total (struct gdbarch *gdbarch) ! @{ ! struct nozel *data = gdbarch_data (gdbarch, nozel_handle); ! return data->total; ! @} ! @end smallexample @section Wrapping Output Lines @cindex line wrap in output --------------070005080700030607020702--