tirwhan has asked for the wisdom of the Perl Monks concerning the following question:

Fellow monks,

while playing around with benchmarks for this node, I came across the sched_yield system call. This seems to be useful enough to expose it to Perl programs, so I wrote up a trivial module using Inline::C. Now I have a number of questions and I'd be happy if you could take the time to answer some of them:

Any other comments and guidances are also more than welcome. Here's the code:

Update: now with Readmore tags, as suggested

package POSIX::Yield; use version;our $VERSION=qv('0.0.1'); use strict; use warnings; use Inline C => <<'END_OF_CODE'; #include <sched.h> int _yield() { return sched_yield() == 0 ? 1 : 0 ; } END_OF_CODE use base qw(Exporter); our @EXPORT_OK = qw(yield); sub yield { _yield() or return; } 1; __END__ =head1 NAME POSIX::Yield - yield the processor =head1 VERSION This documentation refers to POSIX::Yield 0.0.1. =head1 SYNOPSIS use POSIX::Yield qw(yield); yield(); =head1 DESCRIPTION This module provides one function, C<yield()>, which calls the POSIX.1 +b C<sched_yield()> system call. It relinquishes the processor without + blocking, allowing other processes to run. This does B<not> change t +he process priority (see the C<nice()> function from the C<POSIX> mod +ule for that), so if your process is currently the one with the highe +st priority it will continue to run without interruption. See the C<s +ched_yield(2)> man page and your operating systems scheduling documen +tation for more details. =head1 INTERFACE =head2 Subroutines =over =item C<yield()> Executes the C<sched_yield> system call. No parameters can be passed, +the function returns 1 on sucess, undef on failure. =back =head1 EXAMPLES / USAGE You can use C<POSIX::Yield> to implement a spinlock: use Fcntl qw(:flock); use POSIX::Yield qw(yield); my $lock; open($lock,">","/tmp/file") or die "Can't open"; while (!flock($lock, LOCK_EX|LOCK_NB)) { yield(); } #.. do something .. flock($lock, LOCK_UN) or die "Can't release lock"; close $lock or die "Can't close lockfile"; This will yield the processor when a process is unable to obtain a loc +k, thus hopefully giving control back to the process which is handlin +g the lock at the moment and allowing it to be released. You should B +<not> use C<yield> this way if you're expecting the lock to be held f +or any extended period of time (for example if the locking process wa +its for I/O with the lock held), because this will cause your yieldin +g process to hog the CPU as it retries,yields,retries,yields etc. =head1 DEPENDENCIES POSIX::Yield depends on the following modules: =over =item * Inline::C =item * version =back and a POSIX environment =head1 SEE ALSO <sched_yield(2) man page =head1 BUGS AND LIMITATIONS None known

Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. -- Brian W. Kernighan

Replies are listed 'Best First'.
Re: RFC: Proposed module POSIX::Yield
by BrowserUk (Patriarch) on Dec 02, 2005 at 16:45 UTC

    threads::yield is portable across platforms and does much the same thing as your code under Linux.

    I tend to use Win32::Sleep $milliseconds; to yield the processor inside poll-type loops, because it allows me to strike a balance between responsivness and threashing the processor to death.

    If shed_yield() has application outside of threaded code, perhaps you could offer a patch to the POSIX module?


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      Thanks, I think I will try with a patch to POSIX and see where that gets me. That is the most logical place to look for it, and even though threads->yield will apparently do the same thing in most cases, users are more likely to recognise they can use POSIX::sched_yield() for processes.


      Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. -- Brian W. Kernighan
Re: RFC: Proposed module POSIX::Yield
by dave_the_m (Monsignor) on Dec 02, 2005 at 14:46 UTC
    Why not just use threads::yield? It typically does the same thing internally (eg on linux it calls sched_yield()), and is portable, eg can be used on windows.

    Dave.

      Well for one, threads::yield will only work on a perl binary with threads support, and AFAIK it's not actually very well defined what threads::yield does, especially in a single-threaded program.

      As for the OP's question about Inline::C vs XS, I'd recommend porting the module to XS if you want to release it to the public, just because it removes a couple of dependencies. Once you have a working Inline::C module, porting to XS isn't very hard.

        Thanks. Do you think it'd be worthwhile doing that? I still like the idea of being able to call sched_yield explicitly (despite dave_the_m's very valid objection), and it'd be useful on older Perl versions as well. But I don't want to pollute CPAN with useless stuff.


        Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. -- Brian W. Kernighan