📄 semaphore.c
字号:
/* * semaphore.c * * Copyright (C) 2006 Insigme Co., Ltd * * Authors: * - Liwei Zhou * * This software has been developed while working on the Linux Unified Kernel * project (http://linux.insigma.com.cn) in the Insigma Reaserch Institute, * which is a subdivision of Insigma Co., Ltd (http://www.insigma.com.cn). * * The project is sponsored by Insigma Co., Ltd. * * The authors can be reached at linux@insigma.com.cn. * * 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 2 of the License, or (at your * option) any later version. * * Revision History: * Jan 2006 - Created. */ /* * semaphore.c: semaphore syscall functions * Reference to Kernel-win32 code */#include <linux/module.h>#include "semaphore.h"#include "thread.h"#include "process.h"#include "objwait.h"#include <asm/uaccess.h>#ifdef CONFIG_UNIFIED_KERNELstatic int SemaphoreConstructor(win32_object *, void *);static int SemaphoreReconstructor(win32_object *, void *);static void SemaphoreDestructor(win32_object *);static int SemaphorePoll(struct wait_table_entry *, struct ethread *);struct win32_object_class semaphore_objclass = { oc_type: "SEMA ", constructor: SemaphoreConstructor, reconstructor: NULL, destructor: SemaphoreDestructor, poll: SemaphorePoll,};/* * initialise the semaphore object class */void SemaphoreClassInit(void){ InitObjectClass(&semaphore_objclass);} /* end SemaphoreClassInit() *//* * open a semaphore object, creating if non-existent */NTSTATUSSTDCALLNtCreateSemaphore(OUT PHANDLE SemaphoreHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN LONG InitialCount, IN LONG MaximumCount){ HANDLE hSemaphore; win32_object *obj; struct ethread *thread; struct sema_args args; OBJECT_ATTRIBUTES obj_attr; UNICODE_STRING obj_name; if(!(thread = thread_find())) return -EINVAL; if((copy_from_user(&obj_attr,ObjectAttributes,sizeof(OBJECT_ATTRIBUTES)))) return -EFAULT; if((copy_from_user(&obj_name,ObjectAttributes->ObjectName,sizeof(UNICODE_STRING)))) return -EFAULT; args.SemaphoreHandle = SemaphoreHandle; args.DesiredAccess = DesiredAccess; args.InitialCount = InitialCount; args.MaximumCount = MaximumCount; args.ObjectAttributes = &obj_attr; args.ObjectAttributes->ObjectName = &obj_name; obj = CreateObject(thread,&semaphore_objclass,(char *)args.ObjectAttributes->ObjectName->Buffer,&args, &hSemaphore); if (IS_ERR(obj)) return PTR_ERR(obj); ktrace("*** [%d] CreateSemaphore(%p,%d,%d) = %p\n", current->pid,obj, args.InitialCount,args.MaximumCount, hSemaphore); if((copy_to_user(SemaphoreHandle,&hSemaphore,sizeof(HANDLE)))) return -EFAULT; objput(obj); return STATUS_SUCCESS;} /* end NtCreateSemaphore() *//* * open a semaphore object, failing if non-existent */NTSTATUSSTDCALLNtOpenSemaphore(OUT PHANDLE SemaphoreHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes){ HANDLE hSemaphore; win32_object *obj; struct ethread *thread; UNICODE_STRING obj_name; if(!(thread = thread_find())) return -EINVAL; if((copy_from_user(&obj_name,ObjectAttributes->ObjectName,sizeof(UNICODE_STRING)))) return -EFAULT; obj = OpenObject(thread,&semaphore_objclass,(char *)obj_name.Buffer,&hSemaphore); if (IS_ERR(obj)) return PTR_ERR(obj); ktrace("*** [%d] OpenSemaphore(%p) = %p\n", current->pid,obj,hSemaphore); if((copy_to_user(SemaphoreHandle,&hSemaphore,sizeof(HANDLE)))) return -EFAULT; objput(obj); return STATUS_SUCCESS;} /* end NtOpenSemaphore() *//* * release a semaphore (increment count up to max limit) */NTSTATUSSTDCALLNtReleaseSemaphore(IN HANDLE SemaphoreHandle, IN LONG ReleaseCount, OUT PLONG PreviousCount OPTIONAL){ struct win32_semaphore *semaphore; win32_object *obj; LONG old; struct ethread *thread; if(!(thread = thread_find())) return -EINVAL; ktrace("ReleaseSemaphore(%p,%p)\n",thread,SemaphoreHandle); /* find delta value */ if (ReleaseCount<=0 || ReleaseCount>0x7FFFFFFF) return -EINVAL; obj = GetObject(thread,SemaphoreHandle,&semaphore_objclass); if (IS_ERR(obj)) return PTR_ERR(obj); semaphore = obj->o_private; spin_lock(&semaphore->ws_lock); old = semaphore->ws_count; semaphore->ws_count = old + ReleaseCount; if (semaphore->ws_count > semaphore->ws_max) semaphore->ws_count = semaphore->ws_max; spin_unlock(&semaphore->ws_lock); signal_object(obj,1); /* store old value back into userspace */ if((copy_to_user(PreviousCount,&old,sizeof(LONG)))) return -EFAULT; ktrace("*** [%d] ReleaseSemaphore(%p,%d)\n",current->pid,obj,old); objput(obj); return STATUS_SUCCESS;} /* end NtReleaseSemaphore() *//* * poll the state of a semaphore for WaitFor*() functions * - if count greater than zero, decrements count under spinlock */static int SemaphorePoll(struct wait_table_entry *wte, struct ethread *thread){ struct win32_semaphore *semaphore = wte->wte_obj->o_private; int ret; ret = POLL_NOTSIG; spin_lock(&semaphore->ws_lock); if (semaphore->ws_count > 0) { semaphore->ws_count--; ret = POLL_SIG; } spin_unlock(&semaphore->ws_lock); ktrace("*** [%d] SemaphorePoll(%p) = %d\n", current->pid,wte->wte_obj,ret); return ret;} /* end SemaphorePoll() *//* * construct a semaphore (allocate its private data) * - called by CreateObject if the semaphore does not already exists * - called with the object class lock held */static int SemaphoreConstructor(win32_object *obj, void *data){ struct sema_args *args = data; struct win32_semaphore *semaphore; ktrace("SemaphoreConstructor(%p)\n",obj); semaphore = (struct win32_semaphore *) kmalloc(sizeof(struct win32_semaphore), GFP_KERNEL); if (!semaphore) return -ENOMEM; obj->o_private = semaphore; semaphore->ws_count = args->InitialCount; semaphore->ws_max = args->MaximumCount; spin_lock_init(&semaphore->ws_lock); return 0;} /* end SemaphoreConstructor() *//* * reconstruct a semaphore (allocate its private data) * - called by CreateObject if the semaphore already exists * - called without the object class lock held * - does nothing */static int SemaphoreReconstructor(win32_object *obj, void *data){ ktrace("SemaphoreReconstructor(%p)\n",obj); return 0;} /* end SemaphoreReconstructor() *//* * destroy a semaphore (discard its private data) */static void SemaphoreDestructor(win32_object *obj){ ktrace("SemaphoreDestructor(%p)\n",obj); kfree(obj->o_private);} /* end SemaphoreDestructor() */#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -