Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > How to name a function to indicate that they require calling from acritical section?

Reply
Thread Tools

How to name a function to indicate that they require calling from acritical section?

 
 
celephicus@gmail.com
Guest
Posts: n/a
 
      08-09-2012
Good programmers know about critical sections, which protect shared resources. Good programmers use descriptive names. I just spent a day tracking down a real-time bug due to me calling a function outside a critical section.

How would you name a function to indicate that it should only be called from within a critical section? Something like doStuff_critical() with the "_critical" telling you the requirement for a critical section. But of course less ugly.

Any ideas?
 
Reply With Quote
 
 
 
 
Eric Sosman
Guest
Posts: n/a
 
      08-09-2012
On 8/8/2012 9:55 PM, http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> Good programmers know about critical sections, which protect shared resources. Good programmers use descriptive names. I just spent a day tracking down a real-time bug due to me calling a function outside a critical section.
>
> How would you name a function to indicate that it should only be called from within a critical section? Something like doStuff_critical() with the "_critical" telling you the requirement for a critical section. But of course less ugly.
>
> Any ideas?


Idea: Pthreads uses names like fputc_unlocked() for a similar
purpose, and you might imitate that. I don't think the ugliness
of such names should be much of a barrier; you *want* them to jump
out and be difficult to overlook -- even difficult to type, if the
functions should only be called in unusual circumstances.

But could you do better by reorganizing the program a bit?
By that I mean: In many cases, an "uncritical" piece of the program
calls a function that "goes critical" (acquires a lock, whatever),
does its job, restores normal mode, and returns to the caller, with
its work done and no longer "critical." If the function's work is
complex enough to be broken down into sub-functions, consider making
those subordinate functions `static' so outsiders cannot call them
directly but can only get at them through the "safe" API.

--
Eric Sosman
(E-Mail Removed)d
 
Reply With Quote
 
 
 
 
Andrew Cooper
Guest
Posts: n/a
 
      08-09-2012
On 09/08/2012 02:55, (E-Mail Removed) wrote:
> Good programmers know about critical sections, which protect shared resources. Good programmers use descriptive names. I just spent a day tracking down a real-time bug due to me calling a function outside a critical section.
>
> How would you name a function to indicate that it should only be called from within a critical section? Something like doStuff_critical() with the "_critical" telling you the requirement for a critical section. But of course less ugly.
>
> Any ideas?
>


By and large, Linux and Xen tend to use foo() and __foo(), where __foo()
is the actual implementation, with assumptions about locks etc in the
comments, and foo() is a wrapper which takes the correct lock(s), irq
states etc.

As a result, non-critical sections can call foo() and bar(), while a
larger complicated critical section can take the relevant locks and call
the required __foo() and __bar() functions.

(Although it should be noted that kernel critical sections will probably
differ widely from application level critical sections)

~Andrew
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      08-09-2012
Andrew Cooper <(E-Mail Removed)> writes:
> On 09/08/2012 02:55, (E-Mail Removed) wrote:
>> Good programmers know about critical sections, which protect shared
>> resources. Good programmers use descriptive names. I just spent a day
>> tracking down a real-time bug due to me calling a function outside a
>> critical section.
>>
>> How would you name a function to indicate that it should only be
>> called from within a critical section? Something like
>> doStuff_critical() with the "_critical" telling you the requirement
>> for a critical section. But of course less ugly.

>
> By and large, Linux and Xen tend to use foo() and __foo(), where __foo()
> is the actual implementation, with assumptions about locks etc in the
> comments, and foo() is a wrapper which takes the correct lock(s), irq
> states etc.
>
> As a result, non-critical sections can call foo() and bar(), while a
> larger complicated critical section can take the relevant locks and call
> the required __foo() and __bar() functions.
>
> (Although it should be noted that kernel critical sections will probably
> differ widely from application level critical sections)


Identifiers starting with two underscores, or with an underscore and an
uppercase letter, are reserved to the implementation; if you define such
an identifer yourself, the behavior is undefined.

(The kernel is arguably part of the implementation, and even if it
isn't, it's probably ok for the developers to rely on certain behaviors
that aren't defined by the language standard.)

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      08-09-2012
"China Blue [Tor], Meersburg" <(E-Mail Removed)> writes:
> In article <(E-Mail Removed)>,
> (E-Mail Removed) wrote:
>
>> Good programmers know about critical sections, which protect shared
>> resources. Good programmers use descriptive names. I just spent a day
>> tracking down a real-time bug due to me calling a function outside a
>> critical section.
>>
>> How would you name a function to indicate that it should only be
>> called from within a critical section? Something like
>> doStuff_critical() with the "_critical" telling you the requirement
>> for a critical section. But of course less ugly.
>>
>> Any ideas?

>
> zephodBeebleBrox_function


How does appending "_function" to the name suggest critical sections? Or
did you mean something else?

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Andrew Cooper
Guest
Posts: n/a
 
      08-09-2012
On 09/08/2012 21:58, Keith Thompson wrote:
> Andrew Cooper <(E-Mail Removed)> writes:
>> On 09/08/2012 02:55, (E-Mail Removed) wrote:
>>> Good programmers know about critical sections, which protect shared
>>> resources. Good programmers use descriptive names. I just spent a day
>>> tracking down a real-time bug due to me calling a function outside a
>>> critical section.
>>>
>>> How would you name a function to indicate that it should only be
>>> called from within a critical section? Something like
>>> doStuff_critical() with the "_critical" telling you the requirement
>>> for a critical section. But of course less ugly.

>>
>> By and large, Linux and Xen tend to use foo() and __foo(), where __foo()
>> is the actual implementation, with assumptions about locks etc in the
>> comments, and foo() is a wrapper which takes the correct lock(s), irq
>> states etc.
>>
>> As a result, non-critical sections can call foo() and bar(), while a
>> larger complicated critical section can take the relevant locks and call
>> the required __foo() and __bar() functions.
>>
>> (Although it should be noted that kernel critical sections will probably
>> differ widely from application level critical sections)

>
> Identifiers starting with two underscores, or with an underscore and an
> uppercase letter, are reserved to the implementation; if you define such
> an identifer yourself, the behavior is undefined.
>
> (The kernel is arguably part of the implementation, and even if it
> isn't, it's probably ok for the developers to rely on certain behaviors
> that aren't defined by the language standard.)
>


I doubt anyone could make a functional kernel while strictly adhering to
non UD behaviour. There is "what the standard states" and "what
basically universally works".

Having said that, because of narrow architecture targets of kernels, you
can perhaps rely substantially more on "what will work" while strictly
being UD.

~Andrew (who had never really pondered this before)
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      08-09-2012
On 8/9/2012 6:11 PM, Andrew Cooper wrote:
> On 09/08/2012 21:58, Keith Thompson wrote:
>> [...]
>> Identifiers starting with two underscores, or with an underscore and an
>> uppercase letter, are reserved to the implementation; if you define such
>> an identifer yourself, the behavior is undefined.
>>
>> (The kernel is arguably part of the implementation, and even if it
>> isn't, it's probably ok for the developers to rely on certain behaviors
>> that aren't defined by the language standard.)
>>

>
> I doubt anyone could make a functional kernel while strictly adhering to
> non UD behaviour. There is "what the standard states" and "what
> basically universally works".


If you hadn't said "universally" I'd have agreed with you,
more or less. But it is *not* universally true that you're
free to start your identifiers with __ and have things "work."
Even if you can get away with the particular set of __xxx you
use today with the particular compiler and options you use today,
you may find yourself in trouble tomorrow when you upgrade to the
next compiler version or invent a new identifier or even #include
a new header.

Example: Try this in gcc:

#include <stdio.h>
static const char *whom(void) {
return "World";
}
int main(void) {
printf("Hello, %s!\n", whom());
}

Everything working? Okay, now change the identifier `whom' to
`__attribute__'.


> Having said that, because of narrow architecture targets of kernels, you
> can perhaps rely substantially more on "what will work" while strictly
> being UD.


Agreed that you can -- indeed, must -- rely on a lot of things
the C language itself does not guarantee. But adopting a dubious
naming convention (when there are plenty of others available) is
begging for trouble just for the thrill of begging.

--
Eric Sosman
(E-Mail Removed)d
 
Reply With Quote
 
Tim Rentsch
Guest
Posts: n/a
 
      09-07-2012
Keith Thompson <(E-Mail Removed)> writes:

> Andrew Cooper <(E-Mail Removed)> writes:

[snip]
>> By and large, Linux and Xen tend to use foo() and __foo(), where __foo()
>> is the actual implementation, [snip]

>
> Identifiers starting with two underscores, or with an underscore and an
> uppercase letter, are reserved to the implementation; if you define such
> an identifer yourself, the behavior is undefined.
>
> (The kernel is arguably part of the implementation, and even if it
> isn't, it's probably ok for the developers to rely on certain behaviors
> that aren't defined by the language standard.)


The Linux kernel is part of no existing C implementation. And,
even if it were, it is not part of implementations running on
other operating systems (eg MS windows or MacOS), yet presumably
it's expected to be compileable some such environments, so it's
still breaking the rules regarding reserved identifiers.

Don't get me wrong, it's no big deal that these particular
rules are being broken in this case, but that doesn't mean
the rules aren't being broken.
 
Reply With Quote
 
Stephen Sprunk
Guest
Posts: n/a
 
      09-07-2012
On 07-Sep-12 10:37, Tim Rentsch wrote:
> Keith Thompson <(E-Mail Removed)> writes:
>> (The kernel is arguably part of the implementation, and even if it
>> isn't, it's probably ok for the developers to rely on certain
>> behaviors that aren't defined by the language standard.)

>
> The Linux kernel is part of no existing C implementation.


The _running_ kernel is arguably part of the implementation; the kernel
_source being compiled_ is not.

> And, even if it were, it is not part of implementations running on other
> operating systems (eg MS windows or MacOS), yet presumably it's expected
> to be compileable some such environments, so it's still breaking the
> rules regarding reserved identifiers.


The Linux kernel is only expected to be compilable by GCC, and successfully
compiling the Linux kernel is a gate in the GCC release process, so the two
are intimately tied together.

I would expect the same of Windows and MSVC, etc. Kernels are special.

> Don't get me wrong, it's no big deal that these particular rules are
> being broken in this case, but that doesn't mean the rules aren't being
> broken.


In such a case, the normal rules are simply not relevant.

OTOH, that also means that one should always be careful before using kernel
source as an example of how to write non-kernel source.

S

--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking
 
Reply With Quote
 
Tim Rentsch
Guest
Posts: n/a
 
      09-08-2012
Stephen Sprunk <(E-Mail Removed)> writes:

> On 07-Sep-12 10:37, Tim Rentsch wrote:
>> Keith Thompson <(E-Mail Removed)> writes:
>>> (The kernel is arguably part of the implementation, and even if it
>>> isn't, it's probably ok for the developers to rely on certain
>>> behaviors that aren't defined by the language standard.)

>>
>> The Linux kernel is part of no existing C implementation.

>
> The _running_ kernel is arguably part of the implementation;


You mean it's arguably part of _an_ implementation. I will
take up this question further on.

> the kernel _source being compiled_ is not.
>
>> And, even if it were, it is not part of implementations running on other
>> operating systems (eg MS windows or MacOS), yet presumably it's expected
>> to be compileable some such environments, so it's still breaking the
>> rules regarding reserved identifiers.

>
> The Linux kernel is only expected to be compilable by GCC,


Doesn't change my point, since GCC runs on systems besides
Linux.

> and successfully compiling the Linux kernel is a gate in the
> GCC release process, so the two are intimately tied together.


That doesn't make Linux part of a gcc implementation, any more
than a requirement for a successful compilation of 'rogue' would
make 'rogue' part of gcc implementations.

> I would expect the same of Windows and MSVC, etc. Kernels are
> special.


Kernels generally are more dependent on their compilation
environment than other programs. From a compiler's point
of view though they are still just programs.

>> Don't get me wrong, it's no big deal that these particular
>> rules are being broken in this case, but that doesn't mean the
>> rules aren't being broken.

>
> In such a case, the normal rules are simply not relevant.


The rules are relevant precisely because the kernel must
ensure that the rules it chooses to violate won't be
messed up by any implementation-reserved decisions made
by the compiler in question. If the kernel didn't break
any rules, then it wouldn't matter which compiler is
used to compile it; it's because the kernel _does_ break
rules that it needs to be choosy about which compilers
it uses. What I think you mean is that, because the
kernel is compiled with a compiler that doesn't exhibit
destructive interference over the rules the kernel does
break, breaking those rules does not have any negative
effects; and certainly that is true (by definition
it would have to be).

> OTOH, that also means that one should always be careful before
> using kernel source as an example of how to write non-kernel
> source.


I agree with that, but I think that's more an artifact of
expecting certain definitions of implementation-defined and
implementation-dependent behavior than it is of being a kernel.
Kernels are more prone to rely on those things than most
programs; but so also are many or most programs that run
on bare hardware, and certainly not all of those are kernels.

On the earlier question of whether Linux (or any typical modern
operating system) is part of a C implementations --

Paragraph 1 of section 5 says

An implementation translates C source files and executes C
programs in two data-processing-system environments, which
will be called the /translation environment/ and the
/execution environment/ in this International Standard.

Paragraph 2 of section 1 says

This International Standard does not specify

[...other items...]

. all minimal requirements of a data-processing system that
is capable of supporting a conforming implementation.

My argument is that a running Linux kernel supplies an execution
environment (and perhaps also a translation environment), which
under the descriptions in sections 1 and 5 is a data-processing
system, and as such these /support/ conforming implementations but
are not themselves /part of/ conforming implementations. The
Standard draws a distinct boundary between the two; and conventional
operating systems are clearly on the non-implementation side of that
boundary.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
problem in running a basic code in python 3.3.0 that includes HTML file Satabdi Mukherjee Python 1 04-04-2013 07:48 PM
Why not use juxtaposition to indicate function application Ray Song Python 10 03-17-2012 05:26 AM
compiler switch to indicate "end of function"? David Mathog C Programming 32 05-14-2011 07:03 AM
they turn, they power, they make nice pics Keith and Jenn Z. Digital Photography 0 09-21-2003 04:16 AM



Advertisments