1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "Routine.hpp"
16 
17 #include "../Common/Memory.hpp"
18 #include "../Common/Thread.hpp"
19 #include "../Common/Types.hpp"
20 
21 namespace sw
22 {
Routine(int bufferSize)23 	Routine::Routine(int bufferSize) : bufferSize(bufferSize), dynamic(true)
24 	{
25 		void *memory = allocateExecutable(bufferSize);
26 
27 		buffer = memory;
28 		entry = memory;
29 		functionSize = bufferSize;   // Updated by RoutineManager::endFunctionBody
30 
31 		bindCount = 0;
32 	}
33 
Routine(void * memory,int bufferSize,int offset)34 	Routine::Routine(void *memory, int bufferSize, int offset) : bufferSize(bufferSize), functionSize(bufferSize), dynamic(false)
35 	{
36 		buffer = (unsigned char*)memory - offset;
37 		entry = memory;
38 
39 		bindCount = 0;
40 	}
41 
~Routine()42 	Routine::~Routine()
43 	{
44 		if(dynamic)
45 		{
46 			deallocateExecutable(buffer, bufferSize);
47 		}
48 	}
49 
setFunctionSize(int functionSize)50 	void Routine::setFunctionSize(int functionSize)
51 	{
52 		this->functionSize = functionSize;
53 	}
54 
getBuffer()55 	const void *Routine::getBuffer()
56 	{
57 		return buffer;
58 	}
59 
getEntry()60 	const void *Routine::getEntry()
61 	{
62 		return entry;
63 	}
64 
getBufferSize()65 	int Routine::getBufferSize()
66 	{
67 		return bufferSize;
68 	}
69 
getFunctionSize()70 	int Routine::getFunctionSize()
71 	{
72 		return functionSize;
73 	}
74 
getCodeSize()75 	int Routine::getCodeSize()
76 	{
77 		return functionSize - ((uintptr_t)entry - (uintptr_t)buffer);
78 	}
79 
isDynamic()80 	bool Routine::isDynamic()
81 	{
82 		return dynamic;
83 	}
84 
bind()85 	void Routine::bind()
86 	{
87 		atomicIncrement(&bindCount);
88 	}
89 
unbind()90 	void Routine::unbind()
91 	{
92 		long count = atomicDecrement(&bindCount);
93 
94 		if(count == 0)
95 		{
96 			delete this;
97 		}
98 	}
99 }
100