/*
Buffer. Very fast reblocking filter speedy writing of tapes.
Copyright (C) 1990,1991 Lee McLoughlin
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Lee McLoughlin.
Dept of Computing, Imperial College,
180 Queens Gate, London, SW7 2BZ, UK.
Email:
[email protected]
*/
/* This is a simple module to provide an easier to understand interface to
* semaphores */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#if defined(SYS5) || defined(ultrix) || defined(_AIX)
union semun {
int val;
struct semid_ds *buf;
ushort *array;
};
#endif
/* Set a semaphore to a particular value - meant to be used before
* first lock/unlock */
void
sem_set( sem_id, val )
int sem_id;
int val;
{
union semun arg;
extern int errno;
arg.val = val;
errno = 0;
semctl( sem_id, 0, SETVAL, arg );
if( errno != 0 ){
perror( "buffer: internal error, sem_set" );
exit( -1 );
}
}
int
new_sem()
{
int sem;
sem = semget( IPC_PRIVATE, 1, IPC_CREAT|S_IREAD|S_IWRITE );
if( sem < 0 ){
perror( "buffer: internal error, couldn't create semaphore" );
exit( -1 );
}
sem_set( sem, 1 );
return sem;
}
void
lock( sem_id )
int sem_id;
{
struct sembuf sembuf;
sembuf.sem_num = 0;
sembuf.sem_op = -1;
sembuf.sem_flg = 0;
if( semop( sem_id, &sembuf, 1 ) == -1 ){
fprintf( stderr, "internal error, lock id %d\n", sem_id );
perror( "buffer: lock error" );
exit( -1 );
}
}
void
unlock( sem_id )
int sem_id;
{
struct sembuf sembuf;
sembuf.sem_num = 0;
sembuf.sem_op = 1;
sembuf.sem_flg = 0;
if( semop( sem_id, &sembuf, 1 ) == -1 ){
fprintf( stderr, "internal error, lock id %d\n", sem_id );
perror( "buffer: unlock error" );
exit( -1 );
}
}
void
remove_sem( sem_id )
int sem_id;
{
if( sem_id == -1 )
return;
if( semctl( sem_id, 0, IPC_RMID, NULL ) == -1 )
perror( "buffer: internal error, failed to remove semaphore" );
}