VPS
Subversion Repository Public Repository

Divide-Framework

This repository has no backups
This repository's network speed is throttled to 100KB/sec

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include "Headers/Task.h"

#include "Core/Headers/Kernel.h"
#include "Core/Headers/Console.h"
#include "Core/Headers/Application.h"
#include "Core/Time/Headers/ApplicationTimer.h"
#include "Utility/Headers/Localization.h"

namespace Divide {

namespace {
    const bool g_DebugTaskStartStop = false;
};

Task::Task() : GUIDWrapper(),
               _tp(nullptr),
               _poolIndex(0),
               _jobIdentifier(-1),
               _priority(TaskPriority::DONT_CARE)
{
    _parentTask = nullptr;
    _childTaskCount = 0;
    _done = true;
    _stopRequested = false;
}

Task::~Task()
{
    stopTask();
    wait();
}

void Task::reset() {
    if (!_done) {
        stopTask();
        wait();
    }

    _stopRequested = false;
    _callback = DELEGATE_CBK_PARAM<bool>();
    _jobIdentifier = -1;
    _priority = TaskPriority::DONT_CARE;
    _parentTask = nullptr;
    _childTasks.clear();
    _childTaskCount = 0;
}

void Task::startTask(TaskPriority priority) {
    assert(!isRunning());

    _done = false;
    _priority = priority;
    if (priority != TaskPriority::REALTIME && _tp != nullptr && _tp->workerThreadCount() > 0) {
        while (!_tp->threadPool().schedule(PoolTask(to_uint(priority), DELEGATE_BIND(&Task::run, this)))) {
            Console::errorfn(Locale::get(_ID("TASK_SCHEDULE_FAIL")));
        }
    } else {
        run();
    }
}

void Task::stopTask() {
#if defined(_DEBUG)
    if (isRunning()) {
        Console::errorfn(Locale::get(_ID("TASK_DELETE_ACTIVE")));
    }
#endif

    for (Task* child : _childTasks){
        child->stopTask();
    }

    _stopRequested = true;
}

void Task::wait() {
    std::unique_lock<std::mutex> lk(_taskDoneMutex);
    while (!_done) {
        _taskDoneCV.wait(lk);
    }
}

//ToDo: Add better wait for children system. Just manually balance calls for now -Ionut
void Task::waitForChildren(bool yeld, I64 timeout) {
    U64 startTime = 0UL;
    if (timeout > 0L) {
        startTime = Time::ElapsedMicroseconds(true);
    }

    while(_childTaskCount > 0) {
        if (timeout > 0L) {
            U64 endTime = Time::ElapsedMicroseconds(true);
            if (endTime - startTime >= static_cast<U64>(timeout)) {
                return;
            }
        } else if (timeout == 0L) {
            return;
        }

        if (yeld) {
            std::this_thread::yield();
        }
    }
}

void Task::run() {
    waitForChildren(true, -1L);
    if (g_DebugTaskStartStop) {
        Console::d_printfn(Locale::get(_ID("TASK_RUN_IN_THREAD")), getGUID(), std::this_thread::get_id());
    }

    if (!Application::instance().ShutdownRequested()) {

        if (_callback) {
            _callback(_stopRequested);
        }

        // task finished. Everything else is bookkeeping
        _tp->taskCompleted(poolIndex());
    }

    if (_parentTask != nullptr) {
        _parentTask->_childTaskCount -= 1;
    }

    if (g_DebugTaskStartStop) {
        Console::d_printfn(Locale::get(_ID("TASK_COMPLETE_IN_THREAD")), getGUID(), std::this_thread::get_id());
    }

    _done = true;

    std::unique_lock<std::mutex> lk(_taskDoneMutex);
    _taskDoneCV.notify_one();
}

};

Commits for Divide-Framework/trunk/Source Code/Platform/Threading/Task.cpp

Diff revisions: vs.
Revision Author Commited Message
693 Diff Diff IonutCava picture IonutCava Thu 28 Apr, 2016 16:19:35 +0000

[IonutCava]
- Cleanup Time and Profiling code

679 Diff Diff IonutCava picture IonutCava Wed 13 Apr, 2016 21:21:51 +0000

[IonutCava]
- Add unit tests for task system
- Adapt task system for better modularity
- Split Divide-Game into Game lib and Game executable projects
- Cleanup unit test projects

674 Diff Diff IonutCava picture IonutCava Mon 11 Apr, 2016 16:17:10 +0000

[IonutCava]
- Some profile guided optimizations:
— Remove the task state hashmap and replace with flat array
— Allow PhysX to load collision meshes from a RAM cache first -> then file -> then recompute
- Improve memory logger output

670 Diff Diff IonutCava picture IonutCava Wed 06 Apr, 2016 16:21:35 +0000

[IonutCava]
- getInstance() renamed to instance() for simplicity (should really go away altogether, but that’s a different issue)
- some particle emitter threading updates

668 Diff Diff IonutCava picture IonutCava Fri 01 Apr, 2016 21:56:01 +0000

[IonutCava]
- Added multiple ‘WAIT_FOR_CONDITION’ macros to allow multiple features instead of the standard buys-wait behaviour:
— timeout
— per loop callback
— thread yielding
- Added task callback queue flushing before each sceneUpdate call
— Multiple passes can now benefit from threaded results from previous passes
-Particle emitter sorting and buffer update is now threaded

667 Diff Diff IonutCava picture IonutCava Fri 01 Apr, 2016 16:12:16 +0000

[IonutCava]
- replaced more strings with _ID equivalent
- streamlined shader include preprocessing
- improved intersection test performance for the Octree system at the cost of some memory

665 Diff Diff IonutCava picture IonutCava Thu 31 Mar, 2016 15:50:03 +0000

[IonutCava]
- Added proper multi-threaded logging support for the Console system using moodycamel::ConcurrentQueue (https://github.com/cameron314/concurrentqueue)

664 Diff Diff IonutCava picture IonutCava Wed 30 Mar, 2016 16:23:51 +0000

[IonutCava]
- Split some render bin loops into multiple tasks
- Cleaned up the Task class
- Attempt to improve Console multithreaded performance (does not compile yet)

663 Diff Diff IonutCava picture IonutCava Tue 29 Mar, 2016 16:07:31 +0000

[IonutCava]
- Reworked task parent<->children system to allow child tasks to be started immediately after creation (to get adding and running to run in parallel)
- Added locked variable support to the debugging system

662 IonutCava picture IonutCava Mon 28 Mar, 2016 18:46:06 +0000

[Ionut]
- stopRequested param for Task callbacks should be an atomic const reference
- DebugInterface thread safety updates
- Initial code for locked Tasks (tasks that can’t be reset)