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
20 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
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 * lnet/libcfs/winnt/winnt-curproc.c
38 * Implementation of winnt curproc routines.
41 #define DEBUG_SUBSYSTEM S_LNET
43 #include <libcfs/libcfs.h>
44 #include <libcfs/kp30.h>
48 * Implementation of cfs_curproc API (see portals/include/libcfs/curproc.h)
52 cfs_task_t this_task =
53 { 0, 0, 0, 0, 0, 0, 0,
54 0, 0, 0, 0, 1, 0, 0, 0, 0,
58 uid_t cfs_curproc_uid(void)
63 gid_t cfs_curproc_gid(void)
68 uid_t cfs_curproc_fsuid(void)
70 return this_task.fsuid;
73 gid_t cfs_curproc_fsgid(void)
75 return this_task.fsgid;
78 pid_t cfs_curproc_pid(void)
80 return cfs_current()->pid;
83 int cfs_curproc_groups_nr(void)
85 return this_task.ngroups;
88 void cfs_curproc_groups_dump(gid_t *array, int size)
90 LASSERT(size <= NGROUPS);
91 size = min_t(int, size, this_task.ngroups);
92 memcpy(array, this_task.groups, size * sizeof(__u32));
95 int cfs_curproc_is_in_groups(gid_t gid)
97 return in_group_p(gid);
100 mode_t cfs_curproc_umask(void)
102 return this_task.umask;
105 char *cfs_curproc_comm(void)
107 return this_task.comm;
110 cfs_kernel_cap_t cfs_curproc_cap_get(void)
112 return this_task.cap_effective;
115 void cfs_curproc_cap_set(cfs_kernel_cap_t cap)
117 this_task.cap_effective = cap;
122 * Implementation of linux task management routines
126 /* global of the task manager structure */
138 PTASK_SLOT task = NULL;
141 task = cfs_mem_cache_alloc(TaskMan.slab, 0);
143 task = cfs_alloc(sizeof(TASK_SLOT), 0);
150 init_task_slot(PTASK_SLOT task)
152 memset(task, 0, sizeof(TASK_SLOT));
153 task->Magic = TASKSLT_MAGIC;
154 task->task = this_task;
155 task->task.pid = (pid_t)PsGetCurrentThreadId();
156 cfs_init_event(&task->Event, TRUE, FALSE);
161 cleanup_task_slot(PTASK_SLOT task)
164 cfs_mem_cache_free(TaskMan.slab, task);
171 * task manager related routines
181 PLIST_ENTRY ListEntry = NULL;
182 PTASK_SLOT TaskSlot = NULL;
184 spin_lock(&(TaskMan.Lock));
186 ListEntry = TaskMan.TaskList.Flink;
188 while (ListEntry != (&(TaskMan.TaskList))) {
190 TaskSlot = CONTAINING_RECORD(ListEntry, TASK_SLOT, Link);
192 if (TaskSlot->Pid == ProcessId && TaskSlot->Tid == ThreadId) {
196 DbgPrint("task_manager_notify: Pid=%xh Tid %xh resued (TaskSlot->Tet = %xh)...\n",
197 ProcessId, ThreadId, TaskSlot->Tet);
200 /* remove the taskslot */
201 RemoveEntryList(&(TaskSlot->Link));
202 TaskMan.NumOfTasks--;
204 /* now free the task slot */
205 cleanup_task_slot(TaskSlot);
209 ListEntry = ListEntry->Flink;
212 spin_unlock(&(TaskMan.Lock));
220 /* initialize the content and magic */
221 memset(&TaskMan, 0, sizeof(TASK_MAN));
222 TaskMan.Magic = TASKMAN_MAGIC;
224 /* initialize the spinlock protection */
225 spin_lock_init(&TaskMan.Lock);
227 /* create slab memory cache */
228 TaskMan.slab = cfs_mem_cache_create(
229 "TSLT", sizeof(TASK_SLOT), 0, 0);
231 /* intialize the list header */
232 InitializeListHead(&(TaskMan.TaskList));
234 /* set the thread creation/destruction notify routine */
235 status = PsSetCreateThreadNotifyRoutine(task_manager_notify);
237 if (!NT_SUCCESS(status)) {
238 cfs_enter_debugger();
245 cleanup_task_manager()
247 PLIST_ENTRY ListEntry = NULL;
248 PTASK_SLOT TaskSlot = NULL;
250 /* we must stay in system since we succeed to register the
251 CreateThreadNotifyRoutine: task_manager_notify */
252 cfs_enter_debugger();
255 /* cleanup all the taskslots attached to the list */
256 spin_lock(&(TaskMan.Lock));
258 while (!IsListEmpty(&(TaskMan.TaskList))) {
260 ListEntry = TaskMan.TaskList.Flink;
261 TaskSlot = CONTAINING_RECORD(ListEntry, TASK_SLOT, Link);
263 RemoveEntryList(ListEntry);
264 cleanup_task_slot(TaskSlot);
267 spin_unlock(&TaskMan.Lock);
269 /* destroy the taskslot cache slab */
270 cfs_mem_cache_destroy(TaskMan.slab);
271 memset(&TaskMan, 0, sizeof(TASK_MAN));
276 * schedule routines (task slot list)
283 HANDLE Pid = PsGetCurrentProcessId();
284 HANDLE Tid = PsGetCurrentThreadId();
285 PETHREAD Tet = PsGetCurrentThread();
287 PLIST_ENTRY ListEntry = NULL;
288 PTASK_SLOT TaskSlot = NULL;
290 spin_lock(&(TaskMan.Lock));
292 ListEntry = TaskMan.TaskList.Flink;
294 while (ListEntry != (&(TaskMan.TaskList))) {
296 TaskSlot = CONTAINING_RECORD(ListEntry, TASK_SLOT, Link);
298 if (TaskSlot->Pid == Pid && TaskSlot->Tid == Tid) {
299 if (TaskSlot->Tet != Tet) {
302 DbgPrint("cfs_current: Pid=%xh Tid %xh Tet = %xh resued (TaskSlot->Tet = %xh)...\n",
303 Pid, Tid, Tet, TaskSlot->Tet);
306 // The old thread was already exit. This must be a
307 // new thread which get the same Tid to the previous.
316 if ((ULONG)TaskSlot->Pid > (ULONG)Pid) {
319 } else if ((ULONG)TaskSlot->Pid == (ULONG)Pid) {
320 if ((ULONG)TaskSlot->Tid > (ULONG)Tid) {
329 ListEntry = ListEntry->Flink;
334 TaskSlot = alloc_task_slot();
337 cfs_enter_debugger();
341 init_task_slot(TaskSlot);
347 if (ListEntry == (&(TaskMan.TaskList))) {
349 // Empty case or the biggest case, put it to the tail.
351 InsertTailList(&(TaskMan.TaskList), &(TaskSlot->Link));
354 // Get a slot and smaller than it's tid, put it just before.
356 InsertHeadList(ListEntry->Blink, &(TaskSlot->Link));
359 TaskMan.NumOfTasks++;
363 // To Check whether he task structures are arranged in the expected order ?
367 PTASK_SLOT Prev = NULL, Curr = NULL;
369 ListEntry = TaskMan.TaskList.Flink;
371 while (ListEntry != (&(TaskMan.TaskList))) {
373 Curr = CONTAINING_RECORD(ListEntry, TASK_SLOT, Link);
374 ListEntry = ListEntry->Flink;
377 if ((ULONG)Prev->Pid > (ULONG)Curr->Pid) {
378 cfs_enter_debugger();
379 } else if ((ULONG)Prev->Pid == (ULONG)Curr->Pid) {
380 if ((ULONG)Prev->Tid > (ULONG)Curr->Tid) {
381 cfs_enter_debugger();
392 spin_unlock(&(TaskMan.Lock));
395 cfs_enter_debugger();
399 return (&(TaskSlot->task));
403 schedule_timeout(int64_t time)
405 cfs_task_t * task = cfs_current();
406 PTASK_SLOT slot = NULL;
409 cfs_enter_debugger();
413 slot = CONTAINING_RECORD(task, TASK_SLOT, task);
414 cfs_assert(slot->Magic == TASKSLT_MAGIC);
416 if (time == MAX_SCHEDULE_TIMEOUT) {
420 return (cfs_wait_event(&(slot->Event), time) != 0);
426 return schedule_timeout(0);
434 PTASK_SLOT slot = NULL;
437 cfs_enter_debugger();
441 slot = CONTAINING_RECORD(task, TASK_SLOT, task);
442 cfs_assert(slot->Magic == TASKSLT_MAGIC);
444 cfs_wake_event(&(slot->Event));
456 cfs_waitlink_init(&link);
457 cfs_waitq_add(waitq, &link);
458 cfs_waitq_wait(&link, CFS_TASK_INTERRUPTIBLE);
459 cfs_waitq_del(waitq, &link);
462 EXPORT_SYMBOL(cfs_curproc_uid);
463 EXPORT_SYMBOL(cfs_curproc_pid);
464 EXPORT_SYMBOL(cfs_curproc_gid);
465 EXPORT_SYMBOL(cfs_curproc_fsuid);
466 EXPORT_SYMBOL(cfs_curproc_fsgid);
467 EXPORT_SYMBOL(cfs_curproc_umask);
468 EXPORT_SYMBOL(cfs_curproc_comm);
469 EXPORT_SYMBOL(cfs_curproc_groups_nr);
470 EXPORT_SYMBOL(cfs_curproc_groups_dump);
471 EXPORT_SYMBOL(cfs_curproc_is_in_groups);
472 EXPORT_SYMBOL(cfs_curproc_cap_get);
473 EXPORT_SYMBOL(cfs_curproc_cap_set);