1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 only,
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License version 2 for more details (a copy is included
16 * in the LICENSE file that accompanied this code).
18 * You should have received a copy of the GNU General Public License
19 * version 2 along with this program; If not, see [sun.com URL with a
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
29 * Copyright 2008 Sun Microsystems, Inc. All rights reserved
30 * Use is subject to license terms.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 * libcfs/libcfs/winnt/winnt-curproc.c
38 * Impletion of winnt curproc routines.
41 #define DEBUG_SUBSYSTEM S_LNET
43 #include <libcfs/libcfs.h>
47 * Implementation of cfs_curproc API (see portals/include/libcfs/curproc.h)
51 cfs_task_t this_task =
52 { 0, 0, 0, 0, 0, 0, 0,
53 0, 0, 0, 0, 1, 0, 0, 0, 0,
57 uid_t cfs_curproc_uid(void)
62 gid_t cfs_curproc_gid(void)
67 uid_t cfs_curproc_fsuid(void)
69 return this_task.fsuid;
72 gid_t cfs_curproc_fsgid(void)
74 return this_task.fsgid;
77 pid_t cfs_curproc_pid(void)
79 return cfs_current()->pid;
82 int cfs_curproc_groups_nr(void)
84 return this_task.ngroups;
87 void cfs_curproc_groups_dump(gid_t *array, int size)
89 LASSERT(size <= NGROUPS);
90 size = min_t(int, size, this_task.ngroups);
91 memcpy(array, this_task.groups, size * sizeof(__u32));
94 int cfs_curproc_is_in_groups(gid_t gid)
96 return in_group_p(gid);
99 mode_t cfs_curproc_umask(void)
101 return this_task.umask;
104 char *cfs_curproc_comm(void)
106 return this_task.comm;
109 cfs_kernel_cap_t cfs_curproc_cap_get(void)
111 return this_task.cap_effective;
114 void cfs_curproc_cap_set(cfs_kernel_cap_t cap)
116 this_task.cap_effective = cap;
121 * Implementation of linux task management routines
125 /* global of the task manager structure */
137 PTASK_SLOT task = NULL;
140 task = cfs_mem_cache_alloc(TaskMan.slab, 0);
142 task = cfs_alloc(sizeof(TASK_SLOT), 0);
149 init_task_slot(PTASK_SLOT task)
151 memset(task, 0, sizeof(TASK_SLOT));
152 task->Magic = TASKSLT_MAGIC;
153 task->task = this_task;
154 task->task.pid = (pid_t)PsGetCurrentThreadId();
155 cfs_init_event(&task->Event, TRUE, FALSE);
160 cleanup_task_slot(PTASK_SLOT task)
163 cfs_mem_cache_free(TaskMan.slab, task);
170 * task manager related routines
180 PLIST_ENTRY ListEntry = NULL;
181 PTASK_SLOT TaskSlot = NULL;
183 spin_lock(&(TaskMan.Lock));
185 ListEntry = TaskMan.TaskList.Flink;
187 while (ListEntry != (&(TaskMan.TaskList))) {
189 TaskSlot = CONTAINING_RECORD(ListEntry, TASK_SLOT, Link);
191 if (TaskSlot->Pid == ProcessId && TaskSlot->Tid == ThreadId) {
195 DbgPrint("task_manager_notify: Pid=%xh Tid %xh resued (TaskSlot->Tet = %xh)...\n",
196 ProcessId, ThreadId, TaskSlot->Tet);
199 /* remove the taskslot */
200 RemoveEntryList(&(TaskSlot->Link));
201 TaskMan.NumOfTasks--;
203 /* now free the task slot */
204 cleanup_task_slot(TaskSlot);
208 ListEntry = ListEntry->Flink;
211 spin_unlock(&(TaskMan.Lock));
219 /* initialize the content and magic */
220 memset(&TaskMan, 0, sizeof(TASK_MAN));
221 TaskMan.Magic = TASKMAN_MAGIC;
223 /* initialize the spinlock protection */
224 spin_lock_init(&TaskMan.Lock);
226 /* create slab memory cache */
227 TaskMan.slab = cfs_mem_cache_create(
228 "TSLT", sizeof(TASK_SLOT), 0, 0);
230 /* intialize the list header */
231 InitializeListHead(&(TaskMan.TaskList));
233 /* set the thread creation/destruction notify routine */
234 status = PsSetCreateThreadNotifyRoutine(task_manager_notify);
236 if (!NT_SUCCESS(status)) {
237 cfs_enter_debugger();
244 cleanup_task_manager()
246 PLIST_ENTRY ListEntry = NULL;
247 PTASK_SLOT TaskSlot = NULL;
249 /* we must stay in system since we succeed to register the
250 CreateThreadNotifyRoutine: task_manager_notify */
251 cfs_enter_debugger();
254 /* cleanup all the taskslots attached to the list */
255 spin_lock(&(TaskMan.Lock));
257 while (!IsListEmpty(&(TaskMan.TaskList))) {
259 ListEntry = TaskMan.TaskList.Flink;
260 TaskSlot = CONTAINING_RECORD(ListEntry, TASK_SLOT, Link);
262 RemoveEntryList(ListEntry);
263 cleanup_task_slot(TaskSlot);
266 spin_unlock(&TaskMan.Lock);
268 /* destroy the taskslot cache slab */
269 cfs_mem_cache_destroy(TaskMan.slab);
270 memset(&TaskMan, 0, sizeof(TASK_MAN));
275 * schedule routines (task slot list)
282 HANDLE Pid = PsGetCurrentProcessId();
283 HANDLE Tid = PsGetCurrentThreadId();
284 PETHREAD Tet = PsGetCurrentThread();
286 PLIST_ENTRY ListEntry = NULL;
287 PTASK_SLOT TaskSlot = NULL;
289 spin_lock(&(TaskMan.Lock));
291 ListEntry = TaskMan.TaskList.Flink;
293 while (ListEntry != (&(TaskMan.TaskList))) {
295 TaskSlot = CONTAINING_RECORD(ListEntry, TASK_SLOT, Link);
297 if (TaskSlot->Pid == Pid && TaskSlot->Tid == Tid) {
298 if (TaskSlot->Tet != Tet) {
301 DbgPrint("cfs_current: Pid=%xh Tid %xh Tet = %xh resued (TaskSlot->Tet = %xh)...\n",
302 Pid, Tid, Tet, TaskSlot->Tet);
305 // The old thread was already exit. This must be a
306 // new thread which get the same Tid to the previous.
315 if ((ULONG)TaskSlot->Pid > (ULONG)Pid) {
318 } else if ((ULONG)TaskSlot->Pid == (ULONG)Pid) {
319 if ((ULONG)TaskSlot->Tid > (ULONG)Tid) {
328 ListEntry = ListEntry->Flink;
333 TaskSlot = alloc_task_slot();
336 cfs_enter_debugger();
340 init_task_slot(TaskSlot);
346 if (ListEntry == (&(TaskMan.TaskList))) {
348 // Empty case or the biggest case, put it to the tail.
350 InsertTailList(&(TaskMan.TaskList), &(TaskSlot->Link));
353 // Get a slot and smaller than it's tid, put it just before.
355 InsertHeadList(ListEntry->Blink, &(TaskSlot->Link));
358 TaskMan.NumOfTasks++;
362 // To Check whether he task structures are arranged in the expected order ?
366 PTASK_SLOT Prev = NULL, Curr = NULL;
368 ListEntry = TaskMan.TaskList.Flink;
370 while (ListEntry != (&(TaskMan.TaskList))) {
372 Curr = CONTAINING_RECORD(ListEntry, TASK_SLOT, Link);
373 ListEntry = ListEntry->Flink;
376 if ((ULONG)Prev->Pid > (ULONG)Curr->Pid) {
377 cfs_enter_debugger();
378 } else if ((ULONG)Prev->Pid == (ULONG)Curr->Pid) {
379 if ((ULONG)Prev->Tid > (ULONG)Curr->Tid) {
380 cfs_enter_debugger();
391 spin_unlock(&(TaskMan.Lock));
394 cfs_enter_debugger();
398 return (&(TaskSlot->task));
402 schedule_timeout(int64_t time)
404 cfs_task_t * task = cfs_current();
405 PTASK_SLOT slot = NULL;
408 cfs_enter_debugger();
412 slot = CONTAINING_RECORD(task, TASK_SLOT, task);
413 cfs_assert(slot->Magic == TASKSLT_MAGIC);
415 if (time == MAX_SCHEDULE_TIMEOUT) {
419 return (cfs_wait_event(&(slot->Event), time) != 0);
425 return schedule_timeout(0);
433 PTASK_SLOT slot = NULL;
436 cfs_enter_debugger();
440 slot = CONTAINING_RECORD(task, TASK_SLOT, task);
441 cfs_assert(slot->Magic == TASKSLT_MAGIC);
443 cfs_wake_event(&(slot->Event));
455 cfs_waitlink_init(&link);
456 cfs_waitq_add(waitq, &link);
457 cfs_waitq_wait(&link, CFS_TASK_INTERRUPTIBLE);
458 cfs_waitq_del(waitq, &link);
461 EXPORT_SYMBOL(cfs_curproc_uid);
462 EXPORT_SYMBOL(cfs_curproc_pid);
463 EXPORT_SYMBOL(cfs_curproc_gid);
464 EXPORT_SYMBOL(cfs_curproc_fsuid);
465 EXPORT_SYMBOL(cfs_curproc_fsgid);
466 EXPORT_SYMBOL(cfs_curproc_umask);
467 EXPORT_SYMBOL(cfs_curproc_comm);
468 EXPORT_SYMBOL(cfs_curproc_groups_nr);
469 EXPORT_SYMBOL(cfs_curproc_groups_dump);
470 EXPORT_SYMBOL(cfs_curproc_is_in_groups);
471 EXPORT_SYMBOL(cfs_curproc_cap_get);
472 EXPORT_SYMBOL(cfs_curproc_cap_set);