Operating System - HP-UX
1820672 Members
2321 Online
109626 Solutions
New Discussion юеВ

Atomic semaphore in 'C' on HP UX

 
eric eberhard
Occasional Contributor

Atomic semaphore in 'C' on HP UX

I need an atomic instruction to set a semaphore (test and set), clear a semaphore, and test a semaphore. It seems that each flavor of unix uses different instructions (grrr). Are there available some simple easy fast atomic instruction available in HP UX? Is there a good on-line resource for this subject?
Thanks!
9 REPLIES 9
A. Clay Stephenson
Acclaimed Contributor

Re: Atomic semaphore in 'C' on HP UX

Hi eric:

I don't quite understand, I used the semop() system call in many flavors of UNIX (both SystemV and BSD based) for over 20 years and it works like a charm and does atomic operations. Dijkstra would be most unhappy if his "P" and "V" semaphores were not atomic.
Tha man page for semop is quite clear and gives examples.
If it ain't broke, I can fix that.
eric eberhard
Occasional Contributor

Re: Atomic semaphore in 'C' on HP UX

semop works fine. And is VERY slow. I need something much simpler and faster:

int sem;

tas(int *sem)
{
if (sem)
return(0);
else
return(++*sem);
}

clear(int *sem)
{
*sem = 0;
}

However the above must be atomic.

Examples: Motorolla and TI use "tas" as function name.
AIX uses "cs" (for check & set?).

I assume HP UX has something similar but man pages don't have either of the above.
A. Clay Stephenson
Acclaimed Contributor

Re: Atomic semaphore in 'C' on HP UX

No, Test and Set is not implemented in HP-UX; typically tas is done in hardware. If you are running the 11.x and have the ANSI/C or aCC+ compiler, you can use the sem_trywait() POSIX version of semaphores which is quite fast.

There are also some mechanisms for sychronizing threads like lock_gate() and cond_lock_gate() but since your project is K & R C, you are going to have a difficult time using them.
If it ain't broke, I can fix that.
eric eberhard
Occasional Contributor

Re: Atomic semaphore in 'C' on HP UX

I probably should have said that I need it to be an int or char or long, and not a structure.

Test and set is what I need, but if not there then I guess I don't have it.

I have used in the past for some systems (that also do not have TAS) my own routines (stolen from a KR textbook) which only have one requirement:

int sem;

sem++;

I need the "sem++" to be atomic. In some systems this is atomic on int and not char, some it is on char and not int, one it is atomic on long! Go figure.

Does anyone know if char, int,
or long increments/decrements
are atomic on HP UX???

Thanks
A. Clay Stephenson
Acclaimed Contributor

Re: Atomic semaphore in 'C' on HP UX

None of these operations, given the scheduler, can be guaranteed to be atomic. The bad news is that trying to test a 'homegrown' semaphore is almost impossible to reliably test. You would have to catch the competing processes/threads at just the wrong moment.

If you are serious about needing semaphores and you can't use the normal semaphores then your only real alternative is to use the libpthread functions (e.g. pthread_mutex_lock() and pthread_mutex_trylock()). Man pthread for details. These are quite fast and are intended for your purposes. You will almost cerainly have to make ANSI/C calls withing this code section but these can simply be wrappers for your K&R code.
If it ain't broke, I can fix that.
Vincent Fleming
Honored Contributor

Re: Atomic semaphore in 'C' on HP UX

I'll show my age here...

What we used to do "way back when" is write your routines in C, then use the C compiler to generate assembly code. Manually edit the assembly, and add the instructions to clear interrupts (usually "cli", you'll have to look it up, as I haven't done this on HPUX/PA-RISC) so that the scheduler cannot interrupt the routine during execution. At the end of the routine, re-enable interrupts.
When you're done editing, assmebly the code, and use it as you would any C routine.

This always worked well for me, and is basically how the kernel does atomic operations.

Good luck!
No matter where you go, there you are.
Harri Pasanen
Occasional Advisor

Re: Atomic semaphore in 'C' on HP UX

If you look at the Linux sources for PA-Risc, you'll find a fast lock implementation in inline assembly. That will work fine also in HP-UX, although I don't know how to do inline assembly with HP C. You can compile the function in question using gcc, and link with HP-C compiled code.

eric eberhard
Occasional Contributor

Re: Atomic semaphore in 'C' on HP UX

I had no idea this would be so difficult -- never heard of a computer that did not have a 'C' function for TAS. I hear that Linux for PA-RISC has such functions in 'C' but I cannot find them anywhere ...

I found this hunting about the web:

PS Instruction "Test and Set"

An often-asked assembly language question for the PA-RISC architecture is the location of an atomic "test and set" instruction for
performance sensitive operations. The "load and clear" word short instruction can perform "test and set." The word must be on a 16-bit
boundary. See the "PA-RISC Architecture and Instruction Set" manual for information on how this instruction operates.


It appears from mucho sources that TAS does not exist but that load/clear can be used in assembler. Does anyone have any assembler code that I can link into my C code (after compiling) that performs the load and clear (and in an ideal world a test function)????
David Layden
New Member

Re: Atomic semaphore in 'C' on HP UX

Try the following:
;
; spin.s: Example assembly language routine for spinlock support.
;
.code
; .level 2.0W ; use this option for 64-bit assembly
.export load_and_clear,entry,priv_lev=3,rtnval=gr
.proc
load_and_clear
.callinfo no_calls
.enter

; create a 16 byte aligned pointer to the load+clear word area
addi 15,%arg0,%arg2 ; add 15 to pointer provided to round up

; Choose one of these statements and comment out the other:
depi 0,31,4,%arg2 ; mask off the lower 4 bits (32-bit version)
; depdi 0,63,4,%arg2 ; mask off the lower 4 bits (64-bit version)

; load and clear the spinlock. If locked, return 0
stbys,e 0,(%arg2) ; scrub cache; important for performance
ldcws (%arg2),%ret0 ; load and clear the spinlock word
nop ; 3 No-Op instructions; needed for older
nop ; HP-PA chips
nop
bv,n (%r2)
.leave
.procend
We can do anything, but not everything!