DragonFly BSD
DragonFly commits List (threaded) for 2005-03
[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]

Re: cvs commit: src/libexec/rtld-elf map_object.c rtld.c rtld.h rtld_tls.h src/libexec/rtld-elf/i386 reloc.c rtld_machdep.h


From: Matthew Dillon <dillon@xxxxxxxxxxxxxxxxxxxx>
Date: Tue, 22 Mar 2005 17:55:56 -0800 (PST)

:I also have a big plan about TCB contents which is related to
:high performance userland critical section and asynchronous
:signal safe.
:
:David Xu

    This is doable.  Signal delivery is so expensive already that I am
    not adverse to implementing a userland counter to disable signal
    delivery within a particular section of code that does not require 
    system interaction. 

    One way of doing this is to register the address of a userland structure
    with the system via a system call, something like this:

    struct userland_crit_section {
	int	ucounter;
	sigset_t blocked_mask;
    }

    When a signal occurs the system checks ucounter.  If it is 0 then the
    signal is delivered normally and no modifications to the
    userland_crit_section structure are made.

    If ucounter is non-zero then the following actions are performed by
    the system:

	* The signal is blocked in the system signal blocking mask for the
	  process.

	* The system sets bit 31 in the ucounter field.

	* The bit representing the signal is added to the blocked_mask
	  element in the registered userland_crit_section structure.

    To exit a critical section userland would have to do this:

	if (--critinfo.ucounter == (int)0x80000000) {
		sys_siguseruncrit(&critinfo);
	}

	RACE CASES: none.  Because the system sets bit 31 in ucounter, if
	any signals were blocked while userland was in the critical section
	ucounter will remain non-zero on the last exit from the critical
	section.  sys_siguseruncrit() would then atomically clear ucounter,
	clear the blocked signals based on blocked_mask, and clear 
	blocked_mask.

    For exiting a critical section there is no way for userland to atomically
    clean up the signal mask via sigprocmask() and clear ucounter... you get
    race cases no matter how you arrange it, so a second system call 
    (sys_siguseruncrit()) is required... but only if signals were actually
    blocked.

    Userland would have to use a (non-bus-locked) atomic instruction to
    increment and decrement ucounter (i.e. a simple incl or decl).

					-Matt
					Matthew Dillon 
					<dillon@xxxxxxxxxxxxx>



[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]