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 * 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 void cfs_cap_raise(cfs_cap_t cap)
111 this_task.cap_effective |= (1 << cap);
114 void cfs_cap_lower(cfs_cap_t cap)
116 this_task.cap_effective &= ~(1 << cap);
119 int cfs_cap_raised(cfs_cap_t cap)
121 return this_task.cap_effective & (1 << cap);
124 cfs_cap_t cfs_curproc_cap_pack(void) {
125 return this_task.cap_effective;
128 void cfs_curproc_cap_unpack(cfs_cap_t cap) {
129 this_task.cap_effective = cap;
132 int cfs_capable(cfs_cap_t cap)
138 * Implementation of linux task management routines
142 /* global of the task manager structure */
154 PTASK_SLOT task = NULL;
157 task = cfs_mem_cache_alloc(TaskMan.slab, 0);
159 task = cfs_alloc(sizeof(TASK_SLOT), 0);
166 init_task_slot(PTASK_SLOT task)
168 memset(task, 0, sizeof(TASK_SLOT));
169 task->Magic = TASKSLT_MAGIC;
170 task->task = this_task;
171 task->task.pid = (pid_t)PsGetCurrentThreadId();
172 cfs_init_event(&task->Event, TRUE, FALSE);
177 cleanup_task_slot(PTASK_SLOT task)
180 cfs_mem_cache_free(TaskMan.slab, task);
187 * task manager related routines
197 PLIST_ENTRY ListEntry = NULL;
198 PTASK_SLOT TaskSlot = NULL;
200 spin_lock(&(TaskMan.Lock));
202 ListEntry = TaskMan.TaskList.Flink;
204 while (ListEntry != (&(TaskMan.TaskList))) {
206 TaskSlot = CONTAINING_RECORD(ListEntry, TASK_SLOT, Link);
208 if (TaskSlot->Pid == ProcessId && TaskSlot->Tid == ThreadId) {
212 DbgPrint("task_manager_notify: Pid=%xh Tid %xh resued (TaskSlot->Tet = %xh)...\n",
213 ProcessId, ThreadId, TaskSlot->Tet);
216 /* remove the taskslot */
217 RemoveEntryList(&(TaskSlot->Link));
218 TaskMan.NumOfTasks--;
220 /* now free the task slot */
221 cleanup_task_slot(TaskSlot);
225 ListEntry = ListEntry->Flink;
228 spin_unlock(&(TaskMan.Lock));
236 /* initialize the content and magic */
237 memset(&TaskMan, 0, sizeof(TASK_MAN));
238 TaskMan.Magic = TASKMAN_MAGIC;
240 /* initialize the spinlock protection */
241 spin_lock_init(&TaskMan.Lock);
243 /* create slab memory cache */
244 TaskMan.slab = cfs_mem_cache_create(
245 "TSLT", sizeof(TASK_SLOT), 0, 0);
247 /* intialize the list header */
248 InitializeListHead(&(TaskMan.TaskList));
250 /* set the thread creation/destruction notify routine */
251 status = PsSetCreateThreadNotifyRoutine(task_manager_notify);
253 if (!NT_SUCCESS(status)) {
254 cfs_enter_debugger();
261 cleanup_task_manager()
263 PLIST_ENTRY ListEntry = NULL;
264 PTASK_SLOT TaskSlot = NULL;
266 /* we must stay in system since we succeed to register the
267 CreateThreadNotifyRoutine: task_manager_notify */
268 cfs_enter_debugger();
271 /* cleanup all the taskslots attached to the list */
272 spin_lock(&(TaskMan.Lock));
274 while (!IsListEmpty(&(TaskMan.TaskList))) {
276 ListEntry = TaskMan.TaskList.Flink;
277 TaskSlot = CONTAINING_RECORD(ListEntry, TASK_SLOT, Link);
279 RemoveEntryList(ListEntry);
280 cleanup_task_slot(TaskSlot);
283 spin_unlock(&TaskMan.Lock);
285 /* destroy the taskslot cache slab */
286 cfs_mem_cache_destroy(TaskMan.slab);
287 memset(&TaskMan, 0, sizeof(TASK_MAN));
292 * schedule routines (task slot list)
299 HANDLE Pid = PsGetCurrentProcessId();
300 HANDLE Tid = PsGetCurrentThreadId();
301 PETHREAD Tet = PsGetCurrentThread();
303 PLIST_ENTRY ListEntry = NULL;
304 PTASK_SLOT TaskSlot = NULL;
306 spin_lock(&(TaskMan.Lock));
308 ListEntry = TaskMan.TaskList.Flink;
310 while (ListEntry != (&(TaskMan.TaskList))) {
312 TaskSlot = CONTAINING_RECORD(ListEntry, TASK_SLOT, Link);
314 if (TaskSlot->Pid == Pid && TaskSlot->Tid == Tid) {
315 if (TaskSlot->Tet != Tet) {
318 DbgPrint("cfs_current: Pid=%xh Tid %xh Tet = %xh resued (TaskSlot->Tet = %xh)...\n",
319 Pid, Tid, Tet, TaskSlot->Tet);
322 // The old thread was already exit. This must be a
323 // new thread which get the same Tid to the previous.
332 if ((ULONG)TaskSlot->Pid > (ULONG)Pid) {
335 } else if ((ULONG)TaskSlot->Pid == (ULONG)Pid) {
336 if ((ULONG)TaskSlot->Tid > (ULONG)Tid) {
345 ListEntry = ListEntry->Flink;
350 TaskSlot = alloc_task_slot();
353 cfs_enter_debugger();
357 init_task_slot(TaskSlot);
363 if (ListEntry == (&(TaskMan.TaskList))) {
365 // Empty case or the biggest case, put it to the tail.
367 InsertTailList(&(TaskMan.TaskList), &(TaskSlot->Link));
370 // Get a slot and smaller than it's tid, put it just before.
372 InsertHeadList(ListEntry->Blink, &(TaskSlot->Link));
375 TaskMan.NumOfTasks++;
379 // To Check whether he task structures are arranged in the expected order ?
383 PTASK_SLOT Prev = NULL, Curr = NULL;
385 ListEntry = TaskMan.TaskList.Flink;
387 while (ListEntry != (&(TaskMan.TaskList))) {
389 Curr = CONTAINING_RECORD(ListEntry, TASK_SLOT, Link);
390 ListEntry = ListEntry->Flink;
393 if ((ULONG)Prev->Pid > (ULONG)Curr->Pid) {
394 cfs_enter_debugger();
395 } else if ((ULONG)Prev->Pid == (ULONG)Curr->Pid) {
396 if ((ULONG)Prev->Tid > (ULONG)Curr->Tid) {
397 cfs_enter_debugger();
408 spin_unlock(&(TaskMan.Lock));
411 cfs_enter_debugger();
415 return (&(TaskSlot->task));
419 schedule_timeout(int64_t time)
421 cfs_task_t * task = cfs_current();
422 PTASK_SLOT slot = NULL;
425 cfs_enter_debugger();
429 slot = CONTAINING_RECORD(task, TASK_SLOT, task);
430 cfs_assert(slot->Magic == TASKSLT_MAGIC);
432 if (time == MAX_SCHEDULE_TIMEOUT) {
436 return (cfs_wait_event(&(slot->Event), time) != 0);
442 return schedule_timeout(0);
450 PTASK_SLOT slot = NULL;
453 cfs_enter_debugger();
457 slot = CONTAINING_RECORD(task, TASK_SLOT, task);
458 cfs_assert(slot->Magic == TASKSLT_MAGIC);
460 cfs_wake_event(&(slot->Event));
472 cfs_waitlink_init(&link);
473 cfs_waitq_add(waitq, &link);
474 cfs_waitq_wait(&link, CFS_TASK_INTERRUPTIBLE);
475 cfs_waitq_del(waitq, &link);
478 EXPORT_SYMBOL(cfs_curproc_uid);
479 EXPORT_SYMBOL(cfs_curproc_pid);
480 EXPORT_SYMBOL(cfs_curproc_gid);
481 EXPORT_SYMBOL(cfs_curproc_fsuid);
482 EXPORT_SYMBOL(cfs_curproc_fsgid);
483 EXPORT_SYMBOL(cfs_curproc_umask);
484 EXPORT_SYMBOL(cfs_curproc_comm);
485 EXPORT_SYMBOL(cfs_curproc_groups_nr);
486 EXPORT_SYMBOL(cfs_curproc_groups_dump);
487 EXPORT_SYMBOL(cfs_curproc_is_in_groups);
488 EXPORT_SYMBOL(cfs_cap_raise);
489 EXPORT_SYMBOL(cfs_cap_lower);
490 EXPORT_SYMBOL(cfs_cap_raised);
491 EXPORT_SYMBOL(cfs_curproc_cap_pack);
492 EXPORT_SYMBOL(cfs_curproc_cap_unpack);
493 EXPORT_SYMBOL(cfs_capable);