/* $Id: thread.c,v 1.3 2004/04/08 10:48:25 reinelt Exp $ * * thread handling (mutex, shmem, ...) * * Copyright 2004 Michael Reinelt * Copyright 2004 The LCD4Linux Team * * parts of this code are based on the old XWindow driver which is * Copyright 2000 Herbert Rosmanith * * This file is part of LCD4Linux. * * LCD4Linux 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 2, or (at your option) * any later version. * * LCD4Linux 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. * * * $Log: thread.c,v $ * Revision 1.3 2004/04/08 10:48:25 reinelt * finished plugin_exec * modified thread handling * added '%x' format to qprintf (hexadecimal) * * Revision 1.2 2004/03/20 07:31:33 reinelt * support for HD66712 (which has a different RAM layout) * further threading development * * Revision 1.1 2004/03/19 06:37:47 reinelt * asynchronous thread handling started * */ /* * exported functions: * * Fixme: document me! * */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include "debug.h" #include "thread.h" #ifdef WITH_DMALLOC #include #endif /* glibc 2.1 requires defining semun ourselves */ #ifdef _SEM_SEMUN_UNDEFINED union semun { int val; struct semid_ds *buf; unsigned short int *array; struct seminfo *__buf; }; #endif int mutex_create (void) { int semid; union semun semun; semid = semget(IPC_PRIVATE, 1, 0); if (semid == -1) { error ("fatal error: semget() failed: %s", strerror(errno)); return -1; } semun.val = 1; semctl(semid, 0, SETVAL, semun); return semid; } void mutex_lock (int semid) { struct sembuf sembuf; sembuf.sem_num = 0; sembuf.sem_op = -1; sembuf.sem_flg = 0; semop (semid, &sembuf, 1); } void mutex_unlock (int semid) { struct sembuf sembuf; sembuf.sem_num = 0; sembuf.sem_op = 1; sembuf.sem_flg = 0; semop (semid, &sembuf, 1); } void mutex_destroy (int semid) { union semun arg; semctl(semid, 0, IPC_RMID, arg); } int shm_create (void **buffer, int size) { int shmid; shmid = shmget(IPC_PRIVATE, size, SHM_R|SHM_W); if (shmid==-1) { error ("fatal error: shmget() failed: %s", strerror(errno)); return -1; } *buffer = shmat(shmid, NULL, 0); if (*buffer == NULL) { error ("fatal error: shmat() failed: %s", strerror(errno)); return -1; } return shmid; } void shm_destroy (int shmid, void *buffer) { shmdt (buffer); shmctl(shmid, IPC_RMID, NULL); } int thread_create (char *name, void (*thread)(void *data), void *data) { pid_t pid, ppid; ppid=getpid(); switch (pid = fork()) { case -1: error ("fatal error: fork(%s) failed: %s", name, strerror(errno)); return -1; case 0: info ("thread %s starting...", name); thread(data); info ("thread %s ended.", name); exit (0); default: info ("forked process %d for thread %s", pid, name); } return pid; }