/* $Id$ * $URL$ * * thread handling (mutex, shmem, ...) * * Copyright (C) 2004 Michael Reinelt * Copyright (C) 2004 The LCD4Linux Team * * parts of this code are based on the old XWindow driver which is * Copyright (C) 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. * */ /* * exported functions: * * int mutex_create (void); * creates a mutex and treturns its ID * * void mutex_lock (int semid); * try to lock a mutex * * void mutex_unlock (int semid); * unlock a mutex * * void mutex_destroy (int semid); * release a mutex * * * int shm_create (void **buffer, int size); * create shared memory segment * * void shm_destroy (int shmid, void *buffer) ; * release shared memory segment * * int thread_create (char *name, void (*thread)(void *data), void *data); * create a new thread * */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include "debug.h" #include "thread.h" #ifdef WITH_DMALLOC #include #endif int thread_argc; char **thread_argv; /* 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(const int semid) { struct sembuf sembuf; sembuf.sem_num = 0; sembuf.sem_op = -1; sembuf.sem_flg = 0; semop(semid, &sembuf, 1); } void mutex_unlock(const int semid) { struct sembuf sembuf; sembuf.sem_num = 0; sembuf.sem_op = 1; sembuf.sem_flg = 0; semop(semid, &sembuf, 1); } void mutex_destroy(const int semid) { union semun arg; semctl(semid, 0, IPC_RMID, arg); } int shm_create(void **buffer, const 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(const int shmid, const void *buffer) { shmdt(buffer); shmctl(shmid, IPC_RMID, NULL); } int thread_create(const 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); if (thread_argc > 0) { strncpy(thread_argv[0], name, strlen(thread_argv[0])); } thread(data); info("thread %s ended.", name); exit(0); default: info("forked process %d for thread %s", pid, name); } return pid; } int thread_destroy(const int pid) { return kill(pid, SIGKILL); } /td>reinelt10-335/+719 2004-01-14[lcd4linux @ 2004-01-14 11:33:00 by reinelt]reinelt15-160/+607 2004-01-13[lcd4linux @ 2004-01-13 10:03:01 by reinelt]reinelt8-23/+458 2004-01-13[lcd4linux @ 2004-01-13 08:18:07 by reinelt]reinelt12-154/+469 2004-01-12[lcd4linux @ 2004-01-12 03:51:01 by reinelt]reinelt5-15/+44 2004-01-11[lcd4linux @ 2004-01-11 18:26:02 by reinelt]reinelt10-79/+158 2004-01-11[lcd4linux @ 2004-01-11 09:26:15 by reinelt]reinelt4-19/+67 2004-01-10[lcd4linux @ 2004-01-10 20:22:33 by reinelt]reinelt13-210/+554 2004-01-10[lcd4linux @ 2004-01-10 17:45:26 by reinelt]reinelt2-5/+15 2004-01-10[lcd4linux @ 2004-01-10 17:36:56 by reinelt]reinelt4-10/+207 2004-01-10[lcd4linux @ 2004-01-10 17:34:40 by reinelt]reinelt3-176/+138 2004-01-10[lcd4linux @ 2004-01-10 10:20:22 by reinelt]reinelt2-14/+605 2004-01-09[lcd4linux @ 2004-01-09 17:03:06 by reinelt]reinelt10-51/+420 2004-01-09[lcd4linux @ 2004-01-09 04:16:06 by reinelt]reinelt28-193/+332 2004-01-08[lcd4linux @ 2004-01-08 06:00:28 by reinelt]reinelt1-8/+14 2004-01-08[lcd4linux @ 2004-01-08 05:28:12 by reinelt]reinelt3-42/+198 2004-01-07[lcd4linux @ 2004-01-07 10:15:41 by reinelt]reinelt4-184/+436 2004-01-06[lcd4linux @ 2004-01-06 23:01:37 by reinelt]reinelt3-4/+7 2004-01-06[lcd4linux @ 2004-01-06 22:33:13 by reinelt]reinelt14-472/+542 2004-01-06[lcd4linux @ 2004-01-06 21:14:51 by reinelt]reinelt4-14/+7 2004-01-06[lcd4linux @ 2004-01-06 18:22:41 by reinelt]reinelt1-3/+13 2004-01-06[lcd4linux @ 2004-01-06 17:56:43 by reinelt]reinelt3-1000/+2045 2004-01-06[lcd4linux @ 2004-01-06 17:37:00 by reinelt]reinelt1-0/+20 2004-01-06[lcd4linux @ 2004-01-06 17:33:45 by reinelt]reinelt6-28/+298 2004-01-06[lcd4linux @ 2004-01-06 15:19:12 by reinelt]reinelt2-104/+136 2004-01-05[lcd4linux @ 2004-01-05 11:57:38 by reinelt]reinelt7-8/+168 2004-01-02[lcd4linux @ 2004-01-02 14:20:15 by reinelt]reinelt10-0/+201 2004-01-02[lcd4linux @ 2004-01-02 14:18:54 by reinelt]reinelt2-0/+101 2003-12-19[lcd4linux @ 2003-12-19 06:27:33 by reinelt]reinelt4-8/+119